Skip to content
This repository has been archived by the owner on Nov 2, 2018. It is now read-only.

Invalid index is passed to adapter when notifyDataSetChanged() while scrolling #85

Open
ypresto opened this issue Jun 18, 2015 · 2 comments

Comments

@ypresto
Copy link
Contributor

ypresto commented Jun 18, 2015

FreeFlowContainer#notifyDataSetChanged() calls requestLayout() and redraw with backed adapter (computeLayout() and mLayout.prepareLayout()) in onMeasure().

But when requestLayout() is called while scrolling, onTouchEvent() is called before onMeasure() and it causes crash by IndexOutOfBoundsException in adapter implementation.

Note that ListView effectively avoids this problem by call layoutChildren() before applying scroll to view.

  1. Set mDataChanged = true in notifyDataSetChanged().
    https://github.com/android/platform_frameworks_base/blob/android-5.1.1_r4/core/java/android/widget/AdapterView.java#L809
  2. Check mDataChanged and call layoutChildren() inTouchMove().
    https://github.com/android/platform_frameworks_base/blob/android-5.1.1_r4/core/java/android/widget/AbsListView.java#L3763
  3. Then redraw views with new data from mAdapter.
    https://github.com/android/platform_frameworks_base/blob/android-5.1.1_r4/core/java/android/widget/ListView.java#L1561
@ypresto
Copy link
Contributor Author

ypresto commented Jun 18, 2015

Calling moveViewPort() before onMeasure() causes crash.

So flingRunnable is also affected.

@ypresto
Copy link
Contributor Author

ypresto commented Jun 19, 2015

For workaround extend FreeFlowContainer and call onMeasure() when moveViewport(boolean) is called.

    @SuppressLint("WrongCall") // for call onMeasure() directly instead of measure()
    @Override
    protected void moveViewport(boolean isInFlingMode) {
        if (dataSetChanged) {
            // XXX: Workaround for onTouchEvent() could be called between notifyDataSetChanged() and layout update in onMeasure()
            // and passing invalid index to adapter. This enforces layout update before applying scroll.
            // Refer: https://github.com/Comcast/FreeFlow/issues/85
            onMeasure(getWidth() | MeasureSpec.EXACTLY, getHeight() | MeasureSpec.EXACTLY);
        }
        super.moveViewport(isInFlingMode);
    }

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant