zoukankan      html  css  js  c++  java
  • 自定义RatingBar评分控件

    1.介绍

    实现类似美团外卖评分供能,系统提供了RatingBar,今天来自定义一波,当做自定义view的一个学习,效果如下,能够滑动或者点击变化星星数量
    image.png

    2.自定义属性

    在values目录下的attrs.xml创建所需要的属性

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="MyRatingView">
            <attr name="normalRatingBar" format="reference" />
            <attr name="selectRatingBar" format="reference" />
            <attr name="ratingNum" format="integer" />
            <attr name="bothPadding" format="dimension" />
        </declare-styleable>
    </resources>
    
    3.自定义View如下
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.support.annotation.Nullable;
    import android.util.AttributeSet;
    import android.view.MotionEvent;
    import android.view.View;
    
    import com.cyq.customview2.R;
    
    /**
     * 自定义评分控件
     */
    public class MyRatingView extends View {
        private Bitmap mNormalRatingBar, mSelectRatingBar;
        private int mGrateNumber = 5;
        private int mBothPadding = 5;//默认星星之间间隔为5dp
        private int mCurrentNumber = 0, mSelectNumber = 0;
    
        public MyRatingView(Context context) {
            this(context, null);
        }
    
        public MyRatingView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public MyRatingView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyRatingView);
    
            int mNormalBitmapId = array.getResourceId(R.styleable.MyRatingView_normalRatingBar, 0);
            if (mNormalBitmapId == 0) {
                throw new RuntimeException("未设置属性");
            }
            mNormalRatingBar = BitmapFactory.decodeResource(getResources(), mNormalBitmapId);
    
            int mSelectBitmapId = array.getResourceId(R.styleable.MyRatingView_selectRatingBar, 0);
            if (mSelectBitmapId == 0) {
                throw new RuntimeException("未设置属性");
            }
            mSelectRatingBar = BitmapFactory.decodeResource(getResources(), mSelectBitmapId);
    
            mGrateNumber = array.getInt(R.styleable.MyRatingView_ratingNum, mGrateNumber);
            mBothPadding = array.getDimensionPixelSize(R.styleable.MyRatingView_bothPadding, 5);
    
            array.recycle();
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int height = mNormalRatingBar.getHeight() + getPaddingTop() + getPaddingBottom();
            int width = mGrateNumber * mNormalRatingBar.getWidth()
                    + mBothPadding * (mGrateNumber - 1)
                    + getPaddingLeft()
                    + getPaddingRight();//暂时还没有设置间隔UP
            //设置测量维度
            setMeasuredDimension(width, height);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            for (int i = 0; i < mGrateNumber; i++) {
                int x = (mNormalRatingBar.getWidth() + mBothPadding) * i + getPaddingLeft();
                int y = getPaddingTop();
                canvas.drawBitmap(mNormalRatingBar, x, y, null);
            }
    
            for (int i = 0; i < mSelectNumber; i++) {
                int x = (mSelectRatingBar.getWidth() + mBothPadding) * i + getPaddingLeft();
                int y = getPaddingTop();
                canvas.drawBitmap(mSelectRatingBar, x, y, null);
            }
    
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                case MotionEvent.ACTION_MOVE:
                case MotionEvent.ACTION_UP:
                    float moveX = event.getX();
                    mCurrentNumber = (int) ((moveX - getPaddingLeft()) / (mNormalRatingBar.getWidth() + mBothPadding));
                    if (mCurrentNumber < 0)
                        mCurrentNumber = 0;
                    if (mCurrentNumber > 0)
                        mCurrentNumber += 1;
                    //避免星星数量没变化时重复调用onDraw方法
                    if (mCurrentNumber != mSelectNumber) {
                        mSelectNumber = mCurrentNumber;
                        invalidate();
                    }
            }
            return true;
        }
    
        /**
         * 返回评分等级
         *
         * @return
         */
        public int getSelectNumber() {
            return mSelectNumber;
        }
    }
    
    XML中使用
     <com.cyq.customview2.page6.MyRatingView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:padding="10dp"
            app:bothPadding="10dp"
            app:normalRatingBar="@drawable/rating_normal_bar"
            app:ratingNum="5"
            app:selectRatingBar="@drawable/rating_select_bar" />
    
  • 相关阅读:
    要么优秀,要么负责阅读作业二感想
    Python核心编程学习日记之数字,序列
    Python核心编程学习日记之错误处理
    Python核心编程学习日记之语法和对象
    Innobakcupex 代码解析
    通过initconnect + binlog 实现MySQL审计功能
    关于Relay Log无法自动删除的问题
    MySQL中 timeout相关参数解析
    慢查询日志中出现超大时间的案例分析
    主键乱序插入对Innodb性能的影响
  • 原文地址:https://www.cnblogs.com/chenyangqi/p/9512761.html
Copyright © 2011-2022 走看看