美文网首页
Android 自定义 简单的RatingBar

Android 自定义 简单的RatingBar

作者: 花椒人生 | 来源:发表于2018-01-24 15:24 被阅读0次

1.效果展示

image.png
image.png

2.效果实现分析

2.1 简单实现,需要两张图片,一张灰色星星,一张黄色星星
2.2 首先绘制五张灰色背景星星,然后重写onTouchEvent()方法,当用户与屏幕进行交互时,在执行MOVE,UP,DOWN时,根据用户手指所在位置距离,算出应对对应几个黄色星星,然后重新绘制。

3.代码实现

3.1 创建CMRatingBarView类,继承至View类
 public class CMRatingBarView extends View {
  private Bitmap cmRatingNormalBitmap, cmRatingFocusBitmap;
  //个数
  private int cmRatingGradeNumber = 5;

  private int cmRatingCurrentNumber = 0;


  public CMRatingBarView(Context context) {
      this(context, null);
  }

  public CMRatingBarView(Context context, @Nullable AttributeSet attrs) {
      this(context, attrs, 0);
  }

  public CMRatingBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
      super(context, attrs, defStyleAttr);
  }
}
3.2 在values目录下的attrs.xml文件中自定义RatingBar的属性
  <declare-styleable name="CMRatingBarView">
    <attr name="cmRatingBarStartNormal" format="reference"></attr>
    <attr name="cmRatingBarStartFocus" format="reference"></attr>
    <attr name="cmRatingBarGradeNumber" format="integer"></attr>
</declare-styleable>
3.3 在布局文件中引用
         <com.test.cmviewdemo.CMRatingBarView
            android:padding="5dp"
            android:background="@color/colorAccent"
            app:cmRatingBarGradeNumber="5"
            app:cmRatingBarStartFocus="@mipmap/star_selected"
            app:cmRatingBarStartNormal="@mipmap/star_normal"
            android:id="@+id/main_cmShape_CMRatingBar"
            android:layout_margin="10dp"
            android:layout_width="50dp"
            android:layout_height="50dp" />
3.4 在CMRatingBar的构造方法中获取自定义的属性
      //获取自定义属性
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CMRatingBarView);

    cmRatingGradeNumber = (int) typedArray.getInt(R.styleable.CMRatingBarView_cmRatingBarGradeNumber, cmRatingGradeNumber);

    int cmRatingNormalId = typedArray.getResourceId(R.styleable.CMRatingBarView_cmRatingBarStartNormal, 0);
    int cmRatingFocusId = typedArray.getResourceId(R.styleable.CMRatingBarView_cmRatingBarStartFocus, 0);
    if (0 == cmRatingNormalId) {
        throw new RuntimeException("请设置默认RatingBar图片");
    }
    if (0 == cmRatingFocusId) {
        throw new RuntimeException("请设置选中RatingBar图片");
    }
    cmRatingNormalBitmap = BitmapFactory.decodeResource(getResources(), cmRatingNormalId);
    cmRatingFocusBitmap = BitmapFactory.decodeResource(getResources(), cmRatingFocusId);
    typedArray.recycle();
3.4 重写onMeasure()方法,从新设置view的宽高
  @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int width = MeasureSpec.getSize(widthMeasureSpec);
    int heigth = MeasureSpec.getSize(heightMeasureSpec);

    width = getPaddingLeft() + (cmRatingNormalBitmap.getWidth() + getPaddingRight()) * cmRatingGradeNumber;
    heigth = cmRatingNormalBitmap.getHeight() + getPaddingTop() + getPaddingBottom();

    setMeasuredDimension(width, heigth);

}
3.5 重写onDray()方法,重新绘制RatingBar
 @Override
protected void onDraw(Canvas canvas) {
    //直接绘制bitmap

    for (int i = 0; i < cmRatingGradeNumber; i++) {
        int x = (cmRatingNormalBitmap.getWidth() + getPaddingRight()) * i;

        if(i < cmRatingCurrentNumber){
            canvas.drawBitmap(cmRatingFocusBitmap, getPaddingLeft() + x, getPaddingTop(), null);
        }else{
            canvas.drawBitmap(cmRatingNormalBitmap, getPaddingLeft() + x, getPaddingTop(), null);
        }
    }
}

cmRatingGradeNumber 是自定义的总的星星数量
cmRatingCurrentNumber是用户选中的星星的数量

3.6 重写onTouchEvent()方法,处理UP,MOVE,DOWN事件
@Override
public boolean onTouchEvent(MotionEvent event) {

    switch (event.getAction()) {

        case MotionEvent.ACTION_MOVE:

            //1.获取手指当前的位置,除以整个的宽度,然后再去画RatingBar
            float cmCurrentWidth = event.getX();
            int cmCurrentNumber = (int) (cmCurrentWidth / cmRatingNormalBitmap.getWidth() + 1);

            Log.e("CMRatingBar 个数",cmCurrentNumber+"个,event.getX()= "+event.getX()+" ! cmRatingNormalBitmap.getWidth() + 1 = "+cmRatingNormalBitmap.getWidth() + 1);

            if(cmCurrentNumber < 0){
                cmCurrentNumber = 0;
            }

            if(cmCurrentNumber > cmRatingGradeNumber){
                cmCurrentNumber= cmRatingGradeNumber;
            }

            if(cmCurrentNumber == cmRatingCurrentNumber){
                return true;
            }



            cmRatingCurrentNumber = cmCurrentNumber;
            invalidate();

            break;
    }

    return true;
}

4 GitHub

Demo 地址 https://github.com/hualianrensheng/CMViewDemo

相关文章

网友评论

      本文标题:Android 自定义 简单的RatingBar

      本文链接:https://www.haomeiwen.com/subject/fisuaxtx.html