Make sure ReorderAlgorithm only work on the logic layer and not on the view layer
The method isNearestDropLocationOccupied finds the NearestDrop location
using the view models (i.e. the CellLayoutLayoutParams) and the new
method isConfigurationRegionOccupied run over the logic models (i.e. the
CellAndSpan or ItemConfiguration) ensuring a separation between them.
Test: ReorderAlgorithmUnitTest
Flag: LEGACY FOLDABLE_SINGLE_PAGE DISABLED
Bug: 270395274
Change-Id: I0b3c6606ee6934ea3a5e41d110677c496d4a4330
diff --git a/src/com/android/launcher3/celllayout/ReorderAlgorithm.java b/src/com/android/launcher3/celllayout/ReorderAlgorithm.java
index 5e5eefe..17786f2 100644
--- a/src/com/android/launcher3/celllayout/ReorderAlgorithm.java
+++ b/src/com/android/launcher3/celllayout/ReorderAlgorithm.java
@@ -15,10 +15,13 @@
*/
package com.android.launcher3.celllayout;
+import android.graphics.Rect;
import android.view.View;
import com.android.launcher3.CellLayout;
+import java.util.Map.Entry;
+
/**
* Contains the logic of a reorder.
*
@@ -109,14 +112,16 @@
*/
public CellLayout.ItemConfiguration dropInPlaceSolution(int pixelX, int pixelY, int spanX,
int spanY, View dragView) {
- int[] result = new int[2];
- if (mCellLayout.isNearestDropLocationOccupied(pixelX, pixelY, spanX, spanY, dragView,
- result)) {
- result[0] = result[1] = -1;
- }
+ int[] result = mCellLayout.findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY,
+ new int[2]);
CellLayout.ItemConfiguration solution = new CellLayout.ItemConfiguration();
mCellLayout.copyCurrentStateToSolution(solution, false);
- solution.isSolution = result[0] != -1;
+
+ solution.isSolution = !isConfigurationRegionOccupied(
+ new Rect(result[0], result[1], result[0] + spanX, result[1] + spanY),
+ solution,
+ dragView
+ );
if (!solution.isSolution) {
return solution;
}
@@ -127,6 +132,17 @@
return solution;
}
+ private boolean isConfigurationRegionOccupied(Rect region,
+ CellLayout.ItemConfiguration configuration, View ignoreView) {
+ return configuration.map.entrySet()
+ .stream()
+ .filter(entry -> entry.getKey() != ignoreView)
+ .map(Entry::getValue)
+ .anyMatch(cellAndSpan -> region.intersect(cellAndSpan.cellX, cellAndSpan.cellY,
+ cellAndSpan.cellX + cellAndSpan.spanX,
+ cellAndSpan.cellY + cellAndSpan.spanY));
+ }
+
/**
* Returns a "reorder" where we simply drop the item in the closest empty space, without moving
* any other item in the way.