ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

简单自定义一:splash界面的倒计时控件

2019-06-14 12:50:21  阅读:329  来源: 互联网

标签:控件 自定义 int textStr private splash import android


实现思路:

1.该控件由圆环和文字组成,所有我们可以继承Textview去实现;

2.考虑到设置固定宽高时,文字范围容易超出圆环,所有建议布局时用wrap_content,我们根据文字大小+文字与圆环的padding来确定控件最终的大小

效果图

上代码之前,我们来回顾下自定义的一些知识点

自定义控件我们可以分成以下几类
1. 直接继承View

     需要重写onMeasure和onDraw方法,计算控件的实际宽高并绘制,注意把padding和wrap_content因素考虑进去

2. 直接继承ViewGroup,实现特殊的布局功能(例如搜索历史的流布局等)

    需要重写onMeasure、onLayout和onDraw方法,计算控件的实际宽高和childview的布局位置并绘制,注意把padding和wrap_content以及childview的margin因素考虑进去

3. 继承特殊View,例如本篇文章介绍的案例就是继承TextView

    重写onMeasure和onDraw方法,注意点padding

4. 继承特殊ViewGroup,例如继LinearLayout,实现多个控件组合效果

    重写onMeasure、onLayout和onDraw方法,注意点padding等因素

 

自定义的属性配置attrs.xml

    <declare-styleable name="SplashTimer">
        <attr name="timer_duration" format="integer"/>
        <attr name="android:text"/>
        <attr name="android:textColor"/>
        <attr name="android:textSize"/>
        <attr name="timer_padding" format="dimension"/>
        <attr name="timer_arcColor" format="color"/>
        <attr name="timer_arcStrokeWidth" format="dimension"/>
    </declare-styleable>

该控件在xml布局中设置

1.倒计时时长

2.中间文字(默认“跳转”)

3.中间文字颜色(默认白色)

4.中间文字与圆环的padding

5.圆环的颜色

6.圆环的环宽

例如:

        app:timer_padding="5dp"
        android:text="跳过"
        android:textColor="@color/white"
        app:timer_duration="2000"
        app:timer_arcColor="@color/white"
        app:timer_arcStrokeWidth="2dp"

完整代码

package com.jsq.crm.mvp.view.wegit.otherview;

import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.widget.TextView;

import com.jsq.crm.R;
import com.jsq.crm.utils.CommonUtils;

import androidx.annotation.Nullable;

/**
 * splash跳转倒计时控件
 * 建议xml布局中使用wrap_content设置长宽
 */
@SuppressLint("AppCompatCustomView")
public class SplashTimerTextView extends TextView {
    // 倒计时动画时间
    private int duration = 0;
    //倒计时文字
    private String textStr;
    //文字与圆环的padding
    private int textPadding;
    // 动画扫过的角度
    private int mSweepAngle = 360;
    // 属性动画
    private ValueAnimator animator;
    // 矩形用来保存位置大小信息
    private final RectF mRect = new RectF();
    // 圆弧的画笔
    private Paint mArcPaint;
    //圆环的宽
    private int mArcStrokeWidth;
    //圆环默认的颜色
    private int mArcColor = 0xFFFFFF;
    //圆环文字的颜色
    private int mTextColor = 0xFFFFFF;
    //文字的大小
    private int mTextSize;
    // 文字画笔
    private Paint mTextPaint;
    //控件的最终宽
    private int mWidth;
    //控件的最终高
    private int mHeight;

    public SplashTimerTextView(Context context) {
        super(context);
        init();
    }

    public SplashTimerTextView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs,0);
    }

    public SplashTimerTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SplashTimer);
        duration = typedArray.getInteger(R.styleable.SplashTimer_timer_duration,0);
        textPadding = (int) typedArray.getDimension(R.styleable.SplashTimer_timer_padding,CommonUtils.dp2px(context,8f));
        mArcStrokeWidth = (int) typedArray.getDimension(R.styleable.SplashTimer_timer_arcStrokeWidth,CommonUtils.dp2px(context,3f));
        mArcColor = typedArray.getColor(R.styleable.SplashTimer_timer_arcColor, mArcColor);
        mTextSize = typedArray.getDimensionPixelSize(R.styleable.SplashTimer_android_textSize,CommonUtils.sp2px(15));
        mTextColor = typedArray.getColor(R.styleable.SplashTimer_android_textColor, mTextColor);
        textStr = typedArray.getString(R.styleable.SplashTimer_android_text);
        if (CommonUtils.isEmpty(textStr)){
            textStr = "跳过";
        }
        typedArray.recycle();

        init();
    }

    /**
     * 初始化画笔
     */
    private void init() {
        //设置画笔平滑
        mArcPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        //设置画笔颜色
        mArcPaint.setColor(mArcColor);
        //设置画笔样式:边框类型
        mArcPaint.setStyle(Paint.Style.STROKE);
        //设置画笔的宽
        mArcPaint.setStrokeWidth(mArcStrokeWidth);

        //设置文字画笔
        mTextPaint = new Paint();
        //去锯齿
        mTextPaint.setAntiAlias(true);
        //设置字体大小
        mTextPaint.setTextSize(mTextSize);
        //设置画笔颜色
        mTextPaint.setColor(mTextColor);
        //设置画笔样式:填充类型
        mTextPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //计算控件的实际宽
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        if (widthMode == MeasureSpec.AT_MOST){
            int desire = (int) (mTextPaint.measureText(textStr) + textPadding + mArcPaint.getStrokeWidth() + getPaddingLeft() + getPaddingRight());
            mWidth = Math.min(desire,widthSize);
        }else {
            mWidth = widthSize;
        }

        //计算控件的实际高
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        if (heightMode == MeasureSpec.AT_MOST){
            int desire = (int) (mTextPaint.measureText(textStr) + textPadding + mArcPaint.getStrokeWidth() + getPaddingTop() + getPaddingBottom());
            mHeight = Math.min(desire,heightSize);
        }else {
            mHeight = heightSize;
        }

        //最终决定当前控件的宽高
        setMeasuredDimension(mWidth,mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //绘制圆环
        mRect.top = getPaddingTop();
        mRect.left = getPaddingLeft();
        mRect.bottom = getHeight() - getPaddingBottom();
        mRect.right = getWidth() - getPaddingRight();
        canvas.drawArc(mRect, -90, mSweepAngle, false, mArcPaint);

        //绘制文字,计算文字居中绘制的位置
        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        float x = (mWidth - mTextPaint.measureText(textStr)) / 2;
        float y = mHeight / 2 + (Math.abs(fontMetrics.ascent) - fontMetrics.descent) / 2;
        canvas.drawText(textStr, x, y, mTextPaint);

        startAnim();
    }

    /**
     * 开始属性动画,通过属性动画,去更新圆环的绘制
     */
    private void startAnim() {
        if (mSweepAngle != 360 || duration <= 0) return;

        animator = ValueAnimator.ofInt(360);
        animator.setDuration(duration);
        animator.addUpdateListener(animation -> {
            mSweepAngle = (int) animation.getAnimatedValue();
            invalidate();
        });
        animator.start();
    }

    /**
     * 获取倒计时的时长,进行界面更新或逻辑
     * @return
     */
    public int getDuration() {
        return duration;
    }

    /**
     * 设置圆环中间显示的文字
     * @param textStr
     * @return
     */
    public String setText(String textStr) {
        return this.textStr = textStr;
    }
}

 

标签:控件,自定义,int,textStr,private,splash,import,android
来源: https://blog.csdn.net/weixin_38617084/article/details/91959960

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有