I have nothing to do and write a star review control using a custom view. Although there are many of this controls on the Internet, I wrote them myself, so I will record them here.
First, custom properties are required
<declare-styleable name="Rate"> <!--The attributes are:Single width,high,Distance between,Number of activated,Total quantity,Activateddrawable,没有Activateddrawable,Is it possible to select quantity--> <attr name="custom_rate_width" format="dimension"/> <attr name="custom_rate_height" format="dimension"/> <attr name="custom_rate_padding" format="dimension"/> <attr name="custom_rate_active_size" format="integer"/> <attr name="custom_rate_size" format="integer"/> <attr name="custom_rate_active_drawable" format="reference"/> <attr name="custom_rate_disactive_drawable" format="reference"/> <attr name="custom_rate_touch" format="boolean"/> </declare-styleable>
Initialization code
protected void init(Context context, AttributeSet attrs) { TypedArray array = (attrs, ); int activeId = 0; int disactiveId = 0; if (array != null) { size = (.Rate_custom_rate_size, 5); activeSize = (.Rate_custom_rate_active_size, 3); rateWidth = (.Rate_custom_rate_width, 0); rateHeight = (.Rate_custom_rate_height, 0); activeId = (.Rate_custom_rate_active_drawable, 0); disactiveId = (.Rate_custom_rate_disactive_drawable, 0); padding = (.Rate_custom_rate_padding, 0); isTouch = (.Rate_custom_rate_touch, false); (); } // If there is no width and height, set a default value if (rateHeight <= 0){ rateHeight = 80; } if (rateWidth <= 0){ rateWidth = 80; } if (activeId!=0){ activeBitmap = (getResources(), activeId); //If the width and height are not set if (rateWidth <= 0) { rateWidth = (); } //Compress the image to the set width and height activeBitmap = (activeBitmap, (int) rateWidth, (int) rateHeight, false); } if (disactiveId != 0){ disactiveBitmap = (getResources(), disactiveId); if (rateHeight <= 0) { rateHeight = (); } disactiveBitmap = (disactiveBitmap, (int) rateWidth, (int) rateHeight, false); } mPaint = new Paint();//Initialize the bitmap brush (true); activPaint = new Paint();//Initialize the selected star brush (true); (); disactivPaint = new Paint();//Initialize the brush with unselected stars (true); (); }
The onMeasure method sets the width and height of the view. If the width and height of each star control are greater than the width and height of the actual view, the width and height of the star space are used to make the width and height of the view.
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthMode = (widthMeasureSpec); int widthSize = (widthMeasureSpec); int heightMode = (heightMeasureSpec); int heightSize = (heightMeasureSpec); // Calculate width if (widthMode == ) { //If the width of the view is smaller than the width of the set size* star, use size * (int) (padding + rateWidth) as the width of the control. if (widthSize < size * (int) (padding + rateWidth)) { width = size * (int) (padding + rateWidth); } else { width = widthSize; } } else { width = size * (int) (padding + rateWidth)-padding; } // Calculate high if (heightMode == ) { //If the height of the view is smaller than the height of the set star, use the height of the star as the height of the control if (heightSize < rateHeight) { height = (int) rateHeight + 5; } else { height = heightSize; } } else { height = (int) rateHeight + 5; } setMeasuredDimension(width, height); }
Draw in onDraw method
//Start draw active for (int i = 0; i < activeSize; i++) { if (activeBitmap != null){ if (i == 0) { (activeBitmap, rateWidth * i, (height - rateHeight) / 2, mPaint); } else { (activeBitmap, (rateWidth + padding) * i, (height - rateHeight) / 2, mPaint); } }else { drawActivRate(i,canvas); } } // // Start drawing disactive for (int i = activeSize; i < size; i++) { if (disactiveBitmap != null){ if (i == 0) { (disactiveBitmap, rateWidth * i, (height - rateHeight) / 2, mPaint); } else { (disactiveBitmap, (rateWidth + padding) * i, (height - rateHeight) / 2, mPaint); } }else { drawDisActivRate(i,canvas); } }
The above two methods drawActivRate and drawDisActivRate are used, which are the default stars drawn in and out of activity when there is no picture of the stars in the activity and the stars in the activity:
/** * Drawing yellow five-pointed stars (in active) * */ private void drawActivRate(int position,Canvas canvas){ float radius = rateWidth/2;//Draw the garden according to the position of each star and determine the location of the five points of the five-point star float angle = 360/5; float centerX = (rateWidth+padding)*(position+1)-padding-radius;//Get the X coordinate in the center of each star space float centerY =height/2;//Get the y coordinate in the center of each star space Path mPath = new Path(); (centerX,centerY-radius); (centerX+(float) ((angle*2-90)* / 180)*radius,centerY+(float)((angle*2-90)* / 180)*radius); ( centerX-(float)(angle* / 180)*radius,centerY-(float)(angle* / 180)*radius); ( centerX+(float)(angle* / 180)*radius,centerY-(float)(angle* / 180)*radius); ( centerX-(float)((angle*3-180)* / 180)*radius,centerY+(float)((angle*3-180)* / 180)*radius); // (centerX,centerY-radius); (); (mPath,activPaint); } /** * Drawing gray five-pointed stars * */ private void drawDisActivRate(int position,Canvas canvas){ float radius = rateWidth/2; float angle = 360/5; float centerX = (rateWidth+padding)*(position+1)-padding-radius; float centerY =height/2; Path mPath = new Path(); (centerX,centerY-radius); (centerX+(float) ((angle*2-90)* / 180)*radius,centerY+(float)((angle*2-90)* / 180)*radius); ( centerX-(float)(angle* / 180)*radius,centerY-(float)(angle* / 180)*radius); ( centerX+(float)(angle* / 180)*radius,centerY-(float)(angle* / 180)*radius); ( centerX-(float)((angle*3-180)* / 180)*radius,centerY+(float)((angle*3-180)* / 180)*radius); // (centerX,centerY-radius); (); (mPath,disactivPaint); }
Finally, the processing of selected and unselected stars is handled in the onTouchEvent method.
@Override public boolean onTouchEvent(MotionEvent event) { if (!isTouch){//If touch is not supported return false; } switch (()) { case MotionEvent.ACTION_DOWN: touchX = (); touchY = (); for (int i = 0; i < size; i++) { if (i == 0) { if (0.0 < touchX && touchX < rateWidth+padding/2) { activeSize = 1; } }else { if ((rateWidth+padding)*i-padding/2<touchX&&touchX<(rateWidth+padding)*(i+1)-padding/2){ activeSize = i+1; } } } invalidate(); break; case MotionEvent.ACTION_UP: if ( null!= changeListener){ (activeSize); } break; case MotionEvent.ACTION_MOVE: touchX = (); touchY = (); for (int i = 0; i < size; i++) { if (i == 0) { if (0.0 < touchX && touchX < rateWidth+padding/2) { activeSize = 1; } }else { if ((rateWidth+padding)*i-padding/2<touchX&&touchX<(rateWidth+padding)*(i+1)-padding/2){ activeSize = i+1; } } } invalidate(); if (touchX<=0){ activeSize = 0; } break; } return true; }
The above is the star comment control written by the custom view. The annotations in the code are already detailed, so I won’t say more.
Source code address
The above is the example code of Android custom star comment space introduced to you by the editor. I hope it will be helpful to everyone!