OSDN Git Service

Merge "Fix text overlap issue when flinging in ManageApplication" into pi-dev
authorTreeHugger Robot <treehugger-gerrit@google.com>
Mon, 26 Mar 2018 21:50:14 +0000 (21:50 +0000)
committerAndroid (Google) Code Review <android-gerrit@google.com>
Mon, 26 Mar 2018 21:50:14 +0000 (21:50 +0000)
src/com/android/settings/applications/manageapplications/ManageApplications.java
tests/robotests/src/com/android/settings/applications/manageapplications/ManageApplicationsTest.java

index d144169..6521056 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.android.settings.applications.manageapplications;
 
+import static android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE;
 import static com.android.settings.applications.manageapplications.AppFilterRegistry
         .FILTER_APPS_ALL;
 import static com.android.settings.applications.manageapplications.AppFilterRegistry
@@ -50,6 +51,7 @@ import android.os.Environment;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.PreferenceFrameLayout;
+import android.support.annotation.NonNull;
 import android.support.annotation.VisibleForTesting;
 import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
@@ -844,11 +846,16 @@ public class ManageApplications extends InstrumentedFragment
         private boolean mHasReceivedBridgeCallback;
         private FileViewHolderController mExtraViewController;
 
-        // These two variables are used to remember and restore the last scroll position when this
+        // This is to remember and restore the last scroll position when this
         // fragment is paused. We need this special handling because app entries are added gradually
         // when we rebuild the list after the user made some changes, like uninstalling an app.
         private int mLastIndex = -1;
 
+        @VisibleForTesting
+        OnScrollListener mOnScrollListener;
+        private RecyclerView mRecyclerView;
+
+
         public ApplicationsAdapter(ApplicationsState state, ManageApplications manageApplications,
                 AppFilterItem appFilter, Bundle savedInstanceState) {
             setHasStableIds(true);
@@ -886,6 +893,22 @@ public class ManageApplications extends InstrumentedFragment
             }
         }
 
+        @Override
+        public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
+            super.onAttachedToRecyclerView(recyclerView);
+            mRecyclerView = recyclerView;
+            mOnScrollListener = new OnScrollListener(this);
+            mRecyclerView.addOnScrollListener(mOnScrollListener);
+        }
+
+        @Override
+        public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
+            super.onDetachedFromRecyclerView(recyclerView);
+            mRecyclerView.removeOnScrollListener(mOnScrollListener);
+            mOnScrollListener = null;
+            mRecyclerView = null;
+        }
+
         public void setCompositeFilter(AppFilter compositeFilter) {
             mCompositeFilter = compositeFilter;
             rebuild();
@@ -1180,9 +1203,8 @@ public class ManageApplications extends InstrumentedFragment
                     rebuild();
                     return;
                 } else {
-                    notifyItemChanged(i);
+                    mOnScrollListener.postNotifyItemChange(i);
                 }
-
             }
         }
 
@@ -1310,13 +1332,39 @@ public class ManageApplications extends InstrumentedFragment
             return mExtraViewController != null
                     && mExtraViewController.shouldShow();
         }
+
+        public static class OnScrollListener extends RecyclerView.OnScrollListener {
+            private int mScrollState = SCROLL_STATE_IDLE;
+            private boolean mDelayNotifyDataChange;
+            private ApplicationsAdapter mAdapter;
+
+            public OnScrollListener(ApplicationsAdapter adapter) {
+                mAdapter = adapter;
+            }
+
+            @Override
+            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
+                mScrollState = newState;
+                if (mScrollState == SCROLL_STATE_IDLE && mDelayNotifyDataChange) {
+                    mDelayNotifyDataChange = false;
+                    mAdapter.notifyDataSetChanged();
+                }
+            }
+
+            public void postNotifyItemChange(int index) {
+                if (mScrollState == SCROLL_STATE_IDLE) {
+                    mAdapter.notifyItemChanged(index);
+                } else {
+                    mDelayNotifyDataChange = true;
+                }
+            }
+        }
     }
 
     private static class SummaryProvider implements SummaryLoader.SummaryProvider {
 
         private final Context mContext;
         private final SummaryLoader mLoader;
-        private ApplicationsState.Session mSession;
 
         private SummaryProvider(Context context, SummaryLoader loader) {
             mContext = context;
index f60c7b0..fb7b59d 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.settings.applications.manageapplications;
 
+import static android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING;
+import static android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE;
 import static com.android.settings.applications.manageapplications.AppFilterRegistry.FILTER_APPS_ALL;
 import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_MAIN;
 import static com.android.settings.applications.manageapplications.ManageApplications.LIST_TYPE_NOTIFICATION;
@@ -229,6 +231,40 @@ public class ManageApplicationsTest {
         verify(loadingViewController).showContent(true /* animate */);
     }
 
+    @Test
+    public void notifyItemChange_recyclerViewIdle_shouldNotify() {
+        final RecyclerView recyclerView = mock(RecyclerView.class);
+        final ManageApplications.ApplicationsAdapter adapter =
+                spy(new ManageApplications.ApplicationsAdapter(mState,
+                        mock(ManageApplications.class),
+                        AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
+
+        adapter.onAttachedToRecyclerView(recyclerView);
+        adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_IDLE);
+        adapter.mOnScrollListener.postNotifyItemChange(0 /* index */);
+
+        verify(adapter).notifyItemChanged(0);
+    }
+
+    @Test
+    public void notifyItemChange_recyclerViewScrolling_shouldNotifyWhenIdle() {
+        final RecyclerView recyclerView = mock(RecyclerView.class);
+        final ManageApplications.ApplicationsAdapter adapter =
+                spy(new ManageApplications.ApplicationsAdapter(mState,
+                        mock(ManageApplications.class),
+                        AppFilterRegistry.getInstance().get(FILTER_APPS_ALL), new Bundle()));
+
+        adapter.onAttachedToRecyclerView(recyclerView);
+        adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_DRAGGING);
+        adapter.mOnScrollListener.postNotifyItemChange(0 /* index */);
+
+        verify(adapter, never()).notifyItemChanged(0);
+        verify(adapter, never()).notifyDataSetChanged();
+
+        adapter.mOnScrollListener.onScrollStateChanged(recyclerView, SCROLL_STATE_IDLE);
+        verify(adapter).notifyDataSetChanged();
+    }
+
     private void setUpOptionMenus() {
         when(mMenu.findItem(anyInt())).thenAnswer(invocation -> {
             final Object[] args = invocation.getArguments();