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" />
    
  • 相关阅读:
    vue-router路由器的使用
    组件间数据传递
    引用模块和动态组件
    vue自定义全局和局部指令
    vue实例的属性和方法
    vue生命周期以及vue的计算属性
    vue 发送ajax请求
    安装vue-cli脚手架
    vue指令详解
    scrapy-redis组件的使用
  • 原文地址:https://www.cnblogs.com/chenyangqi/p/9512761.html
Copyright © 2011-2022 走看看