Solution to the Caton problem in the countdown of Android sale list

In the development of Android, we often encounter the countdown operation, which is usually completed by the joint operation of timer and handler. Of course, you can also use the Android system control countdowntimer. Here we package it into a control, which is also convenient for everyone to use.

Let's start with the previous rendering:

Let's talk about the reasons for the jamming. When sliding, the getview of the adapter is frequently created and destroyed, resulting in jamming and data dislocation. Then the countdown of each item needs to be maintained separately. Here, I use the method of combining the handler with timer and TimerTask. We know that TimerTask runs in its own sub thread, and then through timer's schedule () Method to realize the countdown function, and finally refresh the view through the handler. Its core code is as follows:

public class CountDownView extends LinearLayout {

 @BindView(R.id.tv_day)
 TextView tvDay;
 @BindView(R.id.tv_hour)
 TextView tvHour;
 @BindView(R.id.tv_minute)
 TextView tvMinute;
 @BindView(R.id.tv_second)
 TextView tvSecond;

 @BindView(R.id.day)
 TextView day;
 @BindView(R.id.hour)
 TextView hour;
 @BindView(R.id.minute)
 TextView minute;

 private Context context;

 private int viewBg;//倒计时的背景
 private int cellBg;//每个倒计时的背景
 private int cellTextColor;//文字颜色
 private int textColor;//外部:等颜色
 private int textSize = 14;//外部文字大小
 private int cellTextSize = 12;//cell文字大小

 private TimerTask timerTask = null;
 private Timer timer = new Timer();
 private Handler handler = new Handler() {

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

 public CountDownView(Context context,AttributeSet attrs) {
  this(context,attrs,0);
  this.context = context;
 }

 public CountDownView(Context context,AttributeSet attrs,int defStyleAttr) {
  super(context,defStyleAttr);
  this.context = context;
  initAttrs(attrs,defStyleAttr);
  initView(context);
 }

 private void initAttrs(AttributeSet attrs,int defStyle) {
  TypedArray typedArray = getContext().obtainStyledAttributes(attrs,R.styleable.CountDownView,defStyle,0);
  viewBg = typedArray.getColor(R.styleable.CountDownView_viewBg,Color.parseColor("#FFFFFF"));
  cellBg = typedArray.getColor(R.styleable.CountDownView_cellBg,Color.parseColor("#F4F4F4"));
  cellTextColor = typedArray.getColor(R.styleable.CountDownView_cellTextColor,Color.parseColor("#646464"));
  textColor = typedArray.getColor(R.styleable.CountDownView_TextColor,Color.parseColor("#B3B3B3"));
  textSize = (int) typedArray.getDimension(R.styleable.CountDownView_TextSize,UIUtils.dp2px(getContext(),14));
  cellTextSize = (int) typedArray.getDimension(R.styleable.CountDownView_cellTextSize,12));
  typedArray.recycle();

 }

 private void initView(Context context) {
  LayoutInflater inflater = (LayoutInflater) context
    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  View view = inflater.inflate(R.layout.layout_countdown_layout,this);
  ButterKnife.bind(view);

  initproperty();
 }

 private void initproperty() {
  tvDay.setBackgroundColor(cellBg);
  tvHour.setBackgroundColor(cellBg);
  tvMinute.setBackgroundColor(cellBg);
  tvSecond.setBackgroundColor(cellBg);

  tvDay.setTextColor(cellTextColor);
  tvHour.setTextColor(cellTextColor);
  tvMinute.setTextColor(cellTextColor);
  tvSecond.setTextColor(cellTextColor);

  day.setTextColor(textColor);
  hour.setTextColor(textColor);
  minute.setTextColor(textColor);
 }

 public void setLeftTime(long leftTime) {
  if (leftTime <= 0) return;
  long time = leftTime / 1000;
  long day = time / (3600 * 24);
  long hours = (time - day * 3600 * 24) / 3600;
  long minutes = (time - day * 3600 * 24 - hours * 3600) / 60;
  long seconds = time - day * 3600 * 24 - hours * 3600 - minutes * 60;

  setTextTime(time);
 }

 public void start() {
  if (timerTask == null) {
   timerTask = new TimerTask() {
    @Override
    public void run() {
     handler.sendEmptyMessage(0);
    }

   };
   timer.schedule(timerTask,1000,1000);
//   timer.schedule(new TimerTask() {
//    @Override
//    public void run() {
//     handler.sendEmptyMessage(0);
//    }
//   },1000);
  }
 }

 public void stop() {
  if (timer != null) {
   timer.cancel();
   timer = null;
  }
 }

 //保证天,时,分,秒都两位显示,不足的补0
 private void setTextTime(long time) {
  String[] s = TimeUtils.formatTimer(time);
  tvDay.setText(s[0]);
  tvHour.setText(s[1]);
  tvMinute.setText(s[2]);
  tvSecond.setText(s[3]);
 }

 private void countDown() {
  if (isCarry4Unit(tvSecond)) {
   if (isCarry4Unit(tvMinute)) {
    if (isCarry4Unit(tvHour)) {
     if (isCarry4Unit(tvDay)) {
      stop();
     }
    }
   }
  }
 }

 private boolean isCarry4Unit(TextView tv) {
  int time = Integer.valueOf(tv.getText().toString());
  time = time - 1;
  if (time < 0) {
   time = 59;
   tv.setText(time + "");
   return true;
  } else if (time < 10) {
   tv.setText("0" + time);
   return false;
  } else {
   tv.setText(time + "");
   return false;
  }
 }
}

Another way of writing:

public class CountDownTimerView extends LinearLayout {

 private TextView hourView,minuteView,secondView;
 private LimitTimer mTimer;
 private Handler handler;
 public static final int START_LIMIT_TIME_MSG = 0x0111;
 public static final int END_LIMIT_TIME_MSG = 0x0112;
 private long endTime,leftTime;
 private LimitTimeListener listener=null;

 public CountDownTimerView(Context context) {
  super(context);
  initView(context);
 }

 public CountDownTimerView(Context context,AttributeSet attrs) {
  super(context,attrs);
  initView(context);
 }

 private void initView(Context context) {
  setOrientation(HORIZONTAL);
  setGravity(Gravity.CENTER_VERTICAL);
  inflate(context,R.layout.layout_countdown_layout,this);
  hourView = (TextView) findViewById(R.id.tv_hour);
  minuteView = (TextView) findViewById(R.id.tv_minute);
  secondView = (TextView) findViewById(R.id.tv_second);
 }

 public long getLeftTime() {
  return leftTime;
 }

 //设置剩余时间
 public void initLeftTime(long endTime) {
  endTime=endTime*1000;
  if (null != mTimer) {
   mTimer.cancel();
   mTimer = null;
  }
  this.endTime = endTime;
  mTimer = new LimitTimer(endTime,1000);
  mTimer.start();
  if (handler != null) {
   handler.sendEmptyMessage(START_LIMIT_TIME_MSG);
  }
 }

 /**
  * 如果该控件使用在碎片中,返回时,则最好还是要stop
  */
 public void stopTimeCount() {
  if (null != mTimer) {
   mTimer.cancel();
   mTimer = null;
  }
 }

 public Handler getHandler() {
  return handler;
 }

 public void setHandler(Handler handler) {
  this.handler = handler;
 }

 private class LimitTimer extends CountDownTimer {

  public LimitTimer(long millisInFuture,long countDownInterval) {
   super(0 != leftTime ? leftTime : endTime,countDownInterval);
  }

  @Override
  public void onTick(long millisUntilFinished) {
   leftTime = millisUntilFinished;
   long totalSecond = millisUntilFinished / 1000;
   int second = (int) (totalSecond % 60);
   int minute = (int) ((totalSecond / 60) % 60);
   int hour = (int) ((totalSecond / 3600) % 24);
   int day = (int) (totalSecond / (3600 * 24));

   formatView(hourView,hour);
   formatView(minuteView,minute);
   formatView(secondView,second);
  }

  @Override
  public void onFinish() {
   String zero = "00";
   hourView.setText(zero);
   minuteView.setText(zero);
   secondView.setText(zero);
   if (null != handler) {
    handler.sendEmptyMessage(END_LIMIT_TIME_MSG);
   }
   if (listener!=null){
    listener.onTimeOver(true);
   }
  }

  private void formatView(TextView view,int time) {
   DecimalFormat df = new DecimalFormat("#00");
   view.setText(df.format(time));
  }
 }

 //倒计时结束监听
 public void setOnLimitTimeListener(LimitTimeListener listener) {
  this.listener = listener;
 }
 public interface LimitTimeListener {
  void onTimeOver(boolean flag);
 }

 @Override
 protected void onDetachedFromWindow() {
  super.onDetachedFromWindow();
  if (handler != null) {
   handler.removeMessages(START_LIMIT_TIME_MSG);
  }
 }
}

Layout files involved

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:orientation="horizontal">

 <TextView
  android:id="@+id/tv_hour"
  style="@style/style_countdown" />

 <TextView
  style="@style/style_wrap_content"
  android:layout_marginLeft="3dp"
  android:layout_marginRight="3dp"
  android:layout_gravity="center_vertical"
  android:text="时"
  android:textColor="@color/color_646464" />

 <TextView
  android:id="@+id/tv_minute"
  style="@style/style_countdown" />

 <TextView
  style="@style/style_wrap_content"
  android:layout_marginLeft="3dp"
  android:layout_marginRight="3dp"
  android:layout_gravity="center_vertical"
  android:text="分"
  android:textColor="@color/color_646464" />

 <TextView
  android:id="@+id/tv_second"
  style="@style/style_countdown" />

 <TextView
  style="@style/style_wrap_content"
  android:layout_marginLeft="3dp"
  android:layout_marginRight="3dp"
  android:layout_gravity="center_vertical"
  android:text="秒"
  android:textColor="@color/color_646464" />
</LinearLayout>

Attach the source code address: click the open link

The above is the whole content of this article. I hope it will help you in your study, and I hope you will support us a lot.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>