Android 自定义View——动态进度条

效果图:

这里写图片描述 

这个是看了梁肖的demo,根据他的思路自己写了一个,但是我写的这个貌似计算还是有些问题,这个过程还是有点曲折的,不过还是觉得收获挺多的。比如通动画来进行动态的展示(之前做的都是通过Handler进行更新的所以现在换一种思路觉得特别好),还有圆弧的起止角度,矩形区域的计算等!关于绘制我们可以循序渐进,比如最开始先画圆,然后再画周围的线,最后设置动画部分就可以了。不多说了,上代码了。

代码

自定义View

public class ColorProgressBar extends View{
    //下面这两行在本demo中没什么用,只是前几天看别人的代码时学到的按一定尺寸,设置其他尺寸的方式,自动忽略或者学习一下也不错
//    private int defaultStepIndicatorNum= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,40,getResources().getDisplayMetrics());
//    int mCircleRadius=0.28f*defaultStepIndicatorNum;


    //布局的宽高
    private int mWidth;
    private int mHeight;


    //底层圆画笔
    private Paint mPaintbg;
    //顶层圆的画笔
    private Paint mPaintft;
    //周围线的画笔
    private Paint mPaintLine;

    //外层线条的长度
    private int mLongItem=dip2px(20);
    //线条与圆的间距
    private int mDistanceItem=dip2px(10);
    //进度条的最大宽度(取底层进度条与顶层进度条宽度最大的)
    private int mProgressWidth;

    //底层圆的颜色
    private int mBackColor;
    //顶层圆的颜色
    private int mFrontColor;
    //底层圆、顶层圆的宽度
    private float mBackWidth;
    private float mFrontWidth;
    //设置进度
    private float currentvalue;
    //通过动画演示进度
    private ValueAnimator animator;
    private int curvalue;



    public ColorProgressBar(Context context) {
        this(context,null,0);
    }

    public ColorProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public ColorProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.ColorProgressBar);
        mBackColor= ta.getColor(R.styleable.ColorProgressBar_back_color, Color.BLACK);
        mFrontColor=ta.getColor(R.styleable.ColorProgressBar_front_color,mBackColor);
        mBackWidth=ta.getDimension(R.styleable.ColorProgressBar_back_width,dip2px(10));
        mFrontWidth=ta.getDimension(R.styleable.ColorProgressBar_front_width,dip2px(10));
        mProgressWidth=mBackWidth>mFrontWidth?(int)mBackWidth:(int)mFrontWidth;
        //注意释放资源
        ta.recycle();
        init();
    }

    /**
     * 都是画笔初始化
     */
    private void init() {
        mPaintbg=new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintbg.setStrokeWidth(mProgressWidth);
        mPaintbg.setColor(mBackColor);
        mPaintbg.setStrokeCap(Paint.Cap.ROUND);
        mPaintbg.setStyle(Paint.Style.STROKE);

        mPaintft=new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintft.setColor(mFrontColor);
        mPaintft.setStyle(Paint.Style.STROKE);
        mPaintft.setStrokeWidth(mFrontWidth);
        mPaintft.setStrokeCap(Paint.Cap.ROUND);

        mPaintLine=new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaintLine.setColor(Color.BLACK);
        mPaintLine.setStrokeWidth(5);

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mWidth=mHeight=getScreenWidth()*2/3;
        setMeasuredDimension(mWidth,mHeight);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制底层圆弧,矩形的具体计算见图片
       canvas.drawArc(new RectF(mProgressWidth+mDistanceItem+mLongItem,mProgressWidth+mDistanceItem+mLongItem,mWidth-mProgressWidth-mDistanceItem-mLongItem,mHeight-mProgressWidth-mDistanceItem-mLongItem),0,360,true,mPaintbg);
        //绘制边缘线
        canvas.save();
        canvas.rotate(144,mWidth/2,mHeight/2);
        for(int i=0;i<=30;i++){
            canvas.rotate(-9,mWidth/2,mHeight/2);
            if(i%5==0){
                canvas.drawLine(mWidth/2,10,mWidth/2,mLongItem,mPaintbg);
            }else {
                canvas.drawLine(mWidth/2,25,mWidth/2,mLongItem,mPaintLine);
            }
        }

        canvas.restore();
        //给画笔设置渐变
        SweepGradient sweepGradient=new SweepGradient(mWidth/2,mHeight/2,Color.RED,Color.YELLOW);
        mPaintft.setShader(sweepGradient);
        //绘制顶层圆弧,currentvalue在改变时呈现动态效果
          canvas.drawArc(new RectF(mProgressWidth+mDistanceItem+mLongItem,mProgressWidth+mDistanceItem+mLongItem,mWidth-mProgressWidth-mDistanceItem-mLongItem,mHeight-mProgressWidth-mDistanceItem-mLongItem),135,currentvalue,false,mPaintft);
        mPaintft.setTextSize(100);
        mPaintft.setTextAlign(Paint.Align.CENTER);
        //绘制文本
        canvas.drawText(String.format("%.0f",currentvalue),mWidth/2,mHeight/2+50,mPaintft);

    }

    /**
     * 设置动画
     * @param value
     */
    public void setCurrentValue(float value){
//        currentvalue=value;
        animator=ValueAnimator.ofFloat(currentvalue,value);
        animator.setDuration(3000);
        animator.setTarget(currentvalue);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                currentvalue= (float) valueAnimator.getAnimatedValue();
                curvalue=curvalue/10;
                 invalidate();
            }
        });
        animator.start();

    }
    private int dip2px(float dip){
        float density=getContext().getResources().getDisplayMetrics().density;
        return (int)(dip*density+0.5f);
    }
}
 private int getScreenWidth(){
        WindowManager manager= (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display=manager.getDefaultDisplay();
        if(Build.VERSION.SDK_INT>=13){
            Point point=new Point();
            display.getSize(point);
            return point.x;

            }else {
            return display.getWidth();
        }
    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158

矩形计算

这里写图片描述

Activity调用

 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.colorprogressbar);
        mBtStart1= (Button) findViewById(R.id.bt1);

        bar1= (ColorProgressBar) findViewById(R.id.cp1);

        mBtStart1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                bar1.setCurrentValue(270);
            }
        });

    }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

自定义属性

 <declare-styleable name="ColorProgressBar">
       <attr name="back_color" format="color"></attr>
        <attr name="front_color" format="color"></attr>
        <attr name="back_width" format="dimension"></attr>
        <attr name="front_width" format="dimension"></attr>
    </declare-styleable>
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

布局

注意:为了使用自定义属性需要添加一行代码(AS)

xmlns:app="http://schemas.android.com/apk/res-auto"
 
 
  • 1
  • 1

布局

 <LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <Button
            android:id="@+id/bt1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="start1"/>

        <com.demo.demo.networkdemo.colorprogressbar.widget.ColorProgressBar
            android:id="@+id/cp1"
            android:layout_width="232dp"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal"
            app:back_color="@color/colorPrimary"
            app:front_color="@color/colorAccent"
            android:background="@mipmap/ic_launcher"/>


    </LinearLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值