OSDN Git Service

Fix locale reorder jank
authorMihai Nita <mnita@google.com>
Fri, 18 Mar 2016 23:06:49 +0000 (16:06 -0700)
committerMihai Nita <mnita@google.com>
Wed, 23 Mar 2016 19:21:31 +0000 (12:21 -0700)
Using RecyclerView.ItemAnimator.ItemAnimatorFinishedListener
to only update the locales when all the animations finished.
This also reduces the number of repeated updates if the
locale list did not actually changed.

This was tested by setting the duration of animations to 3 seconds,
which made it possible to "shuffle" the list a lot and see several
items slowly moving around in the same time.

Bug: 26710681
Change-Id: I7d025e60cc252f4b90006b7b18c86d93ab94826f

src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java

index 28a5588..a78c60d 100644 (file)
@@ -48,6 +48,7 @@ class LocaleDragAndDropAdapter
     private final Context mContext;
     private final List<LocaleStore.LocaleInfo> mFeedItemList;
     private final ItemTouchHelper mItemTouchHelper;
+    private RecyclerView mParentView = null;
     private boolean mRemoveMode = false;
     private boolean mDragEnabled = true;
     private NumberFormat mNumberFormatter = NumberFormat.getNumberInstance();
@@ -132,6 +133,7 @@ class LocaleDragAndDropAdapter
     }
 
     public void setRecyclerView(RecyclerView rv) {
+        mParentView = rv;
         mItemTouchHelper.attachToRecyclerView(rv);
     }
 
@@ -239,17 +241,46 @@ class LocaleDragAndDropAdapter
 
     public void doTheUpdate() {
         int count = mFeedItemList.size();
-        Locale[] newList = new Locale[count];
+        final Locale[] newList = new Locale[count];
 
         for (int i = 0; i < count; i++) {
-            LocaleStore.LocaleInfo li = mFeedItemList.get(i);
+            final LocaleStore.LocaleInfo li = mFeedItemList.get(i);
             newList[i] = li.getLocale();
         }
 
-        LocaleList ll = new LocaleList(newList);
-        LocalePicker.updateLocales(ll);
+        final LocaleList ll = new LocaleList(newList);
+        updateLocalesWhenAnimationStops(ll);
+    }
+
+    private LocaleList mLocalesToSetNext = null;
+    private LocaleList mLocalesSetLast = null;
+
+    public void updateLocalesWhenAnimationStops(final LocaleList localeList) {
+        if (localeList.equals(mLocalesToSetNext)) {
+            return;
+        }
+
+        // This will only update the Settings application to make things feel more responsive,
+        // the system will be updated later, when animation stopped.
+        LocaleList.setDefault(localeList);
 
-        mNumberFormatter = NumberFormat.getNumberInstance(Locale.getDefault());
+        mLocalesToSetNext = localeList;
+        final RecyclerView.ItemAnimator itemAnimator = mParentView.getItemAnimator();
+        itemAnimator.isRunning(new RecyclerView.ItemAnimator.ItemAnimatorFinishedListener() {
+            @Override
+            public void onAnimationsFinished() {
+                if (mLocalesToSetNext == null || mLocalesToSetNext.equals(mLocalesSetLast)) {
+                    // All animations finished, but the locale list did not change
+                    return;
+                }
+
+                LocalePicker.updateLocales(mLocalesToSetNext);
+                mLocalesSetLast = mLocalesToSetNext;
+                mLocalesToSetNext = null;
+
+                mNumberFormatter = NumberFormat.getNumberInstance(Locale.getDefault());
+            }
+        });
     }
 
     private void setDragEnabled(boolean enabled) {