Limit the suggestions to be shown to 5.
- when creating the dashboard data, pass the sublist of suggestions to cap the total number of suggestions to be shown to 5. - if user swipe away the suggestion, it will only remove the suggestion from the suggestion adapater, and will not trigger rebuilding the whole UI. Bug: 64072051 Change-Id: I1efabeb2a805c670007c631d3ccb0fdfbde7b55a Fix: 63309218 Test: make RunSettingsRoboTests
This commit is contained in:
@@ -67,6 +67,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
static final String STATE_SUGGESTION_CONDITION_MODE = "suggestion_condition_mode";
|
static final String STATE_SUGGESTION_CONDITION_MODE = "suggestion_condition_mode";
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final int SUGGESTION_CONDITION_HEADER_POSITION = 0;
|
static final int SUGGESTION_CONDITION_HEADER_POSITION = 0;
|
||||||
|
@VisibleForTesting
|
||||||
|
static final int MAX_SUGGESTION_TO_SHOW = 5;
|
||||||
|
|
||||||
private final IconCache mCache;
|
private final IconCache mCache;
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -152,7 +154,8 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
|
|
||||||
final DashboardData prevData = mDashboardData;
|
final DashboardData prevData = mDashboardData;
|
||||||
mDashboardData = new DashboardData.Builder(prevData)
|
mDashboardData = new DashboardData.Builder(prevData)
|
||||||
.setSuggestions(suggestions)
|
.setSuggestions(suggestions.subList(0,
|
||||||
|
Math.min(suggestions.size(), MAX_SUGGESTION_TO_SHOW)))
|
||||||
.setCategory(category)
|
.setCategory(category)
|
||||||
.build();
|
.build();
|
||||||
notifyDashboardDataChanged(prevData);
|
notifyDashboardDataChanged(prevData);
|
||||||
@@ -194,9 +197,12 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
notifyDashboardDataChanged(prevData);
|
notifyDashboardDataChanged(prevData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSuggestionDismissed() {
|
public void onSuggestionDismissed(Tile suggestion) {
|
||||||
final List<Tile> suggestions = mDashboardData.getSuggestions();
|
final List<Tile> suggestions = mDashboardData.getSuggestions();
|
||||||
if (suggestions != null && suggestions.size() == 1) {
|
if (suggestions == null || suggestions.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (suggestions.size() == 1) {
|
||||||
// The only suggestion is dismissed, and the the empty suggestion container will
|
// The only suggestion is dismissed, and the the empty suggestion container will
|
||||||
// remain as the dashboard item. Need to refresh the dashboard list.
|
// remain as the dashboard item. Need to refresh the dashboard list.
|
||||||
final DashboardData prevData = mDashboardData;
|
final DashboardData prevData = mDashboardData;
|
||||||
@@ -204,6 +210,9 @@ public class DashboardAdapter extends RecyclerView.Adapter<DashboardAdapter.Dash
|
|||||||
.setSuggestions(null)
|
.setSuggestions(null)
|
||||||
.build();
|
.build();
|
||||||
notifyDashboardDataChanged(prevData);
|
notifyDashboardDataChanged(prevData);
|
||||||
|
} else {
|
||||||
|
suggestions.remove(suggestion);
|
||||||
|
mSuggestionAdapter.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -251,10 +251,7 @@ public class DashboardSummary extends InstrumentedFragment
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSuggestionDismissed(Tile suggestion) {
|
public void onSuggestionDismissed(Tile suggestion) {
|
||||||
mAdapter.onSuggestionDismissed();
|
mAdapter.onSuggestionDismissed(suggestion);
|
||||||
// Refresh the UI to pick up suggestions that can now be shown because, say, a higher
|
|
||||||
// priority suggestion has been dismissed, or an exclusive suggestion category is emptied.
|
|
||||||
rebuildUI();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SuggestionLoader extends AsyncTask<Void, Void, List<Tile>> {
|
private class SuggestionLoader extends AsyncTask<Void, Void, List<Tile>> {
|
||||||
|
@@ -321,17 +321,33 @@ public class DashboardAdapterTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuggestionDismissed_notOnlySuggestion_doNothing() {
|
public void testSuggestionDismissed_notOnlySuggestion_updateSuggestionOnly() {
|
||||||
final DashboardAdapter adapter =
|
final DashboardAdapter adapter =
|
||||||
spy(new DashboardAdapter(mContext, null, null, null, null));
|
spy(new DashboardAdapter(mContext, null, null, null, null));
|
||||||
adapter.setCategoriesAndSuggestions(
|
final List<Tile> suggestions = makeSuggestions("pkg1", "pkg2", "pkg3");
|
||||||
null /* category */, makeSuggestions("pkg1", "pkg2", "pkg3"));
|
adapter.setCategoriesAndSuggestions(null /* category */, suggestions);
|
||||||
|
|
||||||
|
final RecyclerView data = mock(RecyclerView.class);
|
||||||
|
when(data.getResources()).thenReturn(mResources);
|
||||||
|
when(data.getContext()).thenReturn(mContext);
|
||||||
|
when(mResources.getDisplayMetrics()).thenReturn(mock(DisplayMetrics.class));
|
||||||
|
final View itemView = mock(View.class);
|
||||||
|
when(itemView.findViewById(R.id.data)).thenReturn(data);
|
||||||
|
final DashboardAdapter.SuggestionAndConditionContainerHolder holder =
|
||||||
|
new DashboardAdapter.SuggestionAndConditionContainerHolder(itemView);
|
||||||
|
|
||||||
|
adapter.onBindConditionAndSuggestion(
|
||||||
|
holder, DashboardAdapter.SUGGESTION_CONDITION_HEADER_POSITION);
|
||||||
|
|
||||||
final DashboardData dashboardData = adapter.mDashboardData;
|
final DashboardData dashboardData = adapter.mDashboardData;
|
||||||
reset(adapter); // clear interactions tracking
|
reset(adapter); // clear interactions tracking
|
||||||
|
|
||||||
adapter.onSuggestionDismissed();
|
final Tile suggestionToRemove = suggestions.get(1);
|
||||||
|
adapter.onSuggestionDismissed(suggestionToRemove);
|
||||||
|
|
||||||
assertThat(adapter.mDashboardData).isEqualTo(dashboardData);
|
assertThat(adapter.mDashboardData).isEqualTo(dashboardData);
|
||||||
|
assertThat(suggestions.size()).isEqualTo(2);
|
||||||
|
assertThat(suggestions.contains(suggestionToRemove)).isFalse();
|
||||||
verify(adapter, never()).notifyDashboardDataChanged(any());
|
verify(adapter, never()).notifyDashboardDataChanged(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,11 +355,12 @@ public class DashboardAdapterTest {
|
|||||||
public void testSuggestionDismissed_onlySuggestion_updateDashboardData() {
|
public void testSuggestionDismissed_onlySuggestion_updateDashboardData() {
|
||||||
DashboardAdapter adapter =
|
DashboardAdapter adapter =
|
||||||
spy(new DashboardAdapter(mContext, null, null, null, null));
|
spy(new DashboardAdapter(mContext, null, null, null, null));
|
||||||
adapter.setCategoriesAndSuggestions(null /* category */, makeSuggestions("pkg1"));
|
final List<Tile> suggestions = makeSuggestions("pkg1");
|
||||||
|
adapter.setCategoriesAndSuggestions(null /* category */, suggestions);
|
||||||
final DashboardData dashboardData = adapter.mDashboardData;
|
final DashboardData dashboardData = adapter.mDashboardData;
|
||||||
reset(adapter); // clear interactions tracking
|
reset(adapter); // clear interactions tracking
|
||||||
|
|
||||||
adapter.onSuggestionDismissed();
|
adapter.onSuggestionDismissed(suggestions.get(0));
|
||||||
|
|
||||||
assertThat(adapter.mDashboardData).isNotEqualTo(dashboardData);
|
assertThat(adapter.mDashboardData).isNotEqualTo(dashboardData);
|
||||||
verify(adapter).notifyDashboardDataChanged(any());
|
verify(adapter).notifyDashboardDataChanged(any());
|
||||||
@@ -385,6 +402,16 @@ public class DashboardAdapterTest {
|
|||||||
verify(mockIcon).setTint(eq(0x89000000));
|
verify(mockIcon).setTint(eq(0x89000000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetCategoriesAndSuggestions_limitSuggestionSize() {
|
||||||
|
List<Tile> packages =
|
||||||
|
makeSuggestions("pkg1", "pkg2", "pkg3", "pkg4", "pkg5", "pkg6", "pkg7");
|
||||||
|
mDashboardAdapter.setCategoriesAndSuggestions(null /* category */, packages);
|
||||||
|
|
||||||
|
assertThat(mDashboardAdapter.mDashboardData.getSuggestions().size())
|
||||||
|
.isEqualTo(DashboardAdapter.MAX_SUGGESTION_TO_SHOW);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBindConditionAndSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
|
public void testBindConditionAndSuggestion_shouldSetSuggestionAdapterAndNoCrash() {
|
||||||
mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null);
|
mDashboardAdapter = new DashboardAdapter(mContext, null, null, null, null);
|
||||||
|
@@ -118,9 +118,8 @@ public class DashboardSummaryTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onSuggestionDismissed_categoryShouldBeRefreshed() {
|
public void onSuggestionDismissed_shouldNotRebuildUI() {
|
||||||
doNothing().when(mSummary).rebuildUI();
|
|
||||||
mSummary.onSuggestionDismissed(mock(Tile.class));
|
mSummary.onSuggestionDismissed(mock(Tile.class));
|
||||||
verify(mSummary).rebuildUI();
|
verify(mSummary, never()).rebuildUI();
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user