diff --git a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java index 9992ae71916..a64ec89e332 100644 --- a/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java +++ b/src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java @@ -141,6 +141,8 @@ public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter return; } + // Highlight request accepted + mHighlightRequested = true; // Collapse app bar after 300 milliseconds. if (appBarLayout != null) { root.postDelayed(() -> { @@ -152,17 +154,37 @@ public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter recyclerView.setItemAnimator(null); // Scroll to correct position after 600 milliseconds. root.postDelayed(() -> { - mHighlightRequested = true; - recyclerView.smoothScrollToPosition(position); - mHighlightPosition = position; + if (ensureHighlightPosition()) { + recyclerView.smoothScrollToPosition(mHighlightPosition); + } }, DELAY_HIGHLIGHT_DURATION_MILLIS); // Highlight preference after 900 milliseconds. root.postDelayed(() -> { - notifyItemChanged(position); + if (ensureHighlightPosition()) { + notifyItemChanged(mHighlightPosition); + } }, DELAY_COLLAPSE_DURATION_MILLIS + DELAY_HIGHLIGHT_DURATION_MILLIS); } + /** + * Make sure we highlight the real-wanted position in case of preference position already + * changed when the delay time comes. + */ + private boolean ensureHighlightPosition() { + if (TextUtils.isEmpty(mHighlightKey)) { + return false; + } + final int position = getPreferenceAdapterPosition(mHighlightKey); + final boolean allowHighlight = position >= 0; + if (allowHighlight && mHighlightPosition != position) { + Log.w(TAG, "EnsureHighlight: position has changed since last highlight request"); + // Make sure RecyclerView always uses latest correct position to avoid exceptions. + mHighlightPosition = position; + } + return allowHighlight; + } + public boolean isHighlightRequested() { return mHighlightRequested; } diff --git a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java index e297b788af9..2453a30587c 100644 --- a/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java +++ b/tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java @@ -129,7 +129,7 @@ public class HighlightablePreferenceGroupAdapterTest { } @Test - public void adjustInitialExpandedChildCount_hasHightlightKey_shouldExpandAllChildren() { + public void adjustInitialExpandedChildCount_hasHighlightKey_shouldExpandAllChildren() { final Bundle args = new Bundle(); when(mFragment.getArguments()).thenReturn(args); args.putString(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, "testkey"); @@ -208,7 +208,7 @@ public class HighlightablePreferenceGroupAdapterTest { } @Test - public void updateBackground_reuseHightlightedRowForNormalRow_shouldResetBackgroundAndTag() { + public void updateBackground_reuseHighlightedRowForNormalRow_shouldResetBackgroundAndTag() { ReflectionHelpers.setField(mAdapter, "mHighlightPosition", 10); mViewHolder.itemView.setTag(R.id.preference_highlighted, true);