之前看到过一个自定义的下载按钮,在点击后,播放一个小动画,然后按钮就变成一个圆形的progressbar,中间文字显示下载比例,外围轮廓弧度显示下载进度,自己也按照样子写了一个!
按钮的效果图:
图:按钮的初始状态
图:按钮在下载中
另外按钮从初始状态到下载中状态时有一个过渡的动画效果,是用valueAnimator实现的!由于不会传动图,所以就不上图了!
实现原理:
1.在ondraw中画出初始状态
2.给自定义view添加点击事件(自定义interface,在点击事件中先播放动画,后面操作让用户来实现)
3.根据用户通过setprogress()传来的progress值来更新view,计算比例,显示出来
原理很简单,下面贴出来每一部分的代码:
1.在ondraw中画出初始状态
// draw the inner circle
mPaint.setColor(mInnnerColor);
mPaint.setAntiAlias(true);
mPaint.setStyle(Style.FILL);
canvas.drawCircle(length, length, mInnerRadius, mPaint);
// draw arrow
Path path = new Path();
path.moveTo(length - mInnerRadius / 2, length);
path.lineTo(length, length + dx);
path.lineTo(length + mInnerRadius / 2, length);
mPaint.setColor(mOutterColor);
mPaint.setStyle(Style.STROKE);
mPaint.setStrokeCap(Cap.ROUND);
mPaint.setStrokeWidth(mOutterRadius);
canvas.drawPath(path, mPaint);
canvas.drawLine(length, length - dx, length, length + dx, mPaint);
if (point_pos > 0) {
canvas.drawPoint(length, point_pos, mPaint);
}
2.自定义一个点击事件的interface
public interface OnclickListener {
public void onClick();
}
自定义的接口中就只有一个方法onclick!该方法会在view初始化的时候把该方法的实现设置给view的onclick中,但是会在调用前先播放一个动画,相当于包装了一层!
//init方法
private void init() {
mPaint = new Paint();
length = mInnerRadius + mOutterRadius;
dx = mInnerRadius / 2;
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startValueAnimator();
if (listener != null) {
listener.onClick();
}
}
});
}
可以看出,在该onclick的方法中,先调用了startValueAnimator();而后再去调用自定义接口的onclick!
而startValueAnimator();则是播放了一个动画!
3.在动画播放完成后,就要去根据下载进度更新view的界面了
// draw the inner circle
mPaint.setColor(mInnnerColor);
mPaint.setAntiAlias(true);
mPaint.setStyle(Style.FILL);
canvas.drawCircle(length, length, mInnerRadius, mPaint);
// draw percent
mPaint.setColor(mOutterColor);
mPaint.setStrokeWidth(mOutterRadius / 8);
mPaint.setTextSize(length/4);
mPaint.setTextAlign(Align.CENTER);
canvas.drawText((int) mProgress * 100 / mMax + "%", length, length + 25, mPaint);
// draw oval
mPaint.setColor(mOutterColor);
mPaint.setStyle(Style.STROKE);
mPaint.setStrokeWidth(mOutterRadius);
mPaint.setStrokeCap(Cap.BUTT);
RectF f = new RectF(mOutterRadius / 2, mOutterRadius / 2, length * 2 - mOutterRadius / 2, length * 2 - mOutterRadius / 2);
canvas.drawArc(f, -90, 360 * mProgress / mMax, false, mPaint);
这样一个可以播放动画的圆形的下载按钮就完成了,但是由于该view的实现原理是ondraw去更新页面,所以就不能够像系统的progressbar一样直接在其他线程直接调用setprogress去更新界面,该view需要通过handler去调用setprogress来更新界面!