Update TextView every second in Android [duplicate

2019-04-16 18:55发布

问题:

This question already has an answer here:

  • Update TextView Every Second 9 answers

i want to update my textview every second. on button click i am calling one method,

loopMethod(milli); //suppose milli= 50000 i.e 50 sec.

so my loopMethod(int m) is as follows:

public void loopMethod(int m){
    timer=(TextView) findViewById(R.id.timerText);
    if(m>=1000){
        try {
            timer.setText(""+m);//timer is a textview
            System.out.println(m);
            m=m-1000;
            Thread.sleep(1000);
        } catch(InterruptedException ex) {
            ex.printStackTrace();
        }
        loopMethod(m);
    }
}

so what i am expecting is, my timer textview should print the value of m every second. but i am getting only console output i.e system.out.println(m)... printing value on console working fine... but its not updating my textview at all

回答1:

You can use following code:

Runnable updater;
void updateTime(final String timeString) {
    timer=(TextView) findViewById(R.id.timerText);
    final Handler timerHandler = new Handler();

    updater = new Runnable() {
        @Override
        public void run() {
            timer.setText(timeString);
            timerHandler.postDelayed(updater,1000);
        }
    };
    timerHandler.post(updater);
}

In this line:

 timerHandler.post(updater);

time will set for the first time. i.e, updater will execute. After first execution it will be posted after every 1 second time interval. It will update your TextView every one second.

You need to remove it when the activity destroys, else it will leak memory.

@Override
protected void onDestroy() {
   super.onDestroy();
   timerHandler.removeCallbacks(updater);
}

Hope it will help you.



回答2:

You should use RxJava library to do so:

Subscription s =
                Observable.interval(1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(v -> {
                    // update your ui here
                }, e -> {

                });

        // call when you no longer need an update:
        if (s != null && !s.isUnsubscribed()){
            s.unsubscribe();
            s = null;
        }

That's it. Do NOT use .postDelay(), Timer because it is error prone.



回答3:

You might want to consider using the Chronometer class: https://developer.android.com/reference/android/widget/Chronometer.html

just use timer.start(); on the button click



回答4:

Using handler can be used like this

TextView timer;
    int m =0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        timer=(TextView) findViewById(R.id.timerText);
        Handler handler = new UpdateHandler();

        m = 10;
        handler.sendEmptyMessageDelayed(1, 1000);//start after 1000
    }


    class UpdateHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
            case 1:
                timer=(TextView) findViewById(R.id.timerText);
                timer.setText("Text :" +m);
                m = m-1000;
                sendEmptyMessageDelayed(1, 1000); //seng again after 1000
                //add some stop logic
                break; 

            default:
                break;
            }

        }
    }


回答5:

Try this code Initialize textview in

onCreate
   timer=(TextView) findViewById(R.id.timerText);


public void loopMethod(int m){

 if(m>=1000){
  try {

    System.out.println(m);
    m=m-1000;

    final ScheduledThreadPoolExecutor c = new ScheduledThreadPoolExecutor(1);
            c.schedule(new Runnable() {
                @Override
                public void run() {
                    timer.setText(""+m);//timer is a textview
                      c.shutdownNow();

                }
            }, 1, TimeUnit.SECONDS);





} catch(InterruptedException ex) {
    ex.printStackTrace();
}
loopMethod(m);
}
}


回答6:

I've added some logics to stop the Timer. If you have any qyestion, ask freely

private int m = 0;
private int milliseconds = 1000;

public void loopMethod(int m){
  timer=(TextView) findViewById(R.id.timerText);
  Timer t = new Timer();

  //schedule a timer
  t.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run() {      
      runOnUiThread(new Runnable() {              
        @Override
        public void run() {
          timer.setText(String.valueOf(m));//avoid using composite string in the setText
          System.out.println(String.valueOf(m));

          //remove from the total the amount of millisecond passed
          m=m-milliseconds;
          if(m <= milliseconds) { //or <= what you want
            //stop the timer repeatitions
            t.cancel();
          }
        }
      });
    }
  //"0" is the amount of time to wait for the timer to start
  //"milliseconds" is the duration
  },0,milliseconds);
}

Add

For a correct analysis you should add more infos in your question. the problem of not-updating textview might be caused by the setText("" + int) because it's always better to avoid the setText with an int. I edited it with String.valueOf, but if it's not working you should add the xml and the onCreate

Hope this helped



回答7:

I have created timer for seconds.

public class TimerForSeconds extends AppCompatActivity {

    private int seconds = 60;
    private TextView tvTimer;
    private Handler mHandler;
    private Runnable runnable = new Runnable() {
        @Override
        public void run() {
            if(seconds == 0){
                mHandler.removeCallbacks(runnable);
            }
            else{
                tvTimer.setText(seconds + "");
                seconds--;
                mHandler.postDelayed(runnable,1000);
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test_activity);

        tvTimer = (TextView) findViewById(R.id.tv_timer);
        mHandler = new Handler();
        mHandler.postDelayed(runnable,1000);
    }
}

//and also removCallback onDestroy too.