【问题标题】:View recycling in listview causes postDelayed() issue在 listview 中查看回收导致 postDelayed() 问题
【发布时间】:2015-04-30 04:27:45
【问题描述】:

我有一个用户任务/待办事项列表,其中包含与之相关的截止日期。每分钟我都会更新TextView,显示这些任务的剩余时间。

我遇到的问题是,有时当文本视图更新时,会显示错误的剩余时间,特别是如果我上下滚动,那么另一个任务的剩余时间将出现在它的位置。

我知道这与列表中的视图被回收有关,并且不敬的(屏幕外)视图仍在处理它们的逻辑。我将错误缩小到我的Runnable 类,其中taskTime 有时与错误的视图相关联。

我不确定如何使用正确的view 维护正确的taskTime,有什么建议吗?

p.s 如何清除所有 postDelayed() 中不再可见的视图?

MyCursorTreeAdapter.class

@Override
protected void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {
    ViewHolder viewHolder = (ViewHolder) view.getTag();
    long taskTime = cursor.getLong(cursor.getColumnIndexOrThrow(TableTask.COLUMN_TIME));
    viewHolder.timeLeftTextView.setText(TimeUtils.getFormatedTimeLeft(taskTime));

    Runnable updateTimeRemainingRunnable = new UpdateTimeRemainingRunnable(view, taskTime);
    long postDelay = TimeUtils.millisecondsUntilNextMinute();
    view.postDelayed(updateTimeRemainingRunnable, postDelay);
}

private static class UpdateTimeRemainingRunnable implements Runnable {
    private final WeakReference<View> weakViewRef;
    private final long taskTime;

    protected UpdateTimeRemainingRunnable(View view, long taskTime) {
        weakViewRef = new WeakReference<>(view);
        this.taskTime = taskTime;
    }

    @Override
    public void run() {
        final View view = weakViewRef.get();
        if (view == null) return;

        ViewHolder viewHolder = (ViewHolder) view.getTag();
        view.getTag();

        // Task time is wrong here -- I sometimes get another task's task time

        String formatedTime = TimeUtils.getFormatedTimeLeft(taskTime);
        viewHolder.timeLeftTextView.setText(formatedTime);

        long postDelay = TimeUtils.millisecondsUntilNextSecond();
        view.postDelayed(this, postDelay);
    }
}

【问题讨论】:

    标签: android runnable android-handler postdelayed


    【解决方案1】:

    直接的方式,

    使用view.setTag(resouce_id,runnable)将runnable和view绑定在一起;

    getChildView时,首先检查view.getTag(resouce_id),如果不为null,使用 view.removeCallbacks() 清除它,并重新组合一个新的 Runnable。

    列表视图在滚动时使用回收项... .

    但这不是最佳解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-16
      • 1970-01-01
      • 2014-11-30
      • 1970-01-01
      相关资源
      最近更新 更多