Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 21875052 authored by Romain Guy's avatar Romain Guy
Browse files

Fix two ListView bugs related to onAttachedToWindow/onDetachedFromWindow.

Bug: #2359368.

onDetachedFromWindow() would never be called for views living in the scrap heap, but onAttachedToWindow() could be called several times for views recycled from the scrap heap.
parent 3e7b44fa
Loading
Loading
Loading
Loading
+14 −8
Original line number Diff line number Diff line
@@ -126,11 +126,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
     */
    static final int TOUCH_MODE_FLING = 4;

    /**
     * Indicates that the user is currently dragging the fast scroll thumb
     */
    static final int TOUCH_MODE_FAST_SCROLL = 5;

    /**
     * Regular layout - usually an unsolicited layout from the view system
     */
@@ -441,6 +436,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
    private int mMinimumVelocity;
    private int mMaximumVelocity;
    
    final boolean[] mIsScrap = new boolean[1];

    /**
     * Interface definition for a callback to be invoked when the list or grid
     * has been scrolled.
@@ -1239,9 +1236,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
     * converting an old view or making a new one.
     *
     * @param position The position to display
     * @param isScrap Array of at least 1 boolean, the first entry will become true if
     *                the returned view was taken from the scrap heap, false if otherwise.
     * 
     * @return A view displaying the data associated with the specified position
     */
    View obtainView(int position) {
    View obtainView(int position, boolean[] isScrap) {
        isScrap[0] = false;
        View scrapView;

        scrapView = mRecycler.getScrapView(position);
@@ -1269,6 +1270,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                    ViewDebug.trace(scrapView, ViewDebug.RecyclerTraceType.MOVE_TO_SCRAP_HEAP,
                            position, -1);
                }
            } else {
                isScrap[0] = true;                
            }
        } else {
            child = mAdapter.getView(position, null, this);
@@ -1543,6 +1546,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
        // Dismiss the popup in case onSaveInstanceState() was not invoked
        dismissPopup();

        // Detach any view left in the scrap heap
        mRecycler.clear();

        final ViewTreeObserver treeObserver = getViewTreeObserver();
        if (treeObserver != null) {
            treeObserver.removeOnTouchModeChangeListener(this);
@@ -3595,12 +3601,12 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            for (int i = 0; i < count; ++i) {
                final View victim = activeViews[i];
                if (victim != null) {
                    int whichScrap = ((AbsListView.LayoutParams)
                            victim.getLayoutParams()).viewType;
                    int whichScrap = ((AbsListView.LayoutParams) victim.getLayoutParams()).viewType;

                    activeViews[i] = null;

                    if (whichScrap == AdapterView.ITEM_VIEW_TYPE_IGNORE) {
                        removeDetachedView(victim, false);
                        // Do not move views that should be ignored
                        continue;
                    }
+2 −2
Original line number Diff line number Diff line
@@ -1485,8 +1485,8 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
         * @return the view for the specified item
         */
        @Override
        protected View obtainView(int position) {
            View view = super.obtainView(position);
        View obtainView(int position, boolean[] isScrap) {
            View view = super.obtainView(position, isScrap);

            if (view instanceof TextView) {
                ((TextView) view).setHorizontallyScrolling(true);
+4 −4
Original line number Diff line number Diff line
@@ -931,7 +931,7 @@ public class GridView extends AbsListView {
        mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
        final int count = mItemCount;
        if (count > 0) {
            final View child = obtainView(0);
            final View child = obtainView(0, mIsScrap);

            AbsListView.LayoutParams p = (AbsListView.LayoutParams)child.getLayoutParams();
            if (p == null) {
@@ -1203,7 +1203,7 @@ public class GridView extends AbsListView {
        View child;

        if (!mDataChanged) {
            // Try to use an exsiting view for this position
            // Try to use an existing view for this position
            child = mRecycler.getActiveView(position);
            if (child != null) {
                // Found it -- we're using an existing child
@@ -1215,10 +1215,10 @@ public class GridView extends AbsListView {

        // Make a new view for this position, or convert an unused view if
        // possible
        child = obtainView(position);
        child = obtainView(position, mIsScrap);

        // This needs to be positioned and measured
        setupChild(child, position, y, flow, childrenLeft, selected, false, where);
        setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0], where);

        return child;
    }
+11 −8
Original line number Diff line number Diff line
@@ -1033,7 +1033,7 @@ public class ListView extends AbsListView {
        mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
        if (mItemCount > 0 && (widthMode == MeasureSpec.UNSPECIFIED ||
                heightMode == MeasureSpec.UNSPECIFIED)) {
            final View child = obtainView(0);
            final View child = obtainView(0, mIsScrap);

            measureScrapChild(child, 0, widthMeasureSpec);

@@ -1142,9 +1142,10 @@ public class ListView extends AbsListView {
        endPosition = (endPosition == NO_POSITION) ? adapter.getCount() - 1 : endPosition;
        final AbsListView.RecycleBin recycleBin = mRecycler;
        final boolean recyle = recycleOnMeasure();
        final boolean[] isScrap = mIsScrap;

        for (i = startPosition; i <= endPosition; ++i) {
            child = obtainView(i);
            child = obtainView(i, isScrap);

            measureScrapChild(child, i, widthMeasureSpec);

@@ -1665,10 +1666,10 @@ public class ListView extends AbsListView {
        }

        // Make a new view for this position, or convert an unused view if possible
        child = obtainView(position);
        child = obtainView(position, mIsScrap);

        // This needs to be positioned and measured
        setupChild(child, position, y, flow, childrenLeft, selected, false);
        setupChild(child, position, y, flow, childrenLeft, selected, mIsScrap[0]);

        return child;
    }
@@ -2823,17 +2824,19 @@ public class ListView extends AbsListView {

    private View addViewAbove(View theView, int position) {
        int abovePosition = position - 1;
        View view = obtainView(abovePosition);
        View view = obtainView(abovePosition, mIsScrap);
        int edgeOfNewChild = theView.getTop() - mDividerHeight;
        setupChild(view, abovePosition, edgeOfNewChild, false, mListPadding.left, false, false);
        setupChild(view, abovePosition, edgeOfNewChild, false, mListPadding.left,
                false, mIsScrap[0]);
        return view;
    }

    private View addViewBelow(View theView, int position) {
        int belowPosition = position + 1;
        View view = obtainView(belowPosition);
        View view = obtainView(belowPosition, mIsScrap);
        int edgeOfNewChild = theView.getBottom() + mDividerHeight;
        setupChild(view, belowPosition, edgeOfNewChild, true, mListPadding.left, false, false);
        setupChild(view, belowPosition, edgeOfNewChild, true, mListPadding.left,
                false, mIsScrap[0]);
        return view;
    }