【问题标题】:ViewPager — how to start different timers on each page?ViewPager — 如何在每个页面上启动不同的计时器?
【发布时间】:2017-11-28 15:04:43
【问题描述】:

我想要的只是为 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); 
    }
}

【问题讨论】:

    标签: android timer handler runnable


    【解决方案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的数据成员(所以你需要创建一个真正的静态内部类)。

    【讨论】:

    • 现在可以使用 textViews。但是有一件事——每次我在页面上滑动时,计时器堆栈和秒数都会变快,回调似乎没有被删除。
    • 您确定在每个实例上调用 removeCallBack 吗?在控制台中打印出你的可运行文件,他们会给你他们的“地址”:每次你创建一个,每次你调用 removecallbacks 时都打印出来。它们应该匹配。
    • 非常感谢,但我还没有弄清楚这些东西。我简单地使用 android.os.CountDownTimer 解决了我的问题,它非常适合。
    猜你喜欢
    • 2017-05-15
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2014-03-07
    • 2021-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多