您的位置:首页 > 移动开发 > Android开发

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

2016-12-19 19:26 417 查看


效果图:


 

这个是看了梁肖的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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: