Android中自定义View仿京东秒杀倒计时

Android中自定义View仿京东秒杀倒计时

效果图
1.创建View:

"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:orientation="horizontal"
              android:padding="@dimen/j2dp">

    "@+id/lay_days"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:gravity="center">
        "wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/goodsdetail_timer_bg"
            android:gravity="center"
            android:paddingLeft="3dp"
            android:paddingRight="3dp">

            "@+id/tv_days_decade"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="0"
                android:textColor="@color/text_10"
                android:textSize="@dimen/j18dp"
                android:textStyle="bold"
                />

            "@+id/tv_days_unit"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="0"
                android:textColor="@color/text_10"
                android:textSize="@dimen/j18dp"
                android:textStyle="bold"
                />
        
        "wrap_content"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="天"
            android:textSize="@dimen/j12dp"
            android:textColor="@color/white"/>
    
    "@+id/lay_hour"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/goodsdetail_timer_bg"
        android:gravity="center"
        android:paddingLeft="3dp"
        android:paddingRight="3dp">

        "@+id/tv_hour_decade"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="@color/text_10"
            android:textSize="@dimen/j18dp"
            android:textStyle="bold"
            />

        "@+id/tv_hour_unit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="@color/text_10"
            android:textSize="@dimen/j18dp"
            android:textStyle="bold"
            />
    

    "wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="@dimen/j3dp"
        android:layout_marginRight="@dimen/j3dp"
        android:gravity="center"
        android:text=":"
        android:textColor="@color/white"
        android:textSize="@dimen/j18dp"/>

    "@+id/lay_min"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/goodsdetail_timer_bg"
        android:gravity="center"
        android:paddingLeft="3dp"
        android:paddingRight="3dp">

        "@+id/tv_min_decade"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="@color/text_10"
            android:textSize="@dimen/j18dp"
            android:textStyle="bold"
            />

        "@+id/tv_min_unit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="@color/text_10"
            android:textSize="@dimen/j18dp"
            android:textStyle="bold"
            />
    

    "wrap_content"
        android:layout_height="match_parent"
        android:layout_marginLeft="@dimen/j3dp"
        android:layout_marginRight="@dimen/j3dp"
        android:gravity="center"
        android:text=":"
        android:textColor="@color/white"
        android:textSize="@dimen/j18dp"/>

    "@+id/lay_s"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/goodsdetail_timer_bg"
        android:gravity="center"
        android:paddingLeft="3dp"
        android:paddingRight="3dp">

        "@+id/tv_sec_decade"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="@color/text_10"
            android:textSize="@dimen/j18dp"
            android:textStyle="bold"
            />

        "@+id/tv_sec_unit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="0"
            android:textColor="@color/text_10"
            android:textSize="@dimen/j18dp"
            android:textStyle="bold"
            />
    

goodsdetail_timer_bg.xml

"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android" >
    "@color/white" />
    
    
    "1dp" />
    
    "2dp" android:color="#ffffff" />

2.重写View:

@SuppressLint("HandlerLeak")
public class GoodsDetailTimerView extends LinearLayout {

    // 天数,十位
    private TextView tv_days_decade;
    // 天数,个位
    private TextView tv_days_unit;
    // 小时,十位
    private TextView tv_hour_decade;
    // 小时,个位
    private TextView tv_hour_unit;
    // 分钟,十位
    private TextView tv_min_decade;
    // 分钟,个位
    private TextView tv_min_unit;
    // 秒,十位
    private TextView tv_sec_decade;
    // 秒,个位
    private TextView tv_sec_unit;

    //布局:时 ,分,秒
    private LinearLayout layHour, layMin, layS, layDays;

    private Context context;

    private int day;
    private int days_decade;
    private int days_unit;
    private int hour_decade;
    private int hour_unit;
    private int min_decade;
    private int min_unit;
    private int sec_decade;
    private int sec_unit;
    // 计时器
    private Timer timer;

    private Handler handler = new Handler() {

        public void handleMessage(Message msg) {
            countDown();
        }
    };

    // 回调接口
    public interface OnTimeOutCallBack {
        void onCallBack();
    }

    private OnTimeOutCallBack callBack;

    public GoodsDetailTimerView(Context context, AttributeSet attrs) {
        super(context, attrs);

        this.context = context;
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.view_goodsdetailtimer, this);

        tv_days_decade = (TextView) view.findViewById(R.id.tv_days_decade);
        tv_days_unit = (TextView) view.findViewById(R.id.tv_days_unit);
        tv_hour_decade = (TextView) view.findViewById(R.id.tv_hour_decade);
        tv_hour_unit = (TextView) view.findViewById(R.id.tv_hour_unit);
        tv_min_decade = (TextView) view.findViewById(R.id.tv_min_decade);
        tv_min_unit = (TextView) view.findViewById(R.id.tv_min_unit);
        tv_sec_decade = (TextView) view.findViewById(R.id.tv_sec_decade);
        tv_sec_unit = (TextView) view.findViewById(R.id.tv_sec_unit);

        layDays = (LinearLayout) view.findViewById(R.id.lay_days);
        layHour = (LinearLayout) view.findViewById(R.id.lay_hour);
        layMin = (LinearLayout) view.findViewById(R.id.lay_min);
        layS = (LinearLayout) view.findViewById(R.id.lay_s);
    }



    public void setOnTimeOutCallBack(OnTimeOutCallBack callBack) {
        this.callBack = callBack;
    }

    /**
     * @param
     * @return void
     * @throws
     * @Description: 开始计时
     */
    public void start() {

        if (timer == null) {
            timer = new Timer();
            timer.schedule(new TimerTask() {

                @Override
                public void run() {
                    handler.sendEmptyMessage(0);
                }
            }, 0, 1000);
        }
    }

    /**
     * @param
     * @return void
     * @throws
     * @Description: 停止计时
     */
    public void stop() {
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    /**
     * @param
     * @return void
     * @throws Exception
     * @throws
     * @Description: 设置倒计时的时长
     */
    public void setTime(int day, int hour, int min, int sec) {
        try {
            if (hour >= 24 || min >= 60 || sec >= 60 || hour < 0 || min < 0 || sec < 0) {
                throw new RuntimeException("Time format is error,please check out your code");
            }
            this.day = day;
            days_decade = day / 10;
            days_unit = day - days_decade * 10;
            hour_decade = (hour) / 10;
            hour_unit = (hour) - hour_decade * 10;
            min_decade = min / 10;
            min_unit = min - min_decade * 10;
            sec_decade = sec / 10;
            sec_unit = sec - sec_decade * 10;

            tv_days_decade.setText(days_decade + "");
            tv_days_unit.setText(days_unit + "");
            tv_hour_decade.setText(hour_decade + "");
            tv_hour_unit.setText(hour_unit + "");
            tv_min_decade.setText(min_decade + "");
            tv_min_unit.setText(min_unit + "");
            tv_sec_decade.setText(sec_decade + "");
            tv_sec_unit.setText(sec_unit + "");

            if (day <= 0) {
                layDays.setVisibility(GONE);
            } else {
                layDays.setVisibility(VISIBLE);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param
     * @return boolean
     * @throws
     * @Description: 倒计时
     */
    private void countDown() {
        if (isCarry4Unit(tv_sec_unit)) {
            if (isCarry4Decade(tv_sec_decade)) {
                if (isCarry4Unit(tv_min_unit)) {
                    if (isCarry4Decade(tv_min_decade)) {
                        if (isHourUnit(tv_hour_unit)) {
                            if (isHourDecade(tv_hour_decade)) {
                                if (isDayUnit(tv_days_unit)) {
                                    if (isDayDecade(tv_days_decade)) {
                                        if (callBack != null) {
                                            callBack.onCallBack();
                                        }
                                        Log.d("TEST", "时间到了");
                                        stop();
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
}

    /**
     * @param
     * @return boolean
     * @throws
     * @Description: 天数变化十位,并判断是否需要进位
     */
    private boolean isDayDecade(TextView tv) {

        int time = Integer.valueOf(tv.getText().toString());
        time = time - 1;
        if (time < 0) {
            time = 9;
            tv.setText(time + "");
            return true;
        } else {
            tv.setText(time + "");
            return false;
        }

    }

    /**
     * @param
     * @return boolean
     * @throws
     * @Description: 天数变化个位,并判断是否需要进位
     */
    private boolean isDayUnit(TextView tv) {

        int time = Integer.valueOf(tv.getText().toString());
        time = time - 1;
        if (time < 0) {
            time = 9;
            tv.setText(time + "");
            return true;
        } else {
            tv.setText(time + "");
            return false;
        }

    }

    /**
     * @param
     * @return boolean
     * @throws
     * @Description: 小时变化十位,并判断是否需要进位
     */
    private boolean isHourDecade(TextView tv) {

        int time = Integer.valueOf(tv.getText().toString());
        time = time - 1;
        if (time < 0) {
            time = 2;
            tv.setText(time + "");
            return true;
        } else {
            tv.setText(time + "");
            return false;
        }

    }

    /**
     * @param
     * @return boolean
     * @throws
     * @Description: 小时变化个位,并判断是否需要进位
     */
    private boolean isHourUnit(TextView tv) {

        int time = Integer.valueOf(tv.getText().toString());
        time = time - 1;
        if (time < 0) {
            time = 3;
            tv.setText(time + "");
            return true;
        } else {
            tv.setText(time + "");
            return false;
        }

    }

    /**
     * @param
     * @return boolean
     * @throws
     * @Description: 分钟、秒钟变化十位,并判断是否需要进位
     */
    private boolean isCarry4Decade(TextView tv) {

        int time = Integer.valueOf(tv.getText().toString());
        time = time - 1;
        if (time < 0) {
            time = 5;
            tv.setText(time + "");
            return true;
        } else {
            tv.setText(time + "");
            return false;
        }

    }

    /**
     * @param
     * @return boolean
     * @throws
     * @Description: 分钟、秒钟变化个位,并判断是否需要进位
     */
    private boolean isCarry4Unit(TextView tv) {

        int time = Integer.valueOf(tv.getText().toString());
        time = time - 1;
        if (time < 0) {
            time = 9;
            tv.setText(time + "");
            return true;
        } else {
            tv.setText(time + "");
            return false;
        }

    }
}
"@+id/timerView"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"/>

启动计时器

GoodsDetailTimerView timerView=(LinearLayout) view.findViewById(R.id.lay_timerview);
timerView.setTime(day, hour, min, s);// 设置时间(day,hour,min,sec)
timerView.start();// 开始倒计时
timerView.stop();// 停止倒计时

你可能感兴趣的:(个人记录)