自定义圆环倒计时

来源:互联网 发布:淘宝客服月总结报告 编辑:程序博客网 时间:2024/05/29 05:06
public class CountDownView extends View{    private static int defaultCircleSolideColor = Color.BLUE;    private static int defaultCircleStrokeColor = Color.WHITE;//最底层的颜色    private static int defaultCircleStrokeWidth = 10;    private static int defaultCircleRadius = 60;    private static int progressColor = Color.YELLOW;//进度条的颜色    private static int progressWidth = 11;//>defaultCircleStrokeWidth    private static int smallCircleSolideColor = Color.BLACK;    private static int smallCircleStrokeColor = Color.WHITE;    private static float smallCircleStrokeWidth = 8;    private static float smallCircleRadius = 30;    private static int textColor = Color.WHITE;//BLACK    private static float textSize = 30;    private static Paint defaultCriclePaint;    private static Paint progressPaint;    private static Paint textPaint;    private static float currentAngle;    public static String textDesc;    public static long countdownTime;    private static int mStartSweepValue = -90;    //设置画布圆形背景    private Paint backgroundPaint;    public static ValueAnimator animator;    public CountDownView(Context context) {        super(context);    }    public CountDownView(Context context, AttributeSet attrs) {        super(context, attrs);        initStyle(attrs);        setPaint();    }    public CountDownView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        //获取自定义属性        initStyle(attrs);        setPaint();    }    private void initStyle(AttributeSet attrs){        TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CountDownProgress);        int indexCount = typedArray.getIndexCount();        for(int i=0;i<indexCount;i++){            int attr = typedArray.getIndex(i);            switch (attr){                case R.styleable.CountDownProgress_default_circle_solide_color:                    defaultCircleSolideColor = typedArray.getColor(attr, defaultCircleSolideColor);                    break;                case R.styleable.CountDownProgress_default_circle_stroke_color:                    defaultCircleStrokeColor = typedArray.getColor(attr, defaultCircleStrokeColor);                    break;                case R.styleable.CountDownProgress_default_circle_stroke_width:                    defaultCircleStrokeWidth = (int) typedArray.getDimension(attr, defaultCircleStrokeWidth);                    break;                case R.styleable.CountDownProgress_default_circle_radius:                    defaultCircleRadius = (int) typedArray.getDimension(attr, defaultCircleRadius);                    break;                case R.styleable.CountDownProgress_progress_color:                    progressColor = typedArray.getColor(attr, progressColor);                    break;                case R.styleable.CountDownProgress_progress_width:                    progressWidth = (int) typedArray.getDimension(attr, progressWidth);                    break;                case R.styleable.CountDownProgress_small_circle_solide_color:                    smallCircleSolideColor = typedArray.getColor(attr, smallCircleSolideColor);                    break;                case R.styleable.CountDownProgress_small_circle_stroke_color:                    smallCircleStrokeColor = typedArray.getColor(attr, smallCircleStrokeColor);                    break;                case R.styleable.CountDownProgress_small_circle_stroke_width:                    smallCircleStrokeWidth = (int) typedArray.getDimension(attr, smallCircleStrokeWidth);                    break;                case R.styleable.CountDownProgress_small_circle_radius:                    smallCircleRadius = (int) typedArray.getDimension(attr, smallCircleRadius);                    break;                case R.styleable.CountDownProgress_text_color:                    textColor = typedArray.getColor(attr, textColor);                    break;                case R.styleable.CountDownProgress_text_size:                    textSize = (int) typedArray.getDimension(attr, textSize);                    break;            }        }        typedArray.recycle();    }    private void setPaint() {        //默认圆        defaultCriclePaint = new Paint();        defaultCriclePaint.setAntiAlias(true);//抗锯齿        defaultCriclePaint.setDither(true);//防抖动        defaultCriclePaint.setStyle(Paint.Style.STROKE);        defaultCriclePaint.setStrokeWidth(defaultCircleStrokeWidth);        defaultCriclePaint.setColor(defaultCircleStrokeColor);//这里先画边框的颜色,后续再添加画笔画实心的颜色        //默认圆上面的进度弧度        progressPaint = new Paint();        progressPaint.setAntiAlias(true);        progressPaint.setDither(true);        progressPaint.setStyle(Paint.Style.STROKE);        progressPaint.setStrokeWidth(progressWidth);        progressPaint.setColor(progressColor);        progressPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔笔刷样式        //文字画笔        textPaint = new Paint();        textPaint.setAntiAlias(true);        textPaint.setDither(true);        textPaint.setStyle(Paint.Style.FILL);        textPaint.setColor(textColor);        textPaint.setTextSize(textSize);        backgroundPaint=new Paint();        backgroundPaint.setAntiAlias(true);//抗锯齿        backgroundPaint.setDither(true);//防抖动        backgroundPaint.setStyle(Paint.Style.FILL);        backgroundPaint.setStrokeWidth(defaultCircleStrokeWidth);        backgroundPaint.setColor(progressColor);//这里先画边框的颜色,后续再添加画笔画实心的颜色    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.save();        canvas.translate(getPaddingLeft(), getPaddingTop());        //背景圆        canvas.drawCircle(defaultCircleRadius, defaultCircleRadius, defaultCircleRadius, backgroundPaint);        //画默认圆        canvas.drawCircle(defaultCircleRadius, defaultCircleRadius, defaultCircleRadius, defaultCriclePaint);        //画进度圆弧        //currentAngle = getProgress()*1.0f/getMax()*360;recf适用于划出一块绘制的区域mStartSweepValue是开始的位置        canvas.drawArc(new RectF(0, 0, defaultCircleRadius*2, defaultCircleRadius*2),mStartSweepValue, 360*currentAngle,false,progressPaint);        //画中间文字        //   String text = getProgress()+"%";        //获取文字的长度的方法        float textWidth = textPaint.measureText(textDesc);        float textHeight = (textPaint.descent() + textPaint.ascent()) / 2;        canvas.drawText(textDesc, defaultCircleRadius - textWidth/2, defaultCircleRadius - textHeight, textPaint);        canvas.restore();    }    /**     * 如果该View布局的宽高开发者没有精确的告诉,则需要进行测量,如果给出了精确的宽高则我们就不管了     * @param widthMeasureSpec     * @param heightMeasureSpec     */    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int widthMode = MeasureSpec.getMode(widthMeasureSpec);        int heightMode = MeasureSpec.getMode(heightMeasureSpec);        int widthSize;        int heightSize;        int strokeWidth = Math.max(defaultCircleStrokeWidth, progressWidth);        //精确指定宽高        if(widthMode != MeasureSpec.EXACTLY){            widthSize = getPaddingLeft() + defaultCircleRadius*2 + strokeWidth + getPaddingRight();            widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);        }        if(heightMode != MeasureSpec.EXACTLY){            heightSize = getPaddingTop() + defaultCircleRadius*2 + strokeWidth + getPaddingBottom();            heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);        }        super.onMeasure(widthMeasureSpec, heightMeasureSpec);    }    //属性动画    public void startCountDownTime(final OnCountdownFinishListener countdownFinishListener){        setClickable(true);        animator = ValueAnimator.ofFloat(0, 1.0f);        //动画时长,让进度条在CountDown时间内正好从0-360走完,这里由于用的是CountDownTimer定时器,倒计时要想减到0则总时长需要多加1000毫秒,所以这里时间也跟着+1000ms        animator.setDuration(countdownTime );//+ 1000        animator.setInterpolator(new LinearInterpolator());//匀速        animator.setRepeatCount(0);//表示不循环,-1表示无限循环        //值从0-1.0F 的动画,动画时长为countdownTime,ValueAnimator没有跟任何的控件相关联,那也正好说明ValueAnimator只是对值做动画运算,而不是针对控件的,我们需要监听ValueAnimator的动画过程来自己对控件做操作        //添加监听器,监听动画过程中值的实时变化(animation.getAnimatedValue()得到的值就是0-1.0)        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {            @Override            public void onAnimationUpdate(ValueAnimator animation) {                /**                 * 这里我们已经知道ValueAnimator只是对值做动画运算,而不是针对控件的,因为我们设置的区间值为0-1.0f                 * 所以animation.getAnimatedValue()得到的值也是在[0.0-1.0]区间,而我们在画进度条弧度时,设置的当前角度为360*currentAngle,                 * 因此,当我们的区间值变为1.0的时候弧度刚好转了360度                 */                currentAngle = (float) animation.getAnimatedValue();                //       Log.e("currentAngle",currentAngle+"");                invalidate();//实时刷新view,这样我们的进度条弧度就动起来了            }        });        //开启动画        animator.start();        //还需要另一个监听,监听动画状态的监听器        animator.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {            }            @Override            public void onAnimationEnd(Animator animation) {                //倒计时结束的时候,需要通过自定义接口通知UI去处理其他业务逻辑                if(countdownFinishListener != null){                    countdownFinishListener.countdownFinished();                }                if(countdownTime > 0){                    setClickable(true);                }else{                    setClickable(false);                }            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });        //调用倒计时操作        countdownMethod();    }    public CountDownTimer timer;    //倒计时的方法    private void countdownMethod(){        timer= new CountDownTimer(countdownTime+1000, 1000) {            @Override            public void onTick(long millisUntilFinished) {                //         Log.e("time",countdownTime+"");                countdownTime = countdownTime-1000;                textDesc = "跳过("+((countdownTime/1000)) + ")";                //countdownTime = countdownTime-1000;                //刷新view                invalidate();            }            @Override            public void onFinish() {                //textDesc = 0 + "″";                //刷新view//                textDesc="跳过(0)";//                invalidate();            }        }.start();    }    public void setCountdownTime(long countdownTime){        this.countdownTime = countdownTime;        textDesc = countdownTime / 1000 + "″";    }    public interface OnCountdownFinishListener{        void countdownFinished();    }} 
<com.bawei.macbook.moni.persenter.CountDownView    android:id="@+id/countdwonview"    android:layout_width="90dp"    android:layout_height="100dp"    android:layout_alignParentRight="true"    android:layout_alignParentTop="true"    android:paddingTop="35dp"    android:paddingRight="10dp"    android:paddingLeft="10dp"    />//////////////////////////////////////////////////////////////////////////////////////// //设置自定义圆球在左上角移到右下角
public class MainActivity extends AppCompatActivity {    private CustomView2 yuan;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);         Display My_Display = getWindow().getWindowManager().getDefaultDisplay();        int Max_X = My_Display.getWidth();        int Max_Y = My_Display.getHeight();        yuan = (CustomView2) findViewById(R.id.yuan);        ObjectAnimator animator = ObjectAnimator.ofFloat(yuan, "translationX", Max_X);        ObjectAnimator animator1 = ObjectAnimator.ofFloat(yuan, "translationY", Max_Y);        AnimatorSet set = new AnimatorSet();        set.setDuration(4000);        set.play(animator).with(animator1);//a1,a2同时执行,之后执行a3        set.start();        set.addListener(new Animator.AnimatorListener() {            @Override            public void onAnimationStart(Animator animation) {            }            @Override            public void onAnimationEnd(Animator animation) {                Intent intent = new Intent(MainActivity.this, MainActivity2.class);                startActivity(intent);            }            @Override            public void onAnimationCancel(Animator animation) {            }            @Override            public void onAnimationRepeat(Animator animation) {            }        });    }}//定义圆球
public class CustomView2 extends View{    public CustomView2(Context context) {        super(context);    }    public CustomView2(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);    }    @Override    protected void onDraw(Canvas canvas) {        Paint paint=new Paint();        paint.setColor(Color.YELLOW);        paint.setStyle(Paint.Style.FILL);       // paint.setAntiAlias(true);        // 画圆形        canvas.drawCircle(100, 100, 100, paint);    }}

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 盐酸溅到皮肤上怎么办 磷性磷酸酶高440怎么办 浓硫酸沾到皮肤上怎么办 浓硫酸溅到皮肤上怎么办 浓硫酸滴到皮肤上怎么办 浓硫酸洒在皮肤上怎么办 浓硫酸溅到眼睛里怎么办 盐酸弄到眼睛了怎么办 稀硫酸进眼睛里怎么办 草酸弄到皮肤上怎么办 大理石被盐酸烧发白怎么办 香薰蜡烛化了怎么办 吸入了大量燃烧纸气体怎么办 狗链条上锈了怎么办 思维迟钝反应慢嘴笨怎么办 小孩思维慢反应迟钝怎么办 苹果4g网络慢怎么办 医院没有号了怎么办啊 fgo宝具动画卡顿怎么办 死刑犯在执行前死亡怎么办 汕头交警 违章扣分怎么办办理 幼儿园家长不保险应该怎么办 csgo掉白银坑了怎么办 错过教资认定现场确认怎么办 乡村建设导致民房开裂怎么办 项目部公章丢了怎么办 手机掉了没有卡怎么办 苹果系统软件删了还是出现怎么办 钉钉检测到作弊怎么办 电脑麦说话声音小怎么办 穿越火线麦克风有杂音怎么办 手闲不住就抠东西怎么办 大便堵在肛门口怎么办 在外地流量不够用怎么办 电脑键盘数字键没反应怎么办 音响音量键坏了怎么办 摩托罗拉移动电话通话没声音怎么办 摩托罗拉对讲机充电座坏了怎么办 手机导航键太灵敏怎么办 经侦大队不立案怎么办 槐茂酱菜太咸怎么办