Loading src/com/android/settings/SettingsPreferenceFragment.java +5 −3 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ import com.android.settingslib.core.instrumentation.Instrumentable; import com.android.settingslib.search.Indexable; import com.android.settingslib.widget.LayoutPreference; import com.google.android.material.appbar.AppBarLayout; import java.util.UUID; /** Loading Loading @@ -112,9 +114,8 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF @VisibleForTesting ViewGroup mPinnedHeaderFrameLayout; private AppBarLayout mAppBarLayout; private LayoutPreference mHeader; private View mEmptyView; private LinearLayoutManager mLayoutManager; private ArrayMap<String, Preference> mPreferenceCache; Loading Loading @@ -145,6 +146,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF Bundle savedInstanceState) { final View root = super.onCreateView(inflater, container, savedInstanceState); mPinnedHeaderFrameLayout = root.findViewById(R.id.pinned_header); mAppBarLayout = getActivity().findViewById(R.id.app_bar); return root; } Loading Loading @@ -250,7 +252,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF return; } if (mAdapter != null) { mAdapter.requestHighlight(getView(), getListView()); mAdapter.requestHighlight(getView(), getListView(), mAppBarLayout); } } Loading src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java +21 −6 Original line number Diff line number Diff line Loading @@ -39,10 +39,14 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.google.android.material.appbar.AppBarLayout; public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter { private static final String TAG = "HighlightableAdapter"; @VisibleForTesting static final long DELAY_COLLAPSE_DURATION_MILLIS = 300L; @VisibleForTesting static final long DELAY_HIGHLIGHT_DURATION_MILLIS = 600L; private static final long HIGHLIGHT_DURATION = 15000L; private static final long HIGHLIGHT_FADE_OUT_DURATION = 500L; Loading Loading @@ -124,15 +128,26 @@ public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter } } public void requestHighlight(View root, RecyclerView recyclerView) { /** * A function can highlight a specific setting in recycler view. * note: Before highlighting a setting, screen collapses tool bar with an animation. */ public void requestHighlight(View root, RecyclerView recyclerView, AppBarLayout appBarLayout) { if (mHighlightRequested || recyclerView == null || TextUtils.isEmpty(mHighlightKey)) { return; } root.postDelayed(() -> { final int position = getPreferenceAdapterPosition(mHighlightKey); if (position < 0) { return; } if (appBarLayout != null) { root.postDelayed(() -> { appBarLayout.setExpanded(false, true); }, DELAY_COLLAPSE_DURATION_MILLIS); } root.postDelayed(() -> { mHighlightRequested = true; recyclerView.smoothScrollToPosition(position); mHighlightPosition = position; Loading tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java +11 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; Loading @@ -43,6 +44,8 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.google.android.material.appbar.AppBarLayout; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -85,8 +88,11 @@ public class HighlightablePreferenceGroupAdapterTest { @Test public void requestHighlight_hasKey_notHighlightedBefore_shouldRequest() { mAdapter.requestHighlight(mRoot, mock(RecyclerView.class)); when(mAdapter.getPreferenceAdapterPosition(anyString())).thenReturn(1); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class), mock(AppBarLayout.class)); verify(mRoot).postDelayed(any(), eq(HighlightablePreferenceGroupAdapter.DELAY_COLLAPSE_DURATION_MILLIS)); verify(mRoot).postDelayed(any(), eq(HighlightablePreferenceGroupAdapter.DELAY_HIGHLIGHT_DURATION_MILLIS)); } Loading @@ -95,21 +101,21 @@ public class HighlightablePreferenceGroupAdapterTest { public void requestHighlight_noKey_highlightedBefore_noRecyclerView_shouldNotRequest() { ReflectionHelpers.setField(mAdapter, "mHighlightKey", null); ReflectionHelpers.setField(mAdapter, "mHighlightRequested", false); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class)); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class), mock(AppBarLayout.class)); ReflectionHelpers.setField(mAdapter, "mHighlightKey", TEST_KEY); ReflectionHelpers.setField(mAdapter, "mHighlightRequested", true); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class)); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class), mock(AppBarLayout.class)); ReflectionHelpers.setField(mAdapter, "mHighlightKey", TEST_KEY); ReflectionHelpers.setField(mAdapter, "mHighlightRequested", false); mAdapter.requestHighlight(mRoot, null /* recyclerView */); mAdapter.requestHighlight(mRoot, null /* recyclerView */, mock(AppBarLayout.class)); verifyZeroInteractions(mRoot); } @Test public void adjustInitialExpandedChildCount_invalidInput_shouldNotadjust() { public void adjustInitialExpandedChildCount_invalidInput_shouldNotAdjust() { HighlightablePreferenceGroupAdapter.adjustInitialExpandedChildCount(null /* host */); HighlightablePreferenceGroupAdapter.adjustInitialExpandedChildCount(mFragment); final Bundle args = new Bundle(); Loading Loading
src/com/android/settings/SettingsPreferenceFragment.java +5 −3 Original line number Diff line number Diff line Loading @@ -57,6 +57,8 @@ import com.android.settingslib.core.instrumentation.Instrumentable; import com.android.settingslib.search.Indexable; import com.android.settingslib.widget.LayoutPreference; import com.google.android.material.appbar.AppBarLayout; import java.util.UUID; /** Loading Loading @@ -112,9 +114,8 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF @VisibleForTesting ViewGroup mPinnedHeaderFrameLayout; private AppBarLayout mAppBarLayout; private LayoutPreference mHeader; private View mEmptyView; private LinearLayoutManager mLayoutManager; private ArrayMap<String, Preference> mPreferenceCache; Loading Loading @@ -145,6 +146,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF Bundle savedInstanceState) { final View root = super.onCreateView(inflater, container, savedInstanceState); mPinnedHeaderFrameLayout = root.findViewById(R.id.pinned_header); mAppBarLayout = getActivity().findViewById(R.id.app_bar); return root; } Loading Loading @@ -250,7 +252,7 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF return; } if (mAdapter != null) { mAdapter.requestHighlight(getView(), getListView()); mAdapter.requestHighlight(getView(), getListView(), mAppBarLayout); } } Loading
src/com/android/settings/widget/HighlightablePreferenceGroupAdapter.java +21 −6 Original line number Diff line number Diff line Loading @@ -39,10 +39,14 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.settings.R; import com.android.settings.SettingsPreferenceFragment; import com.google.android.material.appbar.AppBarLayout; public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter { private static final String TAG = "HighlightableAdapter"; @VisibleForTesting static final long DELAY_COLLAPSE_DURATION_MILLIS = 300L; @VisibleForTesting static final long DELAY_HIGHLIGHT_DURATION_MILLIS = 600L; private static final long HIGHLIGHT_DURATION = 15000L; private static final long HIGHLIGHT_FADE_OUT_DURATION = 500L; Loading Loading @@ -124,15 +128,26 @@ public class HighlightablePreferenceGroupAdapter extends PreferenceGroupAdapter } } public void requestHighlight(View root, RecyclerView recyclerView) { /** * A function can highlight a specific setting in recycler view. * note: Before highlighting a setting, screen collapses tool bar with an animation. */ public void requestHighlight(View root, RecyclerView recyclerView, AppBarLayout appBarLayout) { if (mHighlightRequested || recyclerView == null || TextUtils.isEmpty(mHighlightKey)) { return; } root.postDelayed(() -> { final int position = getPreferenceAdapterPosition(mHighlightKey); if (position < 0) { return; } if (appBarLayout != null) { root.postDelayed(() -> { appBarLayout.setExpanded(false, true); }, DELAY_COLLAPSE_DURATION_MILLIS); } root.postDelayed(() -> { mHighlightRequested = true; recyclerView.smoothScrollToPosition(position); mHighlightPosition = position; Loading
tests/robotests/src/com/android/settings/widget/HighlightablePreferenceGroupAdapterTest.java +11 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; Loading @@ -43,6 +44,8 @@ import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.SettingsPreferenceFragment; import com.google.android.material.appbar.AppBarLayout; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading Loading @@ -85,8 +88,11 @@ public class HighlightablePreferenceGroupAdapterTest { @Test public void requestHighlight_hasKey_notHighlightedBefore_shouldRequest() { mAdapter.requestHighlight(mRoot, mock(RecyclerView.class)); when(mAdapter.getPreferenceAdapterPosition(anyString())).thenReturn(1); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class), mock(AppBarLayout.class)); verify(mRoot).postDelayed(any(), eq(HighlightablePreferenceGroupAdapter.DELAY_COLLAPSE_DURATION_MILLIS)); verify(mRoot).postDelayed(any(), eq(HighlightablePreferenceGroupAdapter.DELAY_HIGHLIGHT_DURATION_MILLIS)); } Loading @@ -95,21 +101,21 @@ public class HighlightablePreferenceGroupAdapterTest { public void requestHighlight_noKey_highlightedBefore_noRecyclerView_shouldNotRequest() { ReflectionHelpers.setField(mAdapter, "mHighlightKey", null); ReflectionHelpers.setField(mAdapter, "mHighlightRequested", false); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class)); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class), mock(AppBarLayout.class)); ReflectionHelpers.setField(mAdapter, "mHighlightKey", TEST_KEY); ReflectionHelpers.setField(mAdapter, "mHighlightRequested", true); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class)); mAdapter.requestHighlight(mRoot, mock(RecyclerView.class), mock(AppBarLayout.class)); ReflectionHelpers.setField(mAdapter, "mHighlightKey", TEST_KEY); ReflectionHelpers.setField(mAdapter, "mHighlightRequested", false); mAdapter.requestHighlight(mRoot, null /* recyclerView */); mAdapter.requestHighlight(mRoot, null /* recyclerView */, mock(AppBarLayout.class)); verifyZeroInteractions(mRoot); } @Test public void adjustInitialExpandedChildCount_invalidInput_shouldNotadjust() { public void adjustInitialExpandedChildCount_invalidInput_shouldNotAdjust() { HighlightablePreferenceGroupAdapter.adjustInitialExpandedChildCount(null /* host */); HighlightablePreferenceGroupAdapter.adjustInitialExpandedChildCount(mFragment); final Bundle args = new Bundle(); Loading