定时倒计时android_android 倒计时定时器 - CSDN
  • android开发 倒计时计时的实现

    千次阅读 2016-09-06 09:51:54
    转自:http://blog.csdn.net/t12x3456/article/details/7816500在购物网站的促销活动中一般都有倒计时限制购物时间或者折扣的时间,这些都是如何实现的呢?在最近的一个安卓客户端项目中恰好遇到了类似的问题,一开始...

    转自:http://blog.csdn.net/t12x3456/article/details/7816500

    在购物网站的促销活动中一般都有倒计时限制购物时间或者折扣的时间,这些都是如何实现的呢?

    在最近的一个安卓客户端项目中恰好遇到了类似的问题,一开始使用的是Timer与 TimerTask, 虽然此方法通用,但后来考虑在安卓中是否有更佳的方案,于是乎共找到以下五种实现方案,最终我使用了方案五完成了此功能.

    效果如图:

    Android实现计时与倒计时(限时抢购)的几种方法

    方法一

    Timer与TimerTask(Java实现)
    public class timerTask extends Activity{

    private int recLen = 11;  
    private TextView txtView;  
    Timer timer = new Timer();  
    
    public void onCreate(Bundle savedInstanceState){  
        super.onCreate(savedInstanceState);  
    
        setContentView(R.layout.timertask);  
        txtView = (TextView)findViewById(R.id.txttime);  
    
        timer.schedule(task, 1000, 1000);       // timeTask  
    }     
    
    TimerTask task = new TimerTask() {  
        @Override  
        public void run() {  
    
            runOnUiThread(new Runnable() {      // UI thread  
                @Override  
                public void run() {  
                    recLen--;  
                    txtView.setText(""+recLen);  
                    if(recLen < 0){  
                        timer.cancel();  
                        txtView.setVisibility(View.GONE);  
                    }  
                }  
            });  
        }  
    };  
    

    }

    方法二
    TimerTask与Handler(不用Timer的改进型)
    public class timerTask extends Activity{
    private int recLen = 11;
    private TextView txtView;
    Timer timer = new Timer();

    public void onCreate(Bundle savedInstanceState){  
        super.onCreate(savedInstanceState);  
    
        setContentView(R.layout.timertask);  
        txtView = (TextView)findViewById(R.id.txttime);  
    
        timer.schedule(task, 1000, 1000);       // timeTask  
    }     
    
    final Handler handler = new Handler(){  
        @Override  
        public void handleMessage(Message msg){  
            switch (msg.what) {  
            case 1:  
                txtView.setText(""+recLen);  
                if(recLen < 0){  
                    timer.cancel();  
                    txtView.setVisibility(View.GONE);  
                }  
            }  
        }  
    };  
    
    TimerTask task = new TimerTask() {  
        @Override  
        public void run() {  
            recLen--;  
            Message message = new Message();  
            message.what = 1;  
            handler.sendMessage(message);  
        }  
    };  
    

    }
    方法三
    Handler与Message(不用TimerTask)

    public class timerTask extends Activity{
    private int recLen = 11;
    private TextView txtView;

    public void onCreate(Bundle savedInstanceState) {    
        super.onCreate(savedInstanceState);    
    
        setContentView(R.layout.timertask);   
        txtView = (TextView)findViewById(R.id.txttime);  
    
        Message message = handler.obtainMessage(1);     // Message  
        handler.sendMessageDelayed(message, 1000);  
    }    
    
    final Handler handler = new Handler(){  
    
        public void handleMessage(Message msg){         // handle message  
            switch (msg.what) {  
            case 1:  
                recLen--;  
                txtView.setText("" + recLen);  
    
                if(recLen > 0){  
                    Message message = handler.obtainMessage(1);  
                    handler.sendMessageDelayed(message, 1000);      // send message  
                }else{  
                    txtView.setVisibility(View.GONE);  
                }  
            }  
    
            super.handleMessage(msg);  
        }  
    };  
    

    }
    方法四

    Handler与Thread(不占用UI线程)
    public class timerTask extends Activity{
    private int recLen = 0;
    private TextView txtView;

    public void onCreate(Bundle savedInstanceState){  
        super.onCreate(savedInstanceState);  
    
        setContentView(R.layout.timertask);  
        txtView = (TextView)findViewById(R.id.txttime);  
    
        new Thread(new MyThread()).start();         // start thread  
    }     
    
    final Handler handler = new Handler(){          // handle  
        public void handleMessage(Message msg){  
            switch (msg.what) {  
            case 1:  
                recLen++;  
                txtView.setText("" + recLen);  
            }  
            super.handleMessage(msg);  
        }  
    };  
    
    public class MyThread implements Runnable{      // thread  
        @Override  
        public void run(){  
            while(true){  
                try{  
                    Thread.sleep(1000);     // sleep 1000ms  
                    Message message = new Message();  
                    message.what = 1;  
                    handler.sendMessage(message);  
                }catch (Exception e) {  
                }  
    

    方法五
    Handler与Runnable(最简单型)

    public class timerTask extends Activity{
    private int recLen = 0;
    private TextView txtView;

    public void onCreate(Bundle savedInstanceState){  
        super.onCreate(savedInstanceState);  
    
        setContentView(R.layout.timertask);  
        txtView = (TextView)findViewById(R.id.txttime);  
    
        handler.postDelayed(runnable, 1000);  
    }     
    
    Handler handler = new Handler();  
    Runnable runnable = new Runnable() {  
        @Override  
        public void run() {  
            recLen++;  
            txtView.setText("" + recLen);  
            handler.postDelayed(this, 1000);  
        }  
    };  
    

    }
    计时与倒计时
    方法1,方法2和方法3,都是倒计时
    方法4,方法5,都是计时
    计时和倒计时,都可使用上述方法实现(代码稍加改动)

    UI线程比较
    方法1,方法2和方法3,都是在UI线程实现的计时;
    方法4和方法5,是另开Runnable线程实现计时

    实现方式比较
    方法1,采用的是Java实现,即Timer和TimerTask方式;
    其它四种方法,都采用了Handler消息处理

    推荐使用
    如果对UI线程交互要求不很高,可以选择方法2和方法3
    如果考虑到UI线程阻塞,严重影响到用户体验,推荐使用方法4,另起线程单独用于计时和其它的逻辑处理
    方法5,综合了前几种方法的优点,是最简的

    转自:http://blog.csdn.net/t12x3456/article/details/7816500

    ———————–2016年9月6日09:49:17————————————
    后来采用:

    package com.zyl.vincent.utils;
    
    import android.content.Context;
    import android.os.CountDownTimer;
    import android.widget.TextView;
    
    import com.zyl.vincent.R;
    
    /**
     * 获取验证码的倒计时
     * Created by Vincent on 2016/9/6.
     */
    
    public class TimeCount extends CountDownTimer {
    
        private TextView tv;
        private Context c;
    
        /**
         * 初始化,构造函数
         * @param context 上下文对象
         * @param millisInFuture 总的时间
         * @param countDownInterval 一般设置为1000,一秒钟减1
         * @param textView 需要设置倒计时的对象
         */
        public TimeCount(Context context,long millisInFuture, long countDownInterval, TextView textView) {
            super(millisInFuture, countDownInterval);
            this.tv = textView;
            this.c=context;
        }
    
        @Override
        public void onTick(long l) {//计时开始
            tv.setClickable(false);//设置不可点击
            tv.setTextColor(c.getResources().getColor(R.color.common_color_red));
            tv.setText(l / 1000 + "s");
        }
    
        @Override
        public void onFinish() {
            tv.setText("再次获取");
            tv.setClickable(true);
        }
    
    }

    初始化之后调用start方法启动即可

    展开全文
  • Android 定时器+倒计时 仿淘宝秒杀

    千次阅读 2017-01-04 17:04:17
    目录结构 imageViewHolder  public class imageViewHolder extends RecyclerView.ViewHolder { public ImageView imageView; public imageViewHolder(View itemView) { super(itemView);

    目录结构



    效果图:


    imageViewHolder 

    public class imageViewHolder extends RecyclerView.ViewHolder {
    
        public ImageView imageView;
    
        public imageViewHolder(View itemView) {
            super(itemView);
            imageView = (ImageView) itemView;
        }
    }
    


    MyViewHolder 

    public class MyViewHolder extends RecyclerView.ViewHolder {
    
        public TextView textView;
    
        public MyViewHolder(View itemView) {
            super(itemView);
            textView = (TextView) itemView;
        }
    }
    


    recycleAdapter 

    package com.nodeprogress.snapupview.SnapUp;
    
    import android.content.Context;
    import android.graphics.Color;
    import android.support.v7.widget.RecyclerView;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class recycleAdapter extends RecyclerView.Adapter {
    
        Context context;
    
        public recycleAdapter(Context context) {
            this.context = context;
        }
    
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
            if (viewType == 0){
                return new imageViewHolder(new ImageView(context));
            }else {
                return new MyViewHolder(new TextView(context));
            }
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            if (getItemViewType(position) == 0) {
                imageViewHolder viewHolder = (imageViewHolder) holder;
                viewHolder.imageView.setPadding(150,20,20,20);
                viewHolder.imageView.setBackgroundColor(Color.BLUE);
            } else {
                MyViewHolder viewHolder = (MyViewHolder) holder;
                viewHolder.textView.setText(" 淘宝 " + position);
            }
        }
    
        @Override
        public int getItemCount() {
            return 21;
        }
    
        @Override
        public int getItemViewType(int position) {
            return (position == 20) ? 0 : 1;
        }
    
    }


    MainActivity 

    package com.nodeprogress.snapupview;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    
    import com.nodeprogress.snapupview.SnapUp.recycleAdapter;
    import com.nodeprogress.snapupview.View.HorizontalRecycleViewLoadMore;
    
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            HorizontalRecycleViewLoadMore recyclerView = (HorizontalRecycleViewLoadMore) findViewById(R.id.recycle);
            recyclerView.setAdapter(new recycleAdapter(MainActivity.this));
    
            SnapUpCountDownTimerView rushBuyCountDownTimerView = (SnapUpCountDownTimerView) findViewById(R.id.RushBuyCountDownTimerView);
            rushBuyCountDownTimerView.setTime(1,55,3);
            rushBuyCountDownTimerView.start();
        }
    }
    


    SnapUpCountDownTimerView 

    package com.nodeprogress.snapupview;
    
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.os.Handler;
    import android.os.Message;
    import android.util.AttributeSet;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.widget.LinearLayout;
    import android.widget.TextView;
    import android.widget.Toast;
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    @SuppressLint("HandlerLeak")
    public class SnapUpCountDownTimerView extends LinearLayout {
    
        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 Context context;
    
        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 SnapUpCountDownTimerView(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_countdowntimer, this);
    
            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);
    
            TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.SnapUpCountDownTimerView);
            int size = array.getInteger(R.styleable.SnapUpCountDownTimerView_viewSize, 12);
    
    
            tv_hour_decade.setTextSize(size);
            tv_hour_unit.setTextSize(size);
            tv_min_decade.setTextSize(size);
            tv_min_unit.setTextSize(size);
            tv_sec_decade.setTextSize(size);
            tv_sec_unit.setTextSize(size);
            ((TextView)view.findViewById(R.id.colon_minute)).setTextSize(size);
            ((TextView)view.findViewById(R.id.colon_hour)).setTextSize(size);
        }
    
    
        public void start() {
            if (timer == null) {
                timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        handler.sendEmptyMessage(0);
                    }
                }, 0, 1000);
            }
        }
    
    
        public void stop() {
            if (timer != null) {
                timer.cancel();
                timer = null;
            }
        }
    
    
        public void setTime(int hour, int min, int sec) {
    
            if (hour >= 60 || min >= 60 || sec >= 60 || hour < 0 || min < 0
                    || sec < 0) {
                throw new RuntimeException("时间格式错误,请检查你的代码");
            }
    
            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_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 + "");
        }
    
    
        private void countDown() {
            if (isCarry4Unit(tv_sec_unit)) {
                if (isCarry4Decade(tv_sec_decade)) {
                    if (isCarry4Unit(tv_min_unit)) {
                        if (isCarry4Decade(tv_min_decade)) {
                            if (isCarry4Unit(tv_hour_unit)) {
                                if (isCarry4Decade(tv_hour_decade)) {
                                    Toast.makeText(context, "计数完成",
                                            Toast.LENGTH_SHORT).show();
                                    stop();
                                    setTime(0, 0, 0);//重置为0
                                }
                            }
                        }
                    }
                }
            }
        }
    
    
        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;
            }
        }
    
    
        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;
            }
        }
    }
    

    activity_main.xml 

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.nodeprogress.snapupview.MainActivity">
    
    
        <include layout="@layout/home_snap_up"></include>
    </RelativeLayout>


    home_snap_up.xml 

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  xmlns:app="http://schemas.android.com/apk/res-auto"
                  android:orientation="vertical"
                  android:background="@android:color/white"
                  android:padding="15dp"
        >
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            >
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:text="秒杀"
                android:textColor="@android:color/holo_red_light"
                android:textSize="20sp"
                />
    
            <com.nodeprogress.snapupview.SnapUpCountDownTimerView
                android:id="@+id/RushBuyCountDownTimerView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="20dp"
                app:viewSize="12"
                >
            </com.nodeprogress.snapupview.SnapUpCountDownTimerView>
    
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center_vertical|right"
                android:text="更多 >"
                android:textSize="15sp"
                />
        </LinearLayout>
    
        <com.nodeprogress.snapupview.View.HorizontalRecycleViewLoadMore
            android:id="@+id/recycle"
            android:layout_marginTop="10dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
        </com.nodeprogress.snapupview.View.HorizontalRecycleViewLoadMore>
    
    
    
    </LinearLayout>


    view_countdowntimer.xml

    <?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:background="@android:color/white"
                  android:orientation="horizontal"
        >
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_snap_up"
            android:padding="5dp"
            >
    
            <TextView
                android:id="@+id/tv_hour_decade"
                style="@style/RushBuyCountDownTimerViewStyle"/>
    
            <TextView
                android:id="@+id/tv_hour_unit"
                style="@style/RushBuyCountDownTimerViewStyle"
                android:layout_marginLeft="1dp"/>
        </LinearLayout>
    
    
        <TextView
            android:id="@+id/colon_hour"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            style="@style/SnapUpViewColon"
            />
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_snap_up"
            android:padding="5dp"
            >
    
            <TextView
                android:id="@+id/tv_min_decade"
                style="@style/RushBuyCountDownTimerViewStyle"/>
    
            <TextView
                android:id="@+id/tv_min_unit"
                style="@style/RushBuyCountDownTimerViewStyle"
                android:layout_marginLeft="1dp"/>
        </LinearLayout>
    
    
        <TextView
            android:id="@+id/colon_minute"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            style="@style/SnapUpViewColon"
            />
    
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/bg_snap_up_red"
            android:padding="5dp"
            >
    
            <TextView
                android:id="@+id/tv_sec_decade"
                style="@style/RushBuyCountDownTimerViewStyleRed"/>
    
            <TextView
                android:id="@+id/tv_sec_unit"
                style="@style/RushBuyCountDownTimerViewStyleRed"
                android:layout_marginLeft="1dp"/>
        </LinearLayout>
    
    </LinearLayout>


    代码全部贴出来了

    源码地址

    http://download.csdn.net/detail/u010566681/9728861


    Android 定时器+倒计时 CountDownTimer实现



    展开全文
  • 最近做了一个Android项目,需要使用到链接,数据提交,等任务,需要使用到超时重链重发,一直问度娘都没找到好的方法,实现计时的功能。所以封装了一个简单的Util。TimerUtil.javaimport android.annotation....

    最近做了一个Android项目,需要使用到链接,数据提交,等任务,需要使用到超时重链重发,一直问度娘都没找到好的方法,实现计时的功能。所以封装了一个简单的Util。



    DateUtil.java

    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    public class DateUtil {
    
        /***
         * 根据时间字符串获取毫秒数
         */
        private static long getTimeMillis(String strTime) {
            long returnMillis = 0;
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            Date d = null;
            try {
                d = sdf.parse(strTime);
                returnMillis = d.getTime();
            } catch (ParseException e) {
            }
            return returnMillis;
        }
    
        /**
         * 根据毫秒数的差值来计算时间差 秒
         * */
        public static long getTimeSExpend(String startTime, String endTime){
            long longStart = getTimeMillis(startTime); //获取开始时间毫秒数
            long longEnd = getTimeMillis(endTime);  //获取结束时间毫秒数
            long longExpend = longEnd - longStart;  //获取时间差
    
            long longs = longExpend / (1000); //根据时间差来计算小时数
            return longs;
        }
    
        /**
         * 根据毫秒数的差值来计算时间差
         * 传入开始时间和结束时间字符串来计算消耗时长
         * */
        private String getTimeExpend(String startTime, String endTime){
            //传入字串类型 2016/06/28 08:30
            long longStart = getTimeMillis(startTime); //获取开始时间毫秒数
            long longEnd = getTimeMillis(endTime);  //获取结束时间毫秒数
            long longExpend = longEnd - longStart;  //获取时间差
    
            long longHours = longExpend / (60 * 60 * 1000); //根据时间差来计算小时数
            long longMinutes = (longExpend - longHours * (60 * 60 * 1000)) / (60 * 1000);   //根据时间差来计算分钟数
    
            return longHours + ":" + longMinutes;
        }
    
        /**
         * 传入结束时间和消耗时长来计算开始时间
         * */
        private String getTimeString(String endTime, String expendTime){
            //传入字串类型 end:2016/06/28 08:30 expend: 03:25
            long longEnd = getTimeMillis(endTime);
            String[] expendTimes = expendTime.split(":");   //截取出小时数和分钟数
            long longExpend = Long.parseLong(expendTimes[0]) * 60 * 60 * 1000 + Long.parseLong(expendTimes[1]) * 60 * 1000;
            SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy/MM/dd HH:mm");
            return sdfTime.format(new Date(longEnd - longExpend));
        }
    }


    TimerUtil.java

    import android.annotation.SuppressLint;
    import android.os.Handler;
    import android.util.Log;
    
    import com.rfid.ross.locationmachine.Interface.TimeResult;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * Created by Administrator on 2018-05-11.
     */
    public class TimerUtil {
    
        private int ultimatelyTime = 10;
    
        private int linkTime = 1000;
    
        private String starTime = "";
    
        private TimeResult timeResult;
    
        private int code = 0;
    
        /**
         * 状态,0:未运行,1:正在运行
         * */
        private int state = 0;
    
        @SuppressLint("SimpleDateFormat")
        private SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    
        /**
         * ultimatelyTime 最终时间  m/s
         * linkTime 每次运行调用间隔时间  m/s
         * */
        public TimerUtil(int ultimatelyTime, int linkTime,TimeResult timeResult,int code){
            this.ultimatelyTime = ultimatelyTime / 1000;
            this.linkTime = linkTime;
            this.timeResult = timeResult;
            this.code = code;
        }
    
        public void start(){
            this.state = 1;
            this.TimingHandler.removeCallbacks(this.TimingRunnable);
            this.TimingHandler.postDelayed(this.TimingRunnable, this.linkTime);
            this.starTime = this.sdf.format(new Date(System.currentTimeMillis()));
        }
    
        public void restart(){
            this.start();
        }
    
        public void destroy(){
            this.state = 0;
            TimingHandler.removeCallbacks(this.TimingRunnable);
        }
    
        //呼叫延时 1分钟
        private Handler TimingHandler = new Handler();
        private Runnable TimingRunnable = new Runnable() {
            @Override
            public void run() {
                if(DateUtil.getTimeSExpend(starTime,sdf.format(new Date(System.currentTimeMillis()))) > ultimatelyTime){
                    //超时结束
                    state = 0;
                    TimingHandler.removeCallbacks(TimingRunnable);
                    timeResult.OvertimeResult(code,"");
                }else{
                    TimingHandler.postDelayed(this, linkTime);
                    Log.i("TimeLog---",(ultimatelyTime - DateUtil.getTimeSExpend(starTime,sdf.format(new Date(System.currentTimeMillis()))))+"m/s");
                    timeResult.CourseResult(code,"");
                }
            }
        };
    }
    

    TimeResult.java

    /**
     * Created by Administrator on 2018-05-11.
     */
    public interface TimeResult {
    
        /**
         * 过程返回
         * code 状态码
         * resule 消息
         * */
        void CourseResult(int code,String resule);
    
        /**
         * 结束返回
         * code 状态码
         * resule 消息
         * */
        void OvertimeResult(int code,String resule);
    }
    

    MainActivity.java

    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.Switch;
    
    public class Main2Activity extends AppCompatActivity implements TimeResult{
    
        private int NO_OPRATION = 1;
    
        private int LINK_OVERTIME = 2;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
    
            TimerUtil timerUtil = new TimerUtil(10 * 1000,1000,this,this.NO_OPRATION);
            timerUtil.start();
            TimerUtil timerUtil = new TimerUtil(10 * 1000,1000,this,this.LINK_OVERTIME);
            timerUtil.start();
        }
    
        @Override
        public void CourseResult(int code, String resule) {
            Log.d("CourseResult:","D");
        }
    
        @Override
        public void OvertimeResult(int code,String resule) {   
         Switch(code){
                case NO_OPRATION:
                    //10s 无操作
                    break;
                case LINK_OVERTIME:
                    //10s 内链接超时,重新链接
                    break;
            }
    展开全文
  • 项目中需要用到倒计时View,因为需求需要,所以不能只依靠本地计时。还需要网络请求数据之后,矫正时间。 控件继承自AppCompatTextView, 增加了设置初始时间,开始计时,更新计时,停止计时,设置字体若干方法。 ...

    需求

    项目中需要用到倒计时View,因为需求需要,所以不能只依靠本地计时。还需要网络请求数据之后,矫正时间。

    所以本文的目标如下:

    • 自定义字体
    • 依赖网络的倒计时
    • 时间矫正
    • 倒计时的自动更新

    最终效果如下:
    倒计时

    分析

    通过自定义控件去实现,然后通过HashMap存储对应奖期以及倒计时信息,然后通过定时的网络请求,去矫正计时。

    因此本文设计控件继承自AppCompatTextView, 增加了设置初始时间,开始计时,更新计时,停止计时,取消计时,矫正计时,设置字体等若干方法。

    实现

    加载自定义字体

    // 加载自定义字体
    Typeface TEXT_TYPE;
    try {
        TEXT_TYPE = Typeface.createFromAsset(context.getAssets(), "fonts/Quartz_Regular.ttf");
    } catch (Exception e) {
        LogUtils.e("加载第三方字体失败。");
        TEXT_TYPE = null;
    }
    
    if (TEXT_TYPE != null) {
        setTypeface(TEXT_TYPE);
    }
    

    开始计时

    开始计时,首先通过接口回调,对外暴露方法,方便进行开始前的准备工作。需要传入期次和结束时间两个参数。

    更新时间通过handler去实现。

        public void start(final int term_no, final long end_time) {
            timeListener.timeStart();
    
            contine_tag = true;
            this.end_time = end_time;
            this.term_no = term_no;
            if (mTimerMap.get(term_no) == null) {
                Timer timer = new Timer();
                Term_view_bean term_view_bean = new Term_view_bean(timer, term_no, end_time);
                mTimerMap.put(term_no, term_view_bean);
                mTimerMap.get(term_no).getTimer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        if (contine_tag) {
                            if (is_over) {
                                this.cancel();
                                return;
                            }
                            mHandler.sendEmptyMessage(ticket_mode);
                        }
                    }
                }, 0, 1000);
            }
        }
    

    结束

    结束计时,共分为2种,取消指定期次,和取消全部期次。

    取消全部期次计时: 当不需要页面倒计时的时候调用,因为倒计时是采用Timer进行维护的,所以需要手动释放,以避免内存泄露相关事宜。

    public void stopAll() {
            try {
                Iterator it = mTimerMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry entry = (Map.Entry) it.next();
                    int key = (int) entry.getKey();
                    Term_view_bean bean = (Term_view_bean) entry.getValue();
                    bean.getTimer().cancel();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            contine_tag = false;
            is_over = true;
        }
       
    

    取消指定期次计时: 某一个期次奖期结束,根据期次号或者存储的值进行停止

       
    public void stop(int position_term_no) {
            if (mTimerMap.get(position_term_no) != null) {
                mTimerMap.get(position_term_no).getTimer().cancel();
        }
    }
    
    public void stopSaveValue(int value) {
        Iterator it = mTimerMap.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            int key = (int) entry.getKey();
            if (key != value) {
                Term_view_bean bean = (Term_view_bean) entry.getValue();
                bean.getTimer().cancel();
            }
        }
    }
    

    时间显示格式化

    /**
     * 时间显示格式化
     *
     * @param second
     * @return
     */
    private String second2TimeSecond(long second) {
    
        long days = second / (3600 * 24);
        long hours = (second / 3600) % 24;
        long minutes = (second % 3600) / 60;
        long seconds = second % 60;
    
        String showTime = "";
        if (days > 0) {
            showTime = days + "天 ";
        }
        if (hours > 0) {
            if (hours < 10) {
                showTime += "0" + hours + "时 ";
            } else {
                showTime += hours + "时 ";
            }
        }
        if (minutes < 10) {
            showTime += "0" + minutes + ":";
        } else {
            showTime += "" + minutes + ":";
        }
        if (seconds < 10) {
            showTime += "0" + seconds;
        } else {
            showTime += "" + seconds;
        }
        return showTime;
    }
    

    修正倒计时

        /**
         * 修正当前倒计时信息
         */
        public void updateTimer(final int term_no, final long end_time) {
            this.end_time = end_time;
            this.term_no = term_no;
            if (mTimerMap.get(term_no) == null) {
                start(term_no, end_time);
            } else {
                mTimerMap.get(term_no).setEnd_time(end_time);
            }
        }
    

    使用

    使用的时候,首先初始化,传入handler,然后定时进行网络请求即可呈现效果。

    完整代码

    完整代码如下:

    public class CountdownTextView extends android.support.v7.widget.AppCompatTextView {
        public static final int what_count_down_k3 = 1;
    
        Map<Integer, Term_view_bean> mTimerMap;
        private int term_no;
        private int ticket_mode;
        private TimeListener timeListener;
        private long end_time = 0;
        private boolean contine_tag = true;
        private boolean is_over = false;
        private Handler mHandler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                    case what_count_down_k3:// 10 分钟一期
    					if (end_time - TimeManager.getInstance().getServiceTime() <= Config.K3_R006_Time_End_sale * 1000) {                 
                            timeListener.buyDown();
                        }
                        if (end_time - TimeManager.getInstance().getServiceTime() <= 0) {
                            timeListener.timedown();
                            while (end_time - TimeManager.getInstance().getServiceTime() <= 0) {
                                term_no++;
                                end_time += 10 * 60 * 1000;
                            }
                            setTimeText();
                            try {
                                stopSaveValue(term_no);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            start(term_no, end_time);
                        } else {
                            setTimeText();
                        }
                        break;
                }
            }
        };
    
        public CountdownTextView(Context context) {
            super(context);
            initTextType(context);
        }
    
        public CountdownTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            initTextType(context);
        }
    
        public CountdownTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initTextType(context);
        }
    
        private void setTimeText() {
            setText(second2TimeSecond((end_time - TimeManager.getInstance().getServiceTime()) / 1000));
        }
    
        private void initTextType(Context context) {
            // 加载自定义字体
            Typeface TEXT_TYPE;
            try {
                TEXT_TYPE = Typeface.createFromAsset(context.getAssets(), "fonts/Quartz_Regular.ttf");
            } catch (Exception e) {
                LogUtils.e("加载第三方字体失败。");
                TEXT_TYPE = null;
            }
    
            if (TEXT_TYPE != null) {
                setTypeface(TEXT_TYPE);
            }
        }
    
        public void init(int ticket_mode, TimeListener timeListener) {
            mTimerMap = new HashMap<>();
            this.timeListener = timeListener;
            this.ticket_mode = ticket_mode;
        }
    
        public void start(final int term_no, final long end_time) {
            timeListener.timeStart();
    
            contine_tag = true;
            this.end_time = end_time;
            this.term_no = term_no;
            if (mTimerMap.get(term_no) == null) {
                Timer timer = new Timer();
                Term_view_bean term_view_bean = new Term_view_bean(timer, term_no, end_time);
                mTimerMap.put(term_no, term_view_bean);
                mTimerMap.get(term_no).getTimer().schedule(new TimerTask() {
                    @Override
                    public void run() {
                        if (contine_tag) {
                            if (is_over) {
                                this.cancel();
                                return;
                            }
                            mHandler.sendEmptyMessage(ticket_mode);
                        }
                    }
                }, 0, 1000);
            }
        }
    
        public void stop(int position_term_no) {
            if (mTimerMap.get(position_term_no) != null) {
                mTimerMap.get(position_term_no).getTimer().cancel();
            }
        }
    
        public void stopAll() {
            try {
                Iterator it = mTimerMap.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry entry = (Map.Entry) it.next();
                    int key = (int) entry.getKey();
                    Term_view_bean bean = (Term_view_bean) entry.getValue();
                    bean.getTimer().cancel();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            contine_tag = false;
            is_over = true;
        }
    
        public void stopSaveValue(int value) {
            Iterator it = mTimerMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry entry = (Map.Entry) it.next();
                int key = (int) entry.getKey();
                if (key != value) {
                    Term_view_bean bean = (Term_view_bean) entry.getValue();
                    bean.getTimer().cancel();
                }
            }
        }
    
        /**
         * 格式化
         *
         * @param second
         * @return
         */
        private String second2TimeSecond(long second) {
    
            long days = second / (3600 * 24);
            long hours = (second / 3600) % 24;
            long minutes = (second % 3600) / 60;
            long seconds = second % 60;
    
            String showTime = "";
            if (days > 0) {
                showTime = days + "天 ";
            }
            if (hours > 0) {
                if (hours < 10) {
                    showTime += "0" + hours + "时 ";
                } else {
                    showTime += hours + "时 ";
                }
            }
            if (minutes < 10) {
                showTime += "0" + minutes + ":";
            } else {
                showTime += "" + minutes + ":";
            }
            if (seconds < 10) {
                showTime += "0" + seconds;
            } else {
                showTime += "" + seconds;
            }
            return showTime;
        }
    
        /**
         * 获取当前奖期
         *
         * @return
         */
        public int getTerm_no() {
            return term_no;
        }
    
        /**
         * 修正当前倒计时信息
         */
        public void updateTimer(final int term_no, final long end_time) {
            this.end_time = end_time;
            this.term_no = term_no;
            if (mTimerMap.get(term_no) == null) {
                start(term_no, end_time);
            } else {
                mTimerMap.get(term_no).setEnd_time(end_time);
            }
        }
    
        public interface TimeListener {
            void timedown();
    
            void buyDown();
    
            void timeStart();
        }
    
        private class Term_view_bean {
            private Timer timer;// 定时器
            private int integer;// 奖期
            private long end_time;// 结束时间
    
            public Term_view_bean() {
            }
    
            public Term_view_bean(Timer timer, int integer, long end_time) {
                this.timer = timer;
                this.integer = integer;
                this.end_time = end_time;
            }
    
            public Timer getTimer() {
                return timer;
            }
    
            public void setTimer(Timer timer) {
                this.timer = timer;
            }
    
            public int getInteger() {
                return integer;
            }
    
            public void setInteger(int integer) {
                this.integer = integer;
            }
    
            public long getEnd_time() {
                return end_time;
            }
    
            public void setEnd_time(long end_time) {
                this.end_time = end_time;
            }
        }
    }
    
    展开全文
  • Android RecycleView全部item倒计时的高效实现
  • Android验证码倒计时实现方式总结

    千次阅读 2016-11-01 18:15:45
    Android验证码倒计时实现方式总结  几乎所有的APP里面都有验证码倒计时按钮,自己在项目中也尝试,简单总结为以下三种: 1、使用线程和Handler的方式,定时刷新倒计时数字,这种方式容易导致内存泄露,所以一般都...
  • 经常要用到倒计时、定时器,但总是搞不清楚,所以这里整理一下,方便后面使用 。 一.倒计时(3、2、1) CountDownTimer() //一共3秒,每隔1秒执行一次 CountDownTimer timer = new CountDownTimer(3000, 1000) { ...
  • 用kotlin实现的纯粹倒计时应用
  • Android自定义TimeButton实现倒计时按钮

    千次阅读 2017-04-05 17:51:24
    Android自定义TimeButton实现倒计时按钮
  • Service中进行倒计时

    2019-12-19 14:22:34
    前言:本文是关于一个发送验证码倒计时60s,退出验证码填写界面后,60s倒计时结束之前,再次进入倒计时页面,倒计时不会重新开始。鉴于这个功能可能比较常见,需要的可以直接粘过去。 下来介绍我的实现过程:开启一...
  • Timers主要是用来在后台运行一些任务。可以把Timer设置为守护线程。当调用cancel时所有已经安排的任务都没会被取消。  Timer中的任务是依次执行的,如果一个任务花很长时间才执行完,那么它就可能影响下一个任务的...
  • Android 实现倒计时动画效果

    千次阅读 2016-11-15 23:14:33
    想要实现的效果图如下: 点击“倒计时开始”按钮,会出现从10到0的倒计时动画。...在android中,我们会用shape定义各种各样的形状,它能实现渐变色、虚线/分割线、边框、半透明、半透明阴影效果。
  • 最近项目中需要在注册等界面中实现短信验证码倒计时效果,由于UI给出效果图,自己撸了一个简单的效果。好了,我们上效果图: 这个效果实现比较简单,代码也不多,自己总结一下。... android:layout_width="90dp" andr
  • 现在很多app的首页都有一个倒计时控件,比如说3秒或者5秒自动跳转界面,或者点击控件直接跳过首先,自定义控件CircleProgressbar(参考网上资料) package com.zhoujian.mykeep.view;import android.annotation.Target...
  • Android 5种倒计时的实现

    千次阅读 2018-09-08 16:58:32
    直入主题: handler+postDelayed() 方式 Timer + TimerTask + handler 方式 ...其中 Timer 的方式实现定时任务,这儿用来做倒计时是没有问题的。但是如果用来执行周期任务,恰好又有多个任务,恰好两个任务之间...
  • android 倒计时的几种做法

    千次阅读 2015-01-19 14:03:58
    1. CountDownTimer 是android 自己封装的定时倒计时的类 主要是重写onTick和onFinsh这两个方法,onFinish()中的代码是计时器结束的时候要做的事情;onTick(Long m)中的代码是你倒计时开始时要做的事情,参数m是...
  • 所以需要实现倒计时,事件到了后通知service暂停音乐播放 解决方案: 使用了CountDownTimer,其构造函数如下: CountDownTimer(long millisInFuture, long countDownInterval) millisInFuture是倒计时的总时间,单位...
  • Android自定义View实战】之获取验证码倒计时按钮

    千次阅读 热门讨论 2016-10-27 17:47:34
    Android开发中,我们不可避免的会做到注册功能,而现在... 1.我们涉及到的变量 倒计时时长,可设置 ... * 倒计时时长,默认倒计时时间60秒; */ private long length = 60 * 1000; 在点击按钮之前按钮所显示的文
  • Android倒计时控制

    2019-03-20 16:55:41
    摘要:目前android 中实现倒计时功能的几种方式:Timer,handler+xxx,AlarmManager 。前俩种的实现方式在系统休眠状态下也会被休眠,由此产生不准确的问题发生,这里主要介绍第三种实现方式。 大致原理:在手机中...
  • 2分钟倒计时,可实现页面切换、APP处于后台 或者 APP 关闭 倒计时继续(代码中private static final int TIME_DIFF = 120*1000;//时间间隔 2分钟 被我标成10分钟了 自己改下注释 我就不改了 )
1 2 3 4 5 ... 20
收藏数 3,342
精华内容 1,336
关键字:

定时倒计时android