Android自定义View实例教程~自定义可拖拽评价进度条二「完全自定义」

Android自定义评View实例教程~自定义可拖拽评价进度条二「完全自定义」

实际效果,在上一节的基础上给控件下方加入了一个随进度移动的评价文字。

并且这个文字是有范围的变化,移动过程中也有透明度和大小的变化。

Android自定义View实例教程~自定义可拖拽评价进度条二「完全自定义」_第1张图片
Screenrecorder-2019-01-15-21-42-44-828~1 - 副本.gif

文字有4个等级,分别是体验很差,体验一般,体验还行,体验很好,对应的其实就是我们4个评价的等级。

并且当用户滑动到某个评价区域内离开手指后,要有一个回弹的效果,毕竟我们评价的等级个数是确定的嘛,又不是百分比。

当然我们也可以根据自己的需求修改评价文字的等级个数,比如修改为三个等级,【效果很差,效果还行,效果很好】等。

项目的源代码已经上传到Github仓库的AProgress文件夹下了,该章节是在上一章节的基础上进行开发的。

  • 自定义可拖拽评价进度条一
  • 自定义可拖拽评价进度条二

其中L.d()是日志封装工具类,等同于Log.d("HelloWord",);

进度条边距,高度的处理

虽然是在上一节的代码上继续写,不过为了区别,我把上一节的EasyProgress复制,改名为AEasyProgress继续开发。先声明几个必要属性。

//文本画笔
private Paint mTextPaint;

//文本的大小
private float mTextSize = ADensity.dip2px(14);

/**
 * 评价文字集合,如体验很好,体验一般,体验不错,体验很好4个等级
 * 之所以使用集合,不使用String数组是想让它保持可扩展性,我们后面课题提供一个接口,让用户自己决定要设置多少个评价等级
 */
private List evaluates = new ArrayList<>();

//文本的宽度
private int textWidth;

//文本的高度
private int textHeight;

//文本的透明度
private float textAlpha;

//文本缩放后的最小的大小
private float textSizeRadio = 0.8f;

//一段评价区间的大小
private float distance;

//评价区间一半的大小
private float half = distance / 2;

初始化画笔

//初始化文本画笔
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextAlign(Paint.Align.CENTER);
mTextPaint.setStrokeWidth(3);
mTextPaint.setColor(Color.parseColor("#9a9a9a"));
mTextPaint.setTextSize(mTextSize);

接着我们原本应该是要对进度条边距进行处理了,还记得上一节对圆形进度指示器的处理吗?

其实这里文字也是一样,因为它也是永远将文字中点对准当前进度的,所以要进行边距处理

但在处理边距之前,我们先弄清一个概念吧,就是一个评价所属的范围,也就是distance区间。

这个区间是评价到达的点前面或者后面吗?No,我们应该是使得它在左右两侧的特定范围都有一个回弹的效果,大概是这样的效果

Android自定义View实例教程~自定义可拖拽评价进度条二「完全自定义」_第2张图片
方向.gif

我特意在中间绘制了一条线,只要圆点指示器在这条线左右的一定范围类滑动,就都属于效果还行的“地盘”。

当你在这个区域滑动,然后松开手指的时候,就会回弹到中间效果还行的坐标位置

那这个范围是多少呢,还是看图

Android自定义View实例教程~自定义可拖拽评价进度条二「完全自定义」_第3张图片
评价范围.png

中间的框框就是一个评价的区域,而在最左边和最右边的评价等级其实也拥有一块完整,大小相同的区域,只是因为他们是在屏幕的最边缘,所以有一半我们是触碰不到的(超过进度条范围也是触摸不到的)

所以实际上上面整个进度条,拥有的文字区间个数是0.5+1+0.5,等于两个,而我们的评价集合里面有三个元素

所以到这里就可以推导一个文字区间的大小了,等于(进度条的实际长度)/集合长度-1。

这个时候我们再去onLayout方法里面对文字的对边距进行处理,然后顺便把我们上面讲的文字区间的大小也初始化好

//初始化几个距离参数
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);


    width = getWidth();//view的宽度
    height = getHeight();//view的高度

    //让左边距至少为半个圆点指示器的距离
    paddingLeft = getPaddingLeft();//距离左边的距离
    if (getPaddingLeft() < mCircleRadius) {
        L.d("onLayout");
        paddingLeft = mCircleRadius;
    }
    //让右边距至少为半个圆点指示器的距离
    paddingRight = getPaddingRight();//距离右边的距离
    if (getPaddingRight() < mCircleRadius) {
        paddingRight = mCircleRadius;
    }

    //暂时在这里给列表设置三个数据
    evaluates.add("效果很差");
    evaluates.add("效果还行");
    evaluates.add("效果很棒");
    //定义一个标准的文本宽度
    textWidth = (int) mTextPaint.measureText("效果很差");


    //让左边距至少为文字宽度的一半
    if (paddingLeft < textWidth / 2) {
        paddingLeft = textWidth / 2;
    }

    //让右边距至少为文字宽度的一半
    if (paddingRight < textWidth / 2) {
        paddingRight = textWidth / 2;
    }

    //如果当前进度小于左边距
    setCurrentProgress();
    //最大进度长度等于View的宽度-(左边的内边距+右边的内边距)
    maxProgress = width - paddingLeft - paddingRight;

    //规定评价进度条至少要有两个元素值
    if (evaluates.size() < 2) {
        Toast.makeText(App.getContext(), "数据设置出错", Toast.LENGTH_SHORT).show();
    } else {
        //一个文字区间的宽度
        distance = maxProgress / (evaluates.size() - 1);
    }
    //半个文字区间的宽度
    half = distance / 2;
}

同样,因为高度增加了文字的高度,也要重新处理

//重新计算控件的宽,高
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    int width = MeasureSpec.getSize(widthMeasureSpec);
    //获取文本高度
    textHeight = (int) (mTextPaint.descent() - mTextPaint.ascent());
    /**
     *进度条下部分的高度(圆点指示器圆点一下)应该为为圆点指示器半径*1.8+文本高度,
     *因为进度条永远在中心,所以上面高度也要一样,*2
     */
    int minHeight = (int) ((mCircleRadius * 1.8 + textHeight) * 2);
    int height = resolveSize(minHeight, heightMeasureSpec);
    setMeasuredDimension(width, height);
}

之所以文字高度在这里处理是因为onMeasure的生命周期的执行存续在onLayout上面,依次为, onMeasure() -> onSizeCahnged() -> onLayout() ->onDraw();

接着到我们的onDraw方法测试一下吧,这里我们暂时不对评价等级做处理,先看看文字绘制是否成功,Activity和xml布局的代码(除了进度条控件换成这个进度条)和上一节一模一样就可以了

/**
 * onDraw方法里面
 * 绘制文字
 */
canvas.drawText(evaluates.get(0), currentProgress, (float) (height / 2 + mCircleRadius * 2.8), mTextPaint);

就是这样的效果

Android自定义View实例教程~自定义可拖拽评价进度条二「完全自定义」_第4张图片
文字效果.gif

文字随着我们的进度的改变而改变,我们下一步要做的就是给他添加范围区域等级的变化和回弹效果。

这一小段的完整代码

/**
 * Created by 舍长 on 2019/1/10
 * describe:一个简单的进度条,下方带评价文字
 */
public class AEasyProgress extends View {

    //灰色背景线段的画笔
    private Paint bgPaint;

    //实际进度绿色线段的画笔
    private Paint progressPaint;

    //圆点指示器的画笔
    private Paint circlePaint;

    //圆点指示器的半径
    private int mCircleRadius = ADensity.dip2px(12);

    //进度条的最大宽度
    private float maxProgress;

    //进度条当前的宽度
    private float currentProgress;

    //当前View的宽度
    private int width;

    //当前View的高度
    private int height;

    //距离左边的内边距
    private int paddingLeft;

    //距离右边的内边距
    private int paddingRight;
    //文本画笔
    private Paint mTextPaint;

    //文本的大小
    private float mTextSize = ADensity.dip2px(14);

    /**
     * 评价文字集合,如体验很好,体验一般,体验不错,体验很好4个等级
     * 之所以使用集合,不使用String数组是想让它保持可扩展性,我们后面课题提供一个接口,
     * 让用户自己决定要设置多少个评价等级
     */
    private List evaluates = new ArrayList<>();

    //文本的宽度
    private int textWidth;

    //文本的高度
    private int textHeight;

    //文本的透明度
    private float textAlpha;

    //文本缩放后的最小的大小
    private float textSizeRadio = 0.8f;

    //一段评价区间的大小
    private float distance;

    //一半评价区间的大小
    private float half = distance / 2;


    public AEasyProgress(Context context) {
        super(context);
    }

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

    public AEasyProgress(Context context, @Nullable AttributeSet attrs,
                            int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initPaint();//初始化画笔
    }

    /**
     * 初始化画笔
     */
    private void initPaint() {
        //进度条背景画笔
        bgPaint = new Paint();
        bgPaint.setColor(Color.parseColor("#F0F0F0"));//灰色
        bgPaint.setStyle(Paint.Style.FILL_AND_STROKE);//填充且描边
        bgPaint.setAntiAlias(true);//抗锯齿
        bgPaint.setStrokeCap(Paint.Cap.ROUND);//线冒的头是圆的
        bgPaint.setStrokeWidth(ADensity.dip2px(3));//大小为3dp转px

        //设置进度画笔
        progressPaint = new Paint();
        progressPaint.setColor(Color.parseColor("#0DE6C2"));//绿色
        progressPaint.setStyle(Paint.Style.FILL_AND_STROKE);//填充且描边
        progressPaint.setAntiAlias(true);//抗锯齿
        progressPaint.setStrokeCap(Paint.Cap.ROUND);//线冒的头圆原的
        progressPaint.setStrokeWidth(ADensity.dip2px(3));//大小为3dp转px

        //圆点指示器
        circlePaint = new Paint();
        circlePaint.setAntiAlias(true);//设置抗锯齿
        circlePaint.setColor(Color.parseColor("#fafafa"));//颜色
        circlePaint.setShadowLayer(ADensity.dip2px(2), 0, 0, 
        Color.parseColor("#38000000"));//外阴影颜色
        circlePaint.setStyle(Paint.Style.FILL);//填充


        //初始化文本画笔
        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setTextAlign(Paint.Align.CENTER);
        mTextPaint.setStrokeWidth(3);
        mTextPaint.setColor(Color.parseColor("#9a9a9a"));
        mTextPaint.setTextSize(mTextSize);
    }

    //重新计算控件的宽,高
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        //获取文本高度
        textHeight = (int) (mTextPaint.descent() - mTextPaint.ascent());
        //最小部分为你那个相等的部分,下部分为圆点指示器半径*1.8+文本高度,因为进度条永远在中心,所以上面高度也要一样,*2
        int minHeight = (int) ((mCircleRadius * 1.8 + textHeight) * 2);
        int height = resolveSize(minHeight, heightMeasureSpec);
        setMeasuredDimension(width, height);
    }

    //返回高度值,作用和resolveSize方法一样
    private int measureHeight(int heightMeasureSpec) {
        int result;
        int mode = MeasureSpec.getMode(heightMeasureSpec);//获取高度类型
        int size = MeasureSpec.getSize(heightMeasureSpec);//获取高度数值
        //制定的最小高度标准
        int minHeight = mCircleRadius * 2 + (ADensity.dip2px(2) * 2);
        //如果用户设定了指定大小
        if (mode == MeasureSpec.EXACTLY) {
            /**
             * 虽然用户已经指定了大小,但是万一指定的大小小于圆点指示器的高度,
             * 还是会出现显示不全的情况,所以还要进行判断
             */
            L.d("EXACTLY");
            if (size < minHeight) {
                result = minHeight;
            } else {
                result = size;
            }
        }
        //如果用户没有设定明确的值
        else {
            //设定高度为圆点指示器的直径
            result = minHeight;
        }
        return result;
    }

    //初始化几个距离参数
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);


        width = getWidth();//view的宽度
        height = getHeight();//view的高度

        //让左边距至少为半个圆点指示器的距离
        paddingLeft = getPaddingLeft();//距离左边的距离
        if (getPaddingLeft() < mCircleRadius) {
            L.d("onLayout");
            paddingLeft = mCircleRadius;
        }
        //让右边距至少为半个圆点指示器的距离
        paddingRight = getPaddingRight();//距离右边的距离
        if (getPaddingRight() < mCircleRadius) {
            paddingRight = mCircleRadius;
        }

        //暂时在这里给列表设置三个数据
        evaluates.add("效果很差");
        evaluates.add("效果还行");
        evaluates.add("效果很棒");
        //定义一个标准的文本宽度
        textWidth = (int) mTextPaint.measureText("效果很差");


        //让左边距至少为文字宽度的一半
        if (paddingLeft < textWidth / 2) {
            paddingLeft = textWidth / 2;
        }

        //让右边距至少为文字宽度的一半
        if (paddingRight < textWidth / 2) {
            paddingRight = textWidth / 2;
        }

        //如果当前进度小于左边距
        setCurrentProgress();
        //最大进度长度等于View的宽度-(左边的内边距+右边的内边距)
        maxProgress = width - paddingLeft - paddingRight;

        //规定评价进度条至少要有两个元素值
        if (evaluates.size() < 2) {
            Toast.makeText(App.getContext(), "数据设置出错", Toast.LENGTH_SHORT).show();
        } else {
            //一个文字区间的宽度
            distance = maxProgress / (evaluates.size() - 1);
        }
        //半个文字区间的宽度
        half = distance / 2;
    }

    //绘制控件
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        /**
         * 绘制背景线段
         */
        canvas.drawLine(paddingLeft, height / 2, width - paddingRight, height / 2, bgPaint);
        /**
         * 绘制实际进度线段
         */
        canvas.drawLine(paddingLeft, height / 2, currentProgress, height / 2, progressPaint);
        //要支持阴影下过必须关闭硬件加速
        setLayerType(LAYER_TYPE_SOFTWARE, null);//发光效果不支持硬件加速
        /**
         * 绘制圆点指示器
         */
        canvas.drawCircle(currentProgress, getHeight() / 2, mCircleRadius, circlePaint);
        /**
         * 绘制文字
         */
        canvas.drawText(evaluates.get(0), currentProgress, (float) (height / 2 + mCircleRadius * 2.8), mTextPaint);
//        canvas.drawText(evaluates.get(0), currentProgress, mCircleRadius * 2 + (ADensity.dip2px(2) * 2), mTextPaint);


    }

    //触摸
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            //按住
            case MotionEvent.ACTION_DOWN:
                //设置进度值
                setMotionProgress(event);
                return true;
            //移动
            case MotionEvent.ACTION_MOVE:
                //获取当前触摸点,赋值给当前进度
                setMotionProgress(event);
                return true;
        }
        return super.onTouchEvent(event);
    }

    //设置进度值
    private void setMotionProgress(MotionEvent event) {
        //获取当前触摸点,赋值给当前进度
        currentProgress = (int) event.getX();
        //如果当前进度小于左边距
        setCurrentProgress();
        //看数学公式就可以了,实际百分比进度数值
        float result = ((currentProgress - paddingLeft) * 100) / maxProgress;
        //进行空值判断
        if (onProgressListener != null) {
            onProgressListener.onSelect((int) result);
        }
        invalidate();
    }


    //设置当前进度条进度,从1到100
    public void setProgress(int progress) {
        if (progress > 100 || progress < 0) {
            Toast.makeText(App.getContext(), "输入的进度值不符合规范", Toast.LENGTH_SHORT).show();
        }
        setCurrentProgress();
        //设置当前进度的宽度
        currentProgress = ((progress * maxProgress) / 100) + paddingLeft;
        onProgressListener.onSelect(progress);
        invalidate();
    }

    private void setCurrentProgress() {
        if (currentProgress < paddingLeft) {
            currentProgress = paddingLeft;
        }
        //如果当前进度大于宽度-右边距
        else if (currentProgress > width - paddingRight) {
            currentProgress = width - paddingRight;
        }
    }

    //当前选中进度的回调
    private OnProgressListener onProgressListener;

    public interface OnProgressListener {
        void onSelect(int progress);
    }

    public void setOnProgressListener(OnProgressListener onProgressListener) {
        this.onProgressListener = onProgressListener;
    }
}

范围的计算和抬手回弹效果

之前我们已经安排了一个评价等级的范围,那时候是用一整块文字区间来讲解,我们接下来看看这张图

Android自定义View实例教程~自定义可拖拽评价进度条二「完全自定义」_第5张图片
一半的评价范围.png

这张图显示的,是半个文字区间,半个文字区间的范围。想想也是,因为我们是要对等级的前后都进行判断,所以用一半一半,这样的来判断是最方便的,用代码来表示就是这样

所以我们只要判断当前的进度位置在哪个等级的范围,我们就将文本绘制出来

   int progress = (int) (currentProgress - paddingLeft);
        if (progress < half) {
            canvas.drawText(evaluates.get(0), currentProgress, (float) (height / 2 + mCircleRadius * 2.8), mTextPaint);
        }
        //第二段范围
        if ((progress > half) && (progress <= half * 3)) {
            canvas.drawText(evaluates.get(1), currentProgress, (float) (height / 2 + mCircleRadius * 2.8), mTextPaint);
        }
        //第三段范围,这里写4也可以,但其实5才是完整的一块文字区间,另外半个在屏幕外
        if ((progress > half * 3) && (progress <= half * 5)) {
            canvas.drawText(evaluates.get(2), currentProgress, (float) (height / 2 + mCircleRadius * 2.8), mTextPaint);
        }

我们只要对着上面的图,去数格子就行了。到这里如果运行程序其实就已经完成了,这样的方式无疑是最容易理解的,但是可称不上最优解

因为维护起来其实不方便,上面我们说过我们要给评价等级设置集合,如果等级有4,5,6,7,8个呢?我们就需要照着写8个if,不大方便。所以我们得想办法,观看这三个if,其实可以找到某种规律的。

如果说progress的距离要在x

所以我们可以将代码推导成这样,其中distance为一整块文字区间,half为一半的文字权健

//第一段范围
int progress = (int) (currentProgress - paddingLeft);
for (int i = 0; i < evaluates.size(); i++) {
    if ((progress > ((i * distance) - half)) && (progress<=(half+(i*distance)))) {
        canvas.drawText(evaluates.get(i), currentProgress, (float) (height / 2 + mCircleRadius * 2.8), mTextPaint);
    }
}

这样我们就实现了和上面一模一样的功能,而且它是可扩展的,不管你添加多少个等级都可以。

接下来我们还使用这条公式,给进度条添加一个回弹的效果,它会在我们的触摸方法里面进行处理。

不过和前面的章节不同的是,我们不能让进度条按到哪里就跳到哪里了,而是只能靠拖动老移动距离。

因为如果我们还是让它按到哪里就跳到哪里,再加上我们还有回弹的效果,整个控件就会跳来跳去,就会让人看了很迷茫,体验很糟糕。

   //开始x
    float startX;
    //结束x
    float endX;
    //当前的进度百分比
    float result;

    //触摸
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            //按住
            case MotionEvent.ACTION_DOWN:
//                //设置进度值
//                setMotionProgress(event);
                startX = event.getX();
                return true;
            //移动
            case MotionEvent.ACTION_MOVE:
                endX = event.getX();
                float dx = endX - startX;
                startX = endX;
                currentProgress = currentProgress + dx;
                //如果当前进度小于左边距
                setCurrentProgress();
                //看数学公式就可以了,实际百分比进度数值
                result = ((currentProgress - paddingLeft) * 100) / maxProgress;
                //进行空值判断
                if (onProgressListener != null) {
                    onProgressListener.onSelect((int) result);
                }
                invalidate();
                return true;
            //抬起回弹效果
            case MotionEvent.ACTION_UP:
                int progress = (int) (currentProgress - paddingLeft);
                for (int i = 0; i < evaluates.size(); i++) {
                    if ((progress > ((i * distance) - half)) && (progress <= (half + (i * distance)))) {
                        currentProgress = distance * i + paddingLeft;
                    }
                }
                //如果当前进度小于左边距
                setCurrentProgress();
                //看数学公式就可以了,实际百分比进度数值
                result = ((currentProgress - paddingLeft) * 100) / maxProgress;
                if (result == 100) {
                    L.d("curr:" + currentProgress);
                }
                //进行空值判断
                if (onProgressListener != null) {
                    onProgressListener.onSelect((int) result);
                }
                break;
        }
        return true;
    }

    private void setCurrentProgress() {
        if (currentProgress < paddingLeft) {
            currentProgress = paddingLeft;
        }
        //如果当前进度大于宽度-右边距
        else if (currentProgress > width - paddingRight) {
            currentProgress = width - paddingRight;
        }
    }

上面就是我们修改后的触摸方法啦,到这里我们就完成这一小段了

设置颜色的透明度和大小变化

文字透明度的动画我们通过一个工具类来实现AColor

/**
 * Created by 舍长 on 2019/1/14
 * describe:修改颜色透明度工具类
 */
public class AColor {
    /**
     * 修改颜色透明度
     * @param color
     * @param alpha
     * @return
     */
    public static int changeAlpha(int color, int alpha) {
        int red = Color.red(color);
        int green = Color.green(color);
        int blue = Color.blue(color);
        return Color.argb(alpha, red, green, blue);
    }
}

传进来的alpha来控制透明度,255是完全不透明,依次减小,直到0就变成完全透明的状态

我们前面声明了两个属性

    //文本的透明度
    private int textAlpha;

    //文本缩放后的最小的大小
    private float textSizeRadio = 0.8f;

textAlpha用来改变透明度,textSizeRadio表示文本最小是多小,缩放后的文本最小也不会小于这个大小。

我们需要根据文字区域的前后来判断透明度是增加还是减少,在前面的区域,是透明度逐渐增加,后面的区域,是透明度逐渐减小,我们修改onDraw方法


        int progress = (int) (currentProgress - paddingLeft);
        for (int i = 0; i < evaluates.size(); i++) {
            if ((progress > ((i * distance) - half)) && (progress <= (half + (i * distance)))) {
                //前半段
                if ((progress - (i * distance)) < 0) {
                    L.d("前半段");
                    float radio = -(progress - (i * distance)) / half;
                    textAlpha = 1 - radio;
                    mTextSize = ADensity.dip2px(14);
                    float size = (mTextSize - mTextSize * textSizeRadio) * (radio);
                    mTextSize = mTextSize - size;
                    mTextPaint.setColor(AColor.changeAlpha(Color.parseColor("#9a9a9a"), (int) (textAlpha * 0xff)));
                    canvas.drawText(evaluates.get(i), progress + paddingLeft, (float) (height / 2 + mCircleRadius * 2.8), mTextPaint);
                }
                //后半段
                else {
                    L.d("后半段");
                    float radio = (progress - (i * distance)) / half;
                    //textAlpha之间变小,radio逐渐变大
                    textAlpha = 1 - radio;
                    //要减去的范围,当textAlpha等于1时,文本最小
                    float size = (mTextSize - mTextSize * textSizeRadio) * (radio);
                    mTextSize = mTextSize - size;
                    mTextPaint.setColor(AColor.changeAlpha(Color.parseColor("#9a9a9a"), (int) (textAlpha * 0xff)));
                    canvas.drawText(evaluates.get(i), progress + paddingLeft, (float) (height / 2 + mCircleRadius * 2.8), mTextPaint);
                }
            }
        }

推导过程确实是复杂,只能是慢慢推导,先推导出前半段和后半段的区间,然后再推导文本大小,最后

是透明度。接着将我们原本写在onLayout的集合数据去掉,提供一个方法来初始化集合。


    //设置评价字符串集合
    public void setEvaluates(String[] strings) {
        evaluates.clear();
        evaluates.addAll(Arrays.asList(strings));
        //每一段文字区间的大小
        //当集合的长度为0,没有数据时
        if (evaluates.size() < 2) {
            Toast.makeText(App.getContext(), "少需要两个评价等级", Toast.LENGTH_SHORT).show();
        }
        //当有多个数据时,区间距离就是整个进度条除以集合个数-1
        else {
            distance = maxProgress / (evaluates.size() - 1);
        }

最后在Actiivty中调用

easyProgress.setEvaluates(new String[]{"效果很差", "效果还行","效果很棒"});

这一段的代码就不贴了,因为已经和源代码一模一样了,需要的可以去源代码查看AEasyProgress.java文件,和AEasyActiivty

句子控

等世界温柔,不如自己动手

你可能感兴趣的:(Android自定义View实例教程~自定义可拖拽评价进度条二「完全自定义」)