diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java index 68532caddf..b152ddc2d9 100644 --- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java +++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java @@ -183,15 +183,16 @@ public class WidgetsBottomSheet extends BaseWidgetSheet { TableLayout widgetsTable = findViewById(R.id.widgets_table); widgetsTable.removeAllViews(); - WidgetsTableUtils.groupWidgetItemsIntoTable(widgets, mMaxHorizontalSpan).forEach(row -> { - TableRow tableRow = new TableRow(getContext()); - tableRow.setGravity(Gravity.TOP); - row.forEach(widgetItem -> { - WidgetCell widget = addItemCell(tableRow); - widget.applyFromCellItem(widgetItem); - }); - widgetsTable.addView(tableRow); - }); + WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering(widgets, mMaxHorizontalSpan) + .forEach(row -> { + TableRow tableRow = new TableRow(getContext()); + tableRow.setGravity(Gravity.TOP); + row.forEach(widgetItem -> { + WidgetCell widget = addItemCell(tableRow); + widget.applyFromCellItem(widgetItem); + }); + widgetsTable.addView(tableRow); + }); } @Override diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java index 9e12f6f541..894c4c9cd3 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java @@ -535,8 +535,8 @@ public class WidgetsFullSheet extends BaseWidgetSheet - noWidgetsViewHeight) * RECOMMENDATION_TABLE_HEIGHT_RATIO; List> recommendedWidgetsInTable = - WidgetsTableUtils.groupWidgetItemsIntoTable(recommendedWidgets, - mMaxSpansPerRow); + WidgetsTableUtils.groupWidgetItemsIntoTableWithoutReordering( + recommendedWidgets, mMaxSpansPerRow); table.setRecommendedWidgets(recommendedWidgetsInTable, maxTableHeight); } else { table.setVisibility(GONE); diff --git a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java index 8c9ff0980b..05e26adacf 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java +++ b/src/com/android/launcher3/widget/picker/WidgetsListTableViewHolderBinder.java @@ -93,7 +93,7 @@ public final class WidgetsListTableViewHolderBinder } table.setListDrawableState(((position & POSITION_LAST) != 0) ? LAST : MIDDLE); List> widgetItemsTable = - WidgetsTableUtils.groupWidgetItemsIntoTable( + WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering( entry.mWidgets, entry.getMaxSpanSizeInCells()); recycleTableBeforeBinding(table, widgetItemsTable); diff --git a/src/com/android/launcher3/widget/util/WidgetsTableUtils.java b/src/com/android/launcher3/widget/util/WidgetsTableUtils.java index 54aaf93ac0..72e27bf37e 100644 --- a/src/com/android/launcher3/widget/util/WidgetsTableUtils.java +++ b/src/com/android/launcher3/widget/util/WidgetsTableUtils.java @@ -45,9 +45,20 @@ public final class WidgetsTableUtils { return item.spanX > otherItem.spanX ? 1 : -1; }; + /** + * Groups {@code widgetItems} items into a 2D array which matches their appearance in a UI + * table. This takes liberty to rearrange widgets to make the table visually appealing. + */ + public static List> groupWidgetItemsIntoTableWithReordering( + List widgetItems, final int maxSpansPerRow) { + List sortedWidgetItems = widgetItems.stream().sorted(WIDGET_SHORTCUT_COMPARATOR) + .collect(Collectors.toList()); + return groupWidgetItemsIntoTableWithoutReordering(sortedWidgetItems, maxSpansPerRow); + } /** - * Groups widgets items into a 2D array which matches their appearance in a UI table. + * Groups {@code widgetItems} into a 2D array which matches their appearance in a UI table while + * maintaining their order. * *

Grouping: * 1. Widgets and shortcuts never group together in the same row. @@ -64,13 +75,12 @@ public final class WidgetsTableUtils { * should be moved to a new row. * Example 3: Row 1: 6x4. This is okay because this is the only item in the row. */ - public static List> groupWidgetItemsIntoTable( + public static List> groupWidgetItemsIntoTableWithoutReordering( List widgetItems, final int maxSpansPerRow) { - List sortedWidgetItems = widgetItems.stream().sorted(WIDGET_SHORTCUT_COMPARATOR) - .collect(Collectors.toList()); + List> widgetItemsTable = new ArrayList<>(); ArrayList widgetItemsAtRow = null; - for (WidgetItem widgetItem : sortedWidgetItems) { + for (WidgetItem widgetItem : widgetItems) { if (widgetItemsAtRow == null) { widgetItemsAtRow = new ArrayList<>(); widgetItemsTable.add(widgetItemsAtRow); diff --git a/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java index d6da776e19..715dcca588 100644 --- a/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java +++ b/tests/src/com/android/launcher3/widget/picker/util/WidgetsTableUtilsTest.java @@ -92,12 +92,13 @@ public final class WidgetsTableUtilsTest { @Test - public void groupWidgetItemsIntoTable_widgetsOnly_maxSpansPerRow5_shouldGroupWidgetsInTable() { + public void groupWidgetItemsIntoTableWithReordering_widgetsOnly_maxSpansPerRow5_shouldGroupWidgetsInTable() { List widgetItems = List.of(mWidget4x4, mWidget2x3, mWidget1x1, mWidget2x4, mWidget2x2); - List> widgetItemInTable = WidgetsTableUtils.groupWidgetItemsIntoTable( - widgetItems, /* maxSpansPerRow= */ 5); + List> widgetItemInTable = + WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering( + widgetItems, /* maxSpansPerRow= */ 5); // Row 0: 1x1, 2x2 // Row 1: 2x3, 2x4 @@ -109,12 +110,13 @@ public final class WidgetsTableUtilsTest { } @Test - public void groupWidgetItemsIntoTable_widgetsOnly_maxSpansPerRow4_shouldGroupWidgetsInTable() { + public void groupWidgetItemsIntoTableWithReordering_widgetsOnly_maxSpansPerRow4_shouldGroupWidgetsInTable() { List widgetItems = List.of(mWidget4x4, mWidget2x3, mWidget1x1, mWidget2x4, mWidget2x2); - List> widgetItemInTable = WidgetsTableUtils.groupWidgetItemsIntoTable( - widgetItems, /* maxSpansPerRow= */ 4); + List> widgetItemInTable = + WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering( + widgetItems, /* maxSpansPerRow= */ 4); // Row 0: 1x1, 2x2 // Row 1: 2x3, @@ -128,12 +130,13 @@ public final class WidgetsTableUtilsTest { } @Test - public void groupWidgetItemsIntoTable_mixItems_maxSpansPerRow4_shouldGroupWidgetsInTable() { + public void groupWidgetItemsIntoTableWithReordering_mixItems_maxSpansPerRow4_shouldGroupWidgetsInTable() { List widgetItems = List.of(mWidget4x4, mShortcut3, mWidget2x3, mShortcut1, mWidget1x1, mShortcut2, mWidget2x4, mWidget2x2); - List> widgetItemInTable = WidgetsTableUtils.groupWidgetItemsIntoTable( - widgetItems, /* maxSpansPerRow= */ 4); + List> widgetItemInTable = + WidgetsTableUtils.groupWidgetItemsIntoTableWithReordering( + widgetItems, /* maxSpansPerRow= */ 4); // Row 0: 1x1, 2x2 // Row 1: 2x3, @@ -148,6 +151,24 @@ public final class WidgetsTableUtilsTest { assertThat(widgetItemInTable.get(4)).containsExactly(mShortcut3, mShortcut2, mShortcut1); } + @Test + public void groupWidgetItemsIntoTableWithoutReordering_shouldMaintainTheOrder() { + List widgetItems = + List.of(mWidget4x4, mWidget2x3, mWidget1x1, mWidget2x4, mWidget2x2); + + List> widgetItemInTable = + WidgetsTableUtils.groupWidgetItemsIntoTableWithoutReordering( + widgetItems, /* maxSpansPerRow= */ 5); + + // Row 0: 4x4 + // Row 1: 2x3, 1x1 + // Row 2: 2x4, 2x2 + assertThat(widgetItemInTable).hasSize(3); + assertThat(widgetItemInTable.get(0)).containsExactly(mWidget4x4); + assertThat(widgetItemInTable.get(1)).containsExactly(mWidget2x3, mWidget1x1); + assertThat(widgetItemInTable.get(2)).containsExactly(mWidget2x4, mWidget2x2); + } + private void initTestWidgets() { List widgetSizes = List.of(new Point(1, 1), new Point(2, 2), new Point(2, 3), new Point(2, 4), new Point(4, 4));