From 5a7ce50e19e3a85b8744d8b58d39adcd7726867d Mon Sep 17 00:00:00 2001 From: Mihai Nita Date: Fri, 18 Mar 2016 16:06:49 -0700 Subject: [PATCH] Fix locale reorder jank 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 --- .../LocaleDragAndDropAdapter.java | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java index 28a5588136b..a78c60dd099 100644 --- a/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java +++ b/src/com/android/settings/localepicker/LocaleDragAndDropAdapter.java @@ -48,6 +48,7 @@ class LocaleDragAndDropAdapter private final Context mContext; private final List 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); + } - mNumberFormatter = NumberFormat.getNumberInstance(Locale.getDefault()); + 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); + + 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) {