ViewPager — how to start different timers on each page?
All I want is to create new separate timer for each page in the ViewPager. My current realization contains the one handler for all of the pages. I start new TimerTask using ViewPager.OnPageChangeListener.onPageSelected(), but as I can see during my application working, runnables stacks and timer goes faster and faster, updating all textviews at one time, even though I'm trying to remove all callbacks in the handler.
How it should work: swipe to page 1 — timer 1 starts, swipe to page 2 — timer 1 resets and stops, timer 2 starts and so on.
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageScrollStateChanged(int page) {
}
public void onPageScrolled(int position, float arg1, int arg2) {
}
public void onPageSelected(int position) {
View currentPage = ((QuestionPagerAdapter) viewPager.getAdapter()).get(position);
timerText = (TextView) currentPage.findViewById(R.id.timerText);
handler.removeCallbacks(doTick);
if (timerText != null) startTimer();
}
});
Runnable realization:
final Runnable doTick = new Runnable() {
public void run() {
seconds--;
if (seconds == -1) {
minutes--;
seconds = 59;
}
String secText = String.valueOf(seconds);
if (seconds < 10) secText = "0" + secText;
timerText.setText("0" + String.valueOf(minutes) + ":" + secText);
viewPager.getAdapter().notifyDataSetChanged();
}
};
private void startTimer() {
for (int i = 1; i <= seconds; i++) {
TimerTask task = new TimerTask() {
@Override
public void run() {
handler.post(doTick);
}
};
timer.schedule(task, i * 1000);
}
}
Where do you instantiate new doTick Runnable? This should be done only once, otherwise, you will not be able to remove all callbacks associated to a doTick instance as you would have lost it and replaced it with a new instance.
Declare it has a data field and modify you startTimer method as follow :
private void startTimer( TextView textView ) {
if( doTicks != null ) {
handler.removeCallbacks(doTick);
doTicks = new doTicks( textView );
}
for (int i = 1; i <= seconds; i++) {
TimerTask task = new TimerTask() {
@Override
public void run() {
handler.post(doTick);
}
};
timer.schedule(task, i * 1000);
}
}
You will also need to provide a parameter to your doTicks Runnable to give it a reference to the field it has to update. Pass this parameter to startTimer as well, and don't keep a reference on this field as the data member of the activity, only as a data member of doTicks (so you need to create a true static inner class).
链接地址: http://www.djcxy.com/p/13006.html