先上图:
核心就在于progress中的dialog和bar的合用,bar也是自定义的,值得一提的是progressbar是为数不多的继承至View的控件,那么就代表着可拓展性很强~~~开始是考虑直接自定义dialog实现,但是因为不能重写onDraw只能改属性或者onCreate,卡住了,如果有用自定义dialog实现了请给点思路或者给个demo,小子不胜感激~
工程目录,很简单:
注意一下,用了向下兼容的属性动画包
自定义progressbar的代码,核心是onDraw和onMeasure
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(getResources().getColor(R.color.white_navy));//画布背景色
mPaint.setColor(getResources().getColor(R.color.white_light));
mPaint.setAntiAlias(true);
mPaint.setStyle(Style.STROKE);//空心
mPaint.setStrokeWidth(strokeWidth);//线的宽度
canvas.drawCircle(getWidth()/2, getHeight()/2, mRadius, mPaint);
mPaint.setColor(getResources().getColor(R.color.orange_light));
mPaint.setStrokeWidth(strokeWidth+4);//覆盖线的宽度
mPaint.setAntiAlias(true);
/**
* oval :指定圆弧的外轮廓矩形区域。计算方式看看就清楚了,核心是x、y相关的坐标
startAngle: 圆弧起始角度,单位为度。
sweepAngle: 圆弧扫过的角度,顺时针方向,单位为度,从右中间开始为零度。
useCenter: 如果为True时,在绘制圆弧时将圆心包括在内,
*/
//Log.e("max", ""+getMax());
//Log.e("getProgress", ""+getProgress());
float sweepAngle = getProgress() * 1.0f / getMax() * 360;//根据现在值和最大值的百分比计算出弧线现在的度数
canvas.drawArc(new RectF(getPaddingLeft(), getPaddingTop(), getPaddingLeft()+strokeWidth+mRadius*2, getPaddingTop()+strokeWidth+mRadius*2), -90,
sweepAngle, false, mPaint);
}
@Override
protected synchronized void onMeasure(int widthMeasureSpec,
int heightMeasureSpec) {
//根据半径算出占屏幕的比重,圆环宽,padding相关
int widthSize = mRadius * 2 + strokeWidth+getPaddingLeft()+getPaddingRight();
setMeasuredDimension(widthSize, widthSize);
}
注释的很详细,没有画双环圆,就用弧线覆盖的方式实现的
自定义progressdialog:
/**
* 自定义的dialog,展示自定义的progressbar
* @author sen
*/
public class CustomTimingProgressDialog extends ProgressDialog {
//private Context context;
private TextView dialog_tv_test;
private CustomTimingCircle dialog_tv_cc;
private Timer timer;
public CustomTimingProgressDialog(Context context) {
super(context);
//this.context = context;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_timing_progress_dialog);
dialog_tv_test = (TextView) findViewById(R.id.dialog_tv_test);
dialog_tv_cc = (CustomTimingCircle) findViewById(R.id.dialog_tv_cc);
dialog_tv_cc.setMax(100);
timer = new Timer();
//计时器任务,延迟多少开始数,数的速度
timer.schedule(timerTask, 0,1000);
//这里用的是nineold的属性动画向下兼容包
ValueAnimator animator = ValueAnimator.ofInt(100,0);
animator.setDuration(5000);
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int animatedValue = (Integer) animation.getAnimatedValue();
dialog_tv_cc.setProgress(animatedValue);
}
});
animator.start();
}
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
//super.handleMessage(msg);
if (msg.what > 0) {
dialog_tv_test.setText(msg.what+ "\n秒");
} else {
dialogDismiss();
}
}
};
TimerTask timerTask = new TimerTask() {
int second = 5;
@Override
public void run() {
Message msg = new Message();
msg.what = second;
handler.sendMessage(msg);
second--;
//Log.e("second", "" + second);
}
};
/**
* 强制取消掉dialog,同样的计时器也同时取消掉
* 看具体情况来判断是否打开新的界面
*/
public void dialogDismiss() {
this.dismiss();
timer.cancel();
}
xml______________________________
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:id="@+id/dialog_tv_cc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="10dip"
/>
android:id="@+id/dialog_tv_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:layout_centerInParent="true"
android:text="5\n秒"
android:textColor="@color/orange_light"
/>
额,好像注释有点少,不过很简单。onCreate,xml是核心,用timerTask和Handler控制对文本的改变,属性动画控制bar的progress值的改变,实现动画效果。
主函数的代码片也放上来吧
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void ok(View v){
new CustomTimingProgressDialog(this).show();
}
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:onClick="ok"
android:text="测试"
/>