Android 自定义控件实现广告页面倒计时,里利用handler实现循环操作

时间:2022-11-09 16:48:09
public class SkipView extends View {
    public static final int TEXT_SIZE = 30;//文字的大小
    public static final int TEXT_MARGIN = 10;//文字距离中间圆边框的间距
    public static final int ARC_WIDTH = 8;//外部圆弧的笔画宽度
    private float mMeasureTextWidth;
    private float mCircleDoubleRadius;
    private float mArcDoubleRadius;
    private RectF mRectF;
    private Paint mArcPaint;
    private Paint mCirclePaint;
    private Paint mTextPaint;
    private Handler mHandler;
    public SkipView(Context context) {
        super(context);
    }
    public SkipView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {
        //文字的画笔
        mTextPaint = new Paint();
        mTextPaint.setTextSize(TEXT_SIZE);
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setAntiAlias(true);
        //中间的圆的画笔
        mCirclePaint = new Paint();
        mCirclePaint.setColor(Color.GRAY);
        mCirclePaint.setAntiAlias(true);
        //外部圆弧的画笔
        mArcPaint = new Paint();
        mArcPaint.setColor(Color.RED);
        mArcPaint.setAntiAlias(true);
        mArcPaint.setStyle(Paint.Style.STROKE);
        mArcPaint.setStrokeWidth(ARC_WIDTH);
        //1 文字的宽度   2 文字距离中间圆边框的间距  3 外部圆弧的笔画宽度
        mMeasureTextWidth = mTextPaint.measureText("跳过");
        //计算中间的圆的直径
        mCircleDoubleRadius = mMeasureTextWidth + TEXT_MARGIN * 2;
        //计算外部的圆狐的直径
        mArcDoubleRadius = mCircleDoubleRadius + 2 * ARC_WIDTH;
        //准备一个矩形出来,画圆弧
        mRectF = new RectF(0+ARC_WIDTH/2, 0+ARC_WIDTH/2,
                mArcDoubleRadius-ARC_WIDTH/2, mArcDoubleRadius-ARC_WIDTH/2);
       //利用handler实现循环 自己给自己发消息
        mHandler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                //接收到消息,会去更新一下角度,重绘一下
                currentTime+=REFRESH_TIME;
                //当角度百分百了,就不再发消息了
                if(currentTime>totalShowTime){
                    //跳转页面
                    /*Toast.makeText(getContext()
                            , "跳转A页面", Toast.LENGTH_SHORT).show();*/
                    if(mOnSkipListener!=null){
                        mOnSkipListener.onSkip();
                    }
                    return;
                }
                invalidate();
                //继续发延时消息给自己
                this.sendEmptyMessageDelayed(0,REFRESH_TIME);
            }
        };
    }
    public static final int REFRESH_TIME = 100;
    public float currentTime = 0;
 //广告页面跳转的总时间
    public float totalShowTime =3000;
 //找到该控件调用该方法开始发消息
    public void start(){
        mHandler.sendEmptyMessageDelayed(0,REFRESH_TIME);
    }
//停止发消息的方法
    public void stop(){
        mHandler.removeCallbacksAndMessages(null);
    }
//给空间
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int eventAction = event.getAction();
        switch (eventAction) {
            case MotionEvent.ACTION_DOWN:
//设置透明度
                setAlpha(0.5f);
                break;
            case MotionEvent.ACTION_MOVE:
                break;
            case MotionEvent.ACTION_UP:
                //让handler的还未处理的消息被移除
                mHandler.removeCallbacksAndMessages(null);
                setAlpha(1f);
                //跳转页面
                /*
                Toast.makeText(getContext()
                        , "跳转A页面", Toast.LENGTH_SHORT).show();*/
                //在哪个页面中用到了这个控件,就在哪个页面写具体的逻辑
                if(mOnSkipListener!=null){
                mOnSkipListener.onSkip();
                }
                break;
        }
        return true;
    }

    //1 定义一个接口
    public interface OnSkipListener{
        void onSkip();
    }
    private OnSkipListener mOnSkipListener;
    //2 来一个Set方法,传递接口实例过来
    public void setOnSkipListener(OnSkipListener listener){
        mOnSkipListener = listener;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制3个东西
        //外部圆弧
        canvas.save();
        canvas.rotate(-90,getMeasuredWidth()/2,getMeasuredHeight()/2);
        float angle = currentTime/totalShowTime*360;
        canvas.drawArc(mRectF,0,angle,false,mArcPaint);
        canvas.restore();
        //中间的圆
        canvas.drawCircle(getMeasuredWidth()/2,getMeasuredHeight()/2,mCircleDoubleRadius/2,mCirclePaint);
        //内部的文字
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float ascent = fontMetrics.ascent;
        float descent = fontMetrics.descent;
        float top = fontMetrics.top;
        float bottom = fontMetrics.bottom;
        Log.e(getClass().getSimpleName()+" xmg", "onDraw: "+" top "+top
        +" ascent "+ascent+" descent "+descent+" bottom "+bottom);
        //文字居中的公式
        float baseLine = getMeasuredHeight()/2 - (top+bottom)/2
        canvas.drawText("跳过",getMeasuredWidth()/2-mMeasureTextWidth/2
                ,baseLine,mTextPaint);
    }