Android之打造可定制的全场秒杀倒计时控件

转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/51005062
本文出自:【顾林海的博客】

##前言

这几天翻看之前写的一些代码,感觉整体的代码设计上有点缺陷,为此买了本《设计模式之禅》,随说之前也研究过设计模式,但长时间不用忘了差不多,买本书补充下知识。


今天给大家带来的是自定义倒计时控件,为什么要写这个,是因为今天在京东首页看到了这个全场秒杀的倒计时控件,感觉挺不错的,于是乎写给大家看看,也算是一个思路吧,当然实现这种样式的控件方法有很多,大家可以按照自己的思路来写,那我这个倒计时有什么特点呢?可定制,颜色,背景,四周角度,文字大小都可定制。

先来看看效果吧:

倒计时控件

##如何使用

下载项目后将里面相关代码复制过去,创建一个继承BaseCountDownTimerView的类。

如以下:

package com.example.countdowntimerproject.view;

import android.content.Context;
import android.util.AttributeSet;

import com.example.countdowntimerproject.view.base.BaseCountDownTimerView;

public class MainDownTimerView extends BaseCountDownTimerView{

	public MainDownTimerView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
	}

	public MainDownTimerView(Context context, AttributeSet attrs) {
		this(context, attrs,0);
	}

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

	@Override
	protected String getStrokeColor() {
		return "333333";
	}

	@Override
	protected String getTextColor() {
		return "000033";
	}

	@Override
	protected int getCornerRadius() {
		return 1;
	}

	@Override
	protected int getTextSize() {
		return 15;
	}

	@Override
	protected String getBackgroundColor() {
		return null;
	}

	
	
}

创建继承自BaseCountDownTimerView的类时会重写几个方法,这几个方法含义如下:

/**
	 * 获取边框颜色
	 * 
	 * @return
	 */
	protected abstract String getStrokeColor();

	/**
	 * 设置背景色
	 * 
	 * @return
	 */
	protected abstract String getBackgroundColor();

	/**
	 * 获取文字颜色
	 * 
	 * @return
	 */
	protected abstract String getTextColor();

	/**
	 * 获取边框圆角
	 * 
	 * @return
	 */
	protected abstract int getCornerRadius();

	/**
	 * 获取标签文字大小
	 * 
	 * @return
	 */
	protected abstract int getTextSize();

创建完毕后,创建我们的xml:




    
    


接着在Activity中使用:

package com.example.countdowntimerproject;

import android.app.Activity;
import android.os.Bundle;

import com.example.countdowntimerproject.view.MainDownTimerView;

public class MainActivity extends Activity {

	private MainDownTimerView mMainDownTimerView;


	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		initViews();
		initEvent();
		startDownTimer();
	}

	private void initViews() {
		mMainDownTimerView = (MainDownTimerView) findViewById(R.id.count_down_timer_view);
		mMainDownTimerView.setDownTime(16000000);
	}

	private void initEvent() {
		mMainDownTimerView.setDownTimerListener(new OnCountDownTimerListener() {

			@Override
			public void onFinish() {
				Toast.makeText(MainActivity.this, "倒计时结束", Toast.LENGTH_SHORT)
						.show();
			}
		});
	}
	
	private void startDownTimer() {
		mMainDownTimerView.startDownTimer();
	}
	
}

setDownTime方法传入的是总的毫秒数,最后通过startDownTimer方法开启倒计时,cancelDownTimer方法是取消倒计时。

##自定义倒计时控件原理

整个控件的容器是LinearLayout,因此创建继承自LinearLayout的抽象类BaseCountDownTimerView,控件内的自控件是水平排列:

public abstract class BaseCountDownTimerView extends LinearLayout {

	public BaseCountDownTimerView(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		this.mContext = context;
		init();
	}

	public BaseCountDownTimerView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

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

	private void init() {
		this.setOrientation(HORIZONTAL);// 设置布局排列方式
		createView();// 创造三个标签
		addLabelView();// 添加标签到容器中
	}
}

标签的创建请查看《自定义瀑布流式的标签列表》这篇文章,创建完标签后,将标签添加到容器中去:

	/**
	 * 创建时、分、秒的标签
	 */
	private void createView() {
		mHourTextView = createLabel();
		mMinTextView = createLabel();
		mSecondTextView = createLabel();
	}

	/**
	 * 添加标签到容器中
	 */
	private void addLabelView() {
		removeAllViews();
		this.addView(mHourTextView);
		this.addView(createColon());
		this.addView(mMinTextView);
		this.addView(createColon());
		this.addView(mSecondTextView);
	}

	/**
	 * 创建冒号
	 * 
	 * @return
	 */
	private TextView createColon() {
		TextView textView = new TextView(mContext);
		textView.setTextColor(Color.BLACK);
		textView.setText(":");
		return textView;
	}

	/**
	 * 创建标签
	 * 
	 * @return
	 */
	private TextView createLabel() {
		TextView textView = new GradientTextView(mContext)
				.setTextColor(getTextColor()).setStrokeColor(getStrokeColor())
				.setBackgroundColor(getBackgroundColor())
				.setTextSize(getTextSize()).setStrokeRadius(getCornerRadius())
				.build();
		return textView;
	}

整体样式已经创建完毕,这里的倒计时是使用CountDownTimer来实现,通过CountDownTimer构造器创建对象时,传入两个值:

  public CountDownTimer(long millisInFuture, long countDownInterval) {
        mMillisInFuture = millisInFuture;
        mCountdownInterval = countDownInterval;
   }

millisInFuture:是总的毫秒数
countDownInterval:间隔毫秒数执行onTick方法

创建CountDownTimer实例时重写以下两个方法:

			@Override
			public void onTick(long millisUntilFinished) {
				setSecond(millisUntilFinished);
			}

			@Override
			public void onFinish() {
				OnCountDownTimerListener.onFinish();
			}

每间隔countDownInterval毫秒执行onTick方法,当倒计时结束后执行onFinish方法。

时、分、秒的计算比较简单,通过除以1000得到总的秒数,将总秒数求余60得到当前的秒;将总秒除以60得到总分,总分求余60的当前的分;总分除以60得总小时,总小时求余24得当前的时,具体公式代码如下:

	/**
	 * 设置秒
	 * 
	 * @param millis
	 */
	private void setSecond(long millis) {
		long totalSeconds = millis / 1000;
		String second = (int) (totalSeconds % 60) + "";// 秒
		long totalMinutes = totalSeconds / 60;
		String minute = (int) (totalMinutes % 60) + "";// 分
		long totalHours = totalMinutes / 60;
		String hour = (int) (totalHours % 24) + "";// 时
		Log.i("TAG", "hour:" + hour);
		Log.i("TAG", "minute:" + minute);
		Log.i("TAG", "second:" + second);
		if (hour.length() == 1) {
			hour = "0" + hour;
		}
		if (minute.length() == 1) {
			minute = "0" + minute;
		}
		if (second.length() == 1) {
			second = "0" + second;
		}
		mHourTextView.setText(hour);
		mMinTextView.setText(minute);
		mSecondTextView.setText(second);
	}

以下是完整的BaseCountDownTimerView类的源码:

package com.example.countdowntimerproject.view.base;

import android.content.Context;
import android.graphics.Color;
import android.os.CountDownTimer;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;
import android.widget.TextView;

public abstract class BaseCountDownTimerView extends LinearLayout {

	private Context mContext;

	/**
	 * 倒计时控制器
	 */
	private CountDownTimer mCountDownTimer;

	private OnCountDownTimerListener OnCountDownTimerListener;

	private int mMillis;

	/**
	 * 时
	 */
	private TextView mHourTextView;

	/**
	 * 分
	 */
	private TextView mMinTextView;

	/**
	 * 秒
	 */
	private TextView mSecondTextView;

	/**
	 * 获取边框颜色
	 * 
	 * @return
	 */
	protected abstract String getStrokeColor();

	/**
	 * 设置背景色
	 * 
	 * @return
	 */
	protected abstract String getBackgroundColor();

	/**
	 * 获取文字颜色
	 * 
	 * @return
	 */
	protected abstract String getTextColor();

	/**
	 * 获取边框圆角
	 * 
	 * @return
	 */
	protected abstract int getCornerRadius();

	/**
	 * 获取标签文字大小
	 * 
	 * @return
	 */
	protected abstract int getTextSize();

	public BaseCountDownTimerView(Context context, AttributeSet attrs,
			int defStyle) {
		super(context, attrs, defStyle);
		this.mContext = context;
		init();
	}

	public BaseCountDownTimerView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

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

	private void init() {
		this.setOrientation(HORIZONTAL);// 设置布局排列方式
		createView();// 创造三个标签
		addLabelView();// 添加标签到容器中
	}

	/**
	 * 创建时、分、秒的标签
	 */
	private void createView() {
		mHourTextView = createLabel();
		mMinTextView = createLabel();
		mSecondTextView = createLabel();
	}

	/**
	 * 添加标签到容器中
	 */
	private void addLabelView() {
		removeAllViews();
		this.addView(mHourTextView);
		this.addView(createColon());
		this.addView(mMinTextView);
		this.addView(createColon());
		this.addView(mSecondTextView);
	}

	/**
	 * 创建冒号
	 * 
	 * @return
	 */
	private TextView createColon() {
		TextView textView = new TextView(mContext);
		textView.setTextColor(Color.BLACK);
		textView.setText(":");
		return textView;
	}

	/**
	 * 创建标签
	 * 
	 * @return
	 */
	private TextView createLabel() {
		TextView textView = new GradientTextView(mContext)
				.setTextColor(getTextColor()).setStrokeColor(getStrokeColor())
				.setBackgroundColor(getBackgroundColor())
				.setTextSize(getTextSize()).setStrokeRadius(getCornerRadius())
				.build();
		return textView;
	}

	/**
	 * 创建倒计时
	 */
	private void createCountDownTimer() {
		mCountDownTimer = new CountDownTimer(mMillis, 1000) {

			@Override
			public void onTick(long millisUntilFinished) {
				setSecond(millisUntilFinished);
			}

			@Override
			public void onFinish() {
				OnCountDownTimerListener.onFinish();
			}
		};
	}

	/**
	 * 设置秒
	 * 
	 * @param millis
	 */
	private void setSecond(long millis) {
		long totalSeconds = millis / 1000;
		String second = (int) (totalSeconds % 60) + "";// 秒
		long totalMinutes = totalSeconds / 60;
		String minute = (int) (totalMinutes % 60) + "";// 分
		long totalHours = totalMinutes / 60;
		String hour = (int) (totalHours % 24) + "";// 时
		Log.i("TAG", "hour:" + hour);
		Log.i("TAG", "minute:" + minute);
		Log.i("TAG", "second:" + second);
		if (hour.length() == 1) {
			hour = "0" + hour;
		}
		if (minute.length() == 1) {
			minute = "0" + minute;
		}
		if (second.length() == 1) {
			second = "0" + second;
		}
		mHourTextView.setText(hour);
		mMinTextView.setText(minute);
		mSecondTextView.setText(second);
	}

	/**
	 * 设置监听事件
	 * 
	 * @param listener
	 */
	public void setDownTimerListener(OnCountDownTimerListener listener) {
		this.OnCountDownTimerListener = listener;
	}

	/**
	 * 设置时间值
	 * 
	 * @param millis
	 */
	public void setDownTime(int millis) {
		this.mMillis = millis;
	}

	/**
	 * 开始倒计时
	 */
	public void startDownTimer() {
		createCountDownTimer();// 创建倒计时
		mCountDownTimer.start();
	}

	public void cancelDownTimer() {
		mCountDownTimer.cancel();
	}

}




> 以下是完整的github项目地址,欢迎star,fork > github项目源码地址:[点击【项目源码】](https://github.com/LinhaiGu/CountDownTimerProject)

你可能感兴趣的:([,Android自定义控件,],Android开发笔记)