2

我想要的只是为 ViewPager 中的每个页面创建新的单独计时器。我当前的实现包含所有页面的一个处理程序。我使用 ViewPager.OnPageChangeListener.onPageSelected() 启动新的 TimerTask,但正如我在应用程序工作期间看到的那样,runnables 堆栈和计时器变得越来越快,一次更新所有文本视图,即使我试图删除所有回调处理程序。

它应该如何工作:滑动到第 1 页 - 计时器 1 启动,滑动到第 2 页 - 计时器 1 重置和停止,计时器 2 启动等等。

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();
        }

    });

可运行实现:

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); 
    }
}
4

1 回答 1

1

你在哪里实例化新的 doTick Runnable?这应该只执行一次,否则,您将无法删除与 doTick 实例关联的所有回调,因为您会丢失它并用新实例替换它。

声明它有一个数据字段并修改你的 startTimer 方法如下:

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); 
    }
}

您还需要为您的 doTicks Runnable 提供一个参数,以便为其必须更新的字段提供参考。把这个参数也传给startTimer,不要把这个字段的引用作为activity的数据成员,只作为doTicks的数据成员(所以你需要创建一个真正的静态内部类)。

于 2012-11-07T19:51:55.960 回答