http://blog.csdn.net/a756213932/article/details/51939422
这个老哥给了我思路
但是他竟然用了BitmapShader,我觉得是完全没有必要的,drawBitmap(..rect1,rect2..)这个api已经为我们处理好缩放了
还有这个老哥精确到0.1,我这里精确到float
我这里没有弄竖排的,因为项目只有横排的需求,不愿浪费这个时间去完善
这里没有弄拖拽滑动改变星级的,因为也没有这个需求,而且滑动的起始点我一时里感觉都不合适,也没弄
效果展示
支持的所有属性
<declare-styleable name="StarGroupView"> <attr format="dimension" name="star_size"/> <attr format="dimension" name="star_padding"/> <attr format="dimension" name="padding_left"/> <attr format="dimension" name="padding_top"/> <attr format="dimension" name="padding_right"/> <attr format="dimension" name="padding_bottom"/> <attr format="integer" name="star_count"/> <!--star_score代表一共有多少分--> <attr format="float" name="star_score"/> <attr format="reference" name="star_empty_drawable"/> <attr format="reference" name="star_fill_drawable"/> </declare-styleable>
也可以在代码里动态设置多少分
StarGroupView starGroupView = findViewById(R.id.star_group_view); starGroupView.setScore(7.7f);
xml使用
<com.example.demo.StarGroupView android:id="@+id/star_group_view" android:layout_width="wrap_content" android:layout_height="wrap_content" StarGroupView:star_count="9" StarGroupView:star_empty_drawable="@drawable/star_empty" StarGroupView:star_fill_drawable="@drawable/star_full" StarGroupView:star_size="9dp" StarGroupView:star_score="5.7"/>
全部代码(因为做了一些优化,所以晦涩难懂,推荐看上面链接里的文章)
public class StarGroupView extends View { public StarGroupView(Context context) { super(context); } public StarGroupView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context, attrs); } public StarGroupView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private int starCounts; private float score; private int starWidth; private int starHeight; private int starPadding; private int paddingLeft; private int paddingTop ; private int paddingRight ; private int paddingBottom; private Bitmap starEmptyBitmap; private Bitmap starFullBitmap; private int starBitmapWidth; private int startBitmapHeight; private Paint paint; private Rect rect1;//两个复用的rect private Rect rect2; //默认属性 private void init(Context context, AttributeSet attrs) { TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.StarGroupView); starPadding = (int) mTypedArray.getDimension(R.styleable.StarGroupView_star_padding, 0); paddingLeft = (int) mTypedArray.getDimension(R.styleable.StarGroupView_padding_left, 0); paddingTop = (int) mTypedArray.getDimension(R.styleable.StarGroupView_padding_top, 0); paddingRight = (int) mTypedArray.getDimension(R.styleable.StarGroupView_padding_right, 0); paddingBottom = (int) mTypedArray.getDimension(R.styleable.StarGroupView_padding_bottom, 0); starWidth = (int) mTypedArray.getDimension(R.styleable.StarGroupView_star_size, 20); starHeight = (int) mTypedArray.getDimension(R.styleable.StarGroupView_star_size, 20); starCounts = mTypedArray.getInteger(R.styleable.StarGroupView_star_count, 5); score = mTypedArray.getFloat(R.styleable.StarGroupView_star_score, 3.6f); Drawable starEmptyDrawable = mTypedArray.getDrawable(R.styleable.StarGroupView_star_empty_drawable); Drawable starFullDrawable = mTypedArray.getDrawable(R.styleable.StarGroupView_star_fill_drawable); mTypedArray.recycle(); starWidth = DensityUtils.dp2px(context, starWidth); starHeight = DensityUtils.dp2px(context, starHeight); starPadding = DensityUtils.dp2px(context, starPadding); paddingLeft = DensityUtils.dp2px(context, paddingLeft); paddingTop = DensityUtils.dp2px(context, paddingTop); paddingRight = DensityUtils.dp2px(context, paddingRight); paddingBottom = DensityUtils.dp2px(context, paddingBottom); starEmptyBitmap = (starEmptyDrawable) != null ? ((BitmapDrawable) starEmptyDrawable).getBitmap() : null; starFullBitmap = (starFullDrawable) != null ? ((BitmapDrawable) starFullDrawable).getBitmap() : null; starBitmapWidth = starEmptyBitmap != null ? starEmptyBitmap.getWidth() : 0; startBitmapHeight = starEmptyBitmap != null ? starEmptyBitmap.getHeight() : 0; paint = new Paint(); rect1 = new Rect(); rect2 = new Rect(); } public void setScore(float score) { this.score = score; invalidate(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); if (widthSpecMode == MeasureSpec.AT_MOST) { widthSpecSize = starWidth * starCounts + starPadding * (starCounts - 1) + paddingLeft + paddingRight; } if (heightSpecMode == MeasureSpec.AT_MOST) { heightSpecSize = starHeight + paddingTop + paddingBottom; } setMeasuredDimension(widthSpecSize, heightSpecSize); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //计算填充的star int score = (int) this.score; if (score > this.score) { score--; } //画整数个被填充的star int startX = - starWidth - starPadding + paddingLeft;//所有的星星的起点都放在这里 for (int i = 0; i < score; i ++) { startX += starWidth + starPadding; rect1.left = startX; rect1.top = paddingTop; rect1.right = startX + starWidth; rect1.bottom = starHeight + paddingTop; canvas.drawBitmap( starFullBitmap, null, rect1, paint); //new Rect(startX, 0, startX + starWidth, starHeight), } //画填充的star和部分未填充的star float fillRate = this.score - score; startX += starWidth + starPadding; rect1.left = 0; rect1.top = 0; rect1.right = (int) (starBitmapWidth * fillRate); rect1.bottom = startBitmapHeight; rect2.left = startX; rect2.top = paddingTop; rect2.right = (int) (startX + fillRate * starWidth); rect2.bottom = starHeight + paddingTop; canvas.drawBitmap( starFullBitmap, rect1, rect2, paint); rect1.left = (int) (starBitmapWidth * fillRate); rect1.top = 0; rect1.right = starBitmapWidth; rect1.bottom = startBitmapHeight; rect2.left = (int) (startX + fillRate * starWidth); rect2.top = paddingTop; rect2.right = startX + starWidth; rect2.bottom = starHeight + paddingTop; canvas.drawBitmap( starEmptyBitmap, rect1, rect2, paint); //画整数个未被填充的star if (score + 1 != starCounts) { for (int i = score + 1; i < starCounts; i ++) { startX += starWidth + starPadding; rect1.left = startX; rect1.top = paddingTop; rect1.right = startX + starWidth; rect1.bottom = starHeight + paddingTop; canvas.drawBitmap( starEmptyBitmap, null, rect1, paint); } } } }