倒计时自定义view

153 阅读1分钟
public class HyCountDownTimeView extends LinearLayout {
    private Context context; // 传入的上下文对象
    protected TextView hourTextView; // 时
    protected TextView minuteTextView; // 分
    protected TextView secondTextView; // 秒
    protected TextView spliteLeftView;
    protected TextView spliteRightView;
    private long mGapTime; // 传入设置的时间间隔即倒计时的总时长
    private long mCount = 1000; // 倒计时的步长
    private int timeBackground = -1;
    private int spliteBackground = -1;
    private int timeTextSize = 8; // 字体大小
    private int timeTextColor = Color.WHITE; //  时间字体颜色
    private int spliteTextSize = -1; // 分隔符字体大小
    private int spliteTextColor = Color.WHITE; // 分隔符字体颜色
    private int timeTextWidth = 30;
    private int timeTextHeight = 30;
    private int spliteTextWidth = -1;
    private int spliteTextHeight = -1;
    private String spliteText = ":";
    private StringBuilder sb = new StringBuilder();
    private HashMap<Integer, CountDownTimer> hyCountDownTimerHashMap = new HashMap<>();

    public HyCountDownTimeView(Context context) {
        this(context, null);
    }

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

    public HyCountDownTimeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public HyCountDownTimeView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.context = context;
        init(attrs, defStyleAttr, defStyleRes);
    }

    public void init(AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        setGravity(Gravity.CENTER_HORIZONTAL);
        if (attrs != null) {
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.HyTimeView, defStyleAttr, defStyleRes);
            timeBackground = ta.getResourceId(R.styleable.HyTimeView_hyTimeBackground, -1);
            spliteBackground = ta.getResourceId(R.styleable.HyTimeView_hySpliteBackground, -1);
            timeTextSize = ta.getDimensionPixelSize(R.styleable.HyTimeView_hyTimeTextSize, 8);
            spliteTextSize = ta.getDimensionPixelSize(R.styleable.HyTimeView_hySpliteTextSize, -1);
            timeTextColor = ta.getColor(R.styleable.HyTimeView_hyTimeTextColor, Color.WHITE);
            spliteTextColor = ta.getColor(R.styleable.HyTimeView_hySpliteTextColor, Color.WHITE);
            timeTextWidth = ta.getDimensionPixelSize(R.styleable.HyTimeView_hyTimeTextWidth, 30);
            timeTextHeight = ta.getDimensionPixelSize(R.styleable.HyTimeView_hyTimeTextHeight, 30);
            spliteTextWidth = ta.getDimensionPixelSize(R.styleable.HyTimeView_hySpliteTextWidth, -1);
            spliteTextHeight = ta.getDimensionPixelSize(R.styleable.HyTimeView_hySpliteTextHeight, -1);
            mGapTime = ta.getInteger(R.styleable.HyTimeView_hyGapTime, 0) * 1000L;
            spliteText = ta.getString(R.styleable.HyTimeView_hySpliteText);
            ta.recycle();
        }
        hourTextView = new TextView(context);
        minuteTextView = new TextView(context);
        secondTextView = new TextView(context);
        spliteLeftView = new TextView(context);
        spliteRightView = new TextView(context);
        hourTextView.setGravity(Gravity.CENTER);
        minuteTextView.setGravity(Gravity.CENTER);
        secondTextView.setGravity(Gravity.CENTER);
        spliteLeftView.setGravity(Gravity.CENTER);
        spliteRightView.setGravity(Gravity.CENTER);
    }

    public void setHyTimeTextSize(int textSize) {
        this.timeTextSize = textSize;
    }

    public void setHySpliteTextSize(int textSize) {
        this.spliteTextSize = textSize;
    }

    public void setHyTimeTextColor(int color) {
        this.timeTextColor = color;
    }

    public void setHySpliteTextColor(int color) {
        this.spliteTextColor = color;
    }

    public void setHyTimeBackground(int bgColor) {
        this.timeBackground = bgColor;
    }

    public void setHySpliteBackground(int bgColor) {
        this.spliteBackground = bgColor;
    }

    public void setHySpliteText(String spliteText) {
        this.spliteText = spliteText;
    }

    //(秒)
    public void setHyGapTime(Long mGapTime) {
        this.mGapTime = mGapTime * 1000L;
    }

    /**
     * 结束倒计时
     */
    public void hyCancelTimer() {
        Log.d("HyCountDownTimeView", "cancelTimer");
        sb.delete(0, sb.length());
        for (int id : hyCountDownTimerHashMap.keySet()) {
            Log.d("HyCountDownTimeView", "cancelTimer->id: " + id);
            hyCountDownTimerHashMap.get(id).cancel();
        }
        hyCountDownTimerHashMap.clear();
    }

    /**
     * 开始倒计时
     */
    public void hyStartTimer() {
        Log.d("HyCountDownTimeView", "startCountDown->this.getChildCount(): " + this.getChildCount());
        if (this.getChildCount() == 0 && hourTextView != null && minuteTextView != null && secondTextView != null) {
            // 时间字体颜色
            hourTextView.setTextColor(timeTextColor);
            minuteTextView.setTextColor(timeTextColor);
            secondTextView.setTextColor(timeTextColor);
            // 时间字体大小
            hourTextView.setTextSize(timeTextSize);
            minuteTextView.setTextSize(timeTextSize);
            secondTextView.setTextSize(timeTextSize);
            // 分隔符字体颜色
            spliteLeftView.setTextColor(spliteTextColor);
            spliteRightView.setTextColor(spliteTextColor);
            // 分隔符字体大小
            if (spliteTextSize != -1) {
                spliteLeftView.setTextSize(spliteTextSize);
                spliteRightView.setTextSize(spliteTextSize);
            } else { // 如果没有设置字体大小,那就用时间的字体大小
                spliteLeftView.setTextSize(timeTextSize);
                spliteRightView.setTextSize(timeTextSize);
            }

            hourTextView.setWidth(timeTextWidth);
            hourTextView.setHeight(timeTextHeight);
            minuteTextView.setWidth(timeTextWidth);
            minuteTextView.setHeight(timeTextHeight);
            secondTextView.setWidth(timeTextWidth);
            secondTextView.setHeight(timeTextHeight);
            if (spliteTextWidth != -1) {
                spliteLeftView.setWidth(spliteTextWidth);
                spliteRightView.setWidth(spliteTextWidth);
            } else {
                spliteLeftView.setWidth(timeTextWidth);
                spliteRightView.setWidth(timeTextWidth);
            }
            if (spliteTextHeight != -1) {
                spliteLeftView.setHeight(spliteTextHeight);
                spliteRightView.setHeight(spliteTextHeight);
            } else {
                spliteLeftView.setHeight(timeTextHeight);
                spliteRightView.setHeight(timeTextHeight);
            }

            // 时间背景样式
            if (timeBackground != -1) {
                hourTextView.setBackground(context.getDrawable(timeBackground));
                minuteTextView.setBackground(context.getDrawable(timeBackground));
                secondTextView.setBackground(context.getDrawable(timeBackground));
            }
            // 分隔符背景样式
            if (spliteBackground != -1) {
                spliteLeftView.setBackground(context.getDrawable(spliteBackground));
                spliteRightView.setBackground(context.getDrawable(spliteBackground));
            }
            spliteLeftView.setText(spliteText);
            spliteRightView.setText(spliteText);
            /*-------------如果设置其他属性 可以在这设置---------*/
            addView(hourTextView);
            addView(spliteLeftView);
            addView(minuteTextView);
            addView(spliteRightView);
            addView(secondTextView);
        }
        hyStartCountDown();
    }

    private void hyStartCountDown() {
        Log.d("HyCountDownTimeView", "startCountDown->id: " + getId());
        if (hyCountDownTimerHashMap.get(getId()) != null) {
            hyCountDownTimerHashMap.get(getId()).cancel();
        }
        hyCountDownTimerHashMap.put(getId(), new CountDownTimer(mGapTime, 1000) {

            @Override
            public void onTick(long millisUntilFinished) {
                millisUntilFinished /= 1000L;
                long hour = millisUntilFinished / 3600;
                if (hour < 10) {
                    sb.append("0").append(hour);
                } else {
                    sb.append(hour);
                }
                hourTextView.setText(sb.toString());
                sb.delete(0, sb.length());

                long minutes = (millisUntilFinished % 3600) / 60;
                if (minutes < 10) {
                    sb.append("0").append(minutes);
                } else {
                    sb.append(minutes);
                }
                minuteTextView.setText(sb.toString());
                sb.delete(0, sb.length());

                long second = (millisUntilFinished % 3600) % 60;
                if (second < 10) {
                    sb.append("0").append(second);
                } else {
                    sb.append(second);
                }
                secondTextView.setText(sb.toString());
                sb.delete(0, sb.length());
            }

            @Override
            public void onFinish() {
                Log.d("HyCountDownTimeView", "倒计时结束了");
            }
        }.start());
        Log.d("HyCountDownTimeView", "spliteText: " + spliteText);
    }
}



<resources>
    <declare-styleable name="HyTimeView">
        <attr name="hyTimeBackground" format="reference" />
        <attr name="hySpliteBackground" format="reference" />
        <attr name="hyTimeTextSize" format="dimension" />
        <attr name="hySpliteTextSize" format="dimension" />
        <attr name="hyTimeTextColor" format="color" />
        <attr name="hySpliteTextColor" format="color" />
        <attr name="hyTimeTextWidth" format="dimension" />
        <attr name="hyTimeTextHeight" format="dimension" />
        <attr name="hySpliteTextWidth" format="dimension" />
        <attr name="hySpliteTextHeight" format="dimension" />
        <attr name="hyGapTime" format="integer" />
        <attr name="hySpliteText" format="string" />
    </declare-styleable>

</resources>

效果图,经典红配绿,赏心悦目