Merge "Fix controller navigation on two panel launcher home" into sc-v2-dev am: 7f569f14b4

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/15261999

Change-Id: I2414078c267aeec335bc4ef433cc78270af3cc46
This commit is contained in:
András Klöczl
2021-07-30 08:55:59 +00:00
committed by Automerger Merge Worker
2 changed files with 91 additions and 53 deletions
+82 -53
View File
@@ -238,10 +238,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return getChildAt(index);
}
protected int indexToPage(int index) {
return index;
}
/**
* Updates the scroll of the current page immediately to its final scroll position. We use this
* in CustomizePagedView to allow tabs to share the same PagedView while resetting the scroll of
@@ -322,18 +318,56 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
*/
@VisibleForTesting(otherwise = PACKAGE_PRIVATE)
public IntSet getVisiblePageIndices() {
IntSet visiblePageIndices = new IntSet();
return getPageIndices(mCurrentPage);
}
/**
* In case the panelCount is 1 this just returns the same page index in an IntSet.
* But in cases where the panelCount > 1 this will return all the page indices that belong
* together, i.e. on the Workspace they are next to each other and shown at the same time.
*/
private IntSet getPageIndices(int pageIndex) {
// we want to make sure the pageIndex is the leftmost page
pageIndex = getLeftmostVisiblePageForIndex(pageIndex);
IntSet pageIndices = new IntSet();
int panelCount = getPanelCount();
int pageCount = getPageCount();
// If a device goes from one panel to two panel (i.e. unfolding a foldable device) while
// an odd indexed page is the current page, then the new leftmost visible page will be
// different from the old mCurrentPage.
int currentPage = getLeftmostVisiblePageForIndex(mCurrentPage);
for (int page = currentPage; page < currentPage + panelCount && page < pageCount; page++) {
visiblePageIndices.add(page);
for (int page = pageIndex; page < pageIndex + panelCount && page < pageCount; page++) {
pageIndices.add(page);
}
return visiblePageIndices;
return pageIndices;
}
/**
* Returns an IntSet with the indices of the neighbour pages that are in the focus direction.
*/
private IntSet getNeighbourPageIndices(int focus) {
int panelCount = getPanelCount();
// getNextPage is more reliable than getCurrentPage
int currentPage = getNextPage();
int nextPage;
if (focus == View.FOCUS_LEFT) {
nextPage = currentPage - panelCount;
} else if (focus == View.FOCUS_RIGHT) {
nextPage = currentPage + panelCount;
} else {
// no neighbours to those direction
return new IntSet();
}
nextPage = validateNewPage(nextPage);
if (nextPage == currentPage) {
// We reached the end of the pages
return new IntSet();
}
int pageCount = getPageCount();
IntSet neighbourIndices = new IntSet();
for (int page = nextPage; page < nextPage + panelCount && page < pageCount; page++) {
neighbourIndices.add(page);
}
return neighbourIndices;
}
/**
@@ -352,7 +386,14 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
* Returns true if the view is on one of the current pages, false otherwise.
*/
public boolean isVisible(View child) {
return getLeftmostVisiblePageForIndex(indexOfChild(child)) == mCurrentPage;
return isVisible(indexOfChild(child));
}
/**
* Returns true if the page with the given index is currently visible, false otherwise.
*/
private boolean isVisible(int pageIndex) {
return getLeftmostVisiblePageForIndex(pageIndex) == mCurrentPage;
}
/**
@@ -817,8 +858,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
@Override
public boolean requestChildRectangleOnScreen(View child, Rect rectangle, boolean immediate) {
int page = indexToPage(indexOfChild(child));
if (page != mCurrentPage || !mScroller.isFinished()) {
int page = indexOfChild(child);
if (!isVisible(page) || !mScroller.isFinished()) {
if (immediate) {
setCurrentPage(page);
} else {
@@ -857,21 +898,25 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
direction = View.FOCUS_LEFT;
}
}
if (direction == View.FOCUS_LEFT) {
if (getCurrentPage() > 0) {
int nextPage = validateNewPage(getCurrentPage() - 1);
snapToPage(nextPage);
getChildAt(nextPage).requestFocus(direction);
return true;
}
} else if (direction == View.FOCUS_RIGHT) {
if (getCurrentPage() < getPageCount() - 1) {
int nextPage = validateNewPage(getCurrentPage() + 1);
snapToPage(nextPage);
getChildAt(nextPage).requestFocus(direction);
return true;
int currentPage = getNextPage();
int closestNeighbourIndex = -1;
int closestNeighbourDistance = Integer.MAX_VALUE;
// Find the closest neighbour page
for (int neighbourPageIndex : getNeighbourPageIndices(direction)) {
int distance = Math.abs(neighbourPageIndex - currentPage);
if (closestNeighbourDistance > distance) {
closestNeighbourDistance = distance;
closestNeighbourIndex = neighbourPageIndex;
}
}
if (closestNeighbourIndex != -1) {
View page = getPageAt(closestNeighbourIndex);
snapToPage(closestNeighbourIndex);
page.requestFocus(direction);
return true;
}
return false;
}
@@ -881,28 +926,12 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return;
}
// Add the current page's views as focusable and the next possible page's too. If the
// last focus change action was left then the left neighbour's views will be added, and
// if it was right then the right neighbour's views will be added.
// Unfortunately mCurrentPage can be outdated if there were multiple control actions in a
// short period of time, but mNextPage is up to date because it is always updated by
// method snapToPage.
int nextPage = getNextPage();
// XXX-RTL: This will be fixed in a future CL
if (nextPage >= 0 && nextPage < getPageCount()) {
getPageAt(nextPage).addFocusables(views, direction, focusableMode);
}
if (direction == View.FOCUS_LEFT) {
if (nextPage > 0) {
nextPage = validateNewPage(nextPage - 1);
getPageAt(nextPage).addFocusables(views, direction, focusableMode);
}
} else if (direction == View.FOCUS_RIGHT) {
if (nextPage < getPageCount() - 1) {
nextPage = validateNewPage(nextPage + 1);
getPageAt(nextPage).addFocusables(views, direction, focusableMode);
}
}
// nextPage is more reliable when multiple control movements have been done in a short
// period of time
getPageIndices(getNextPage())
.addAll(getNeighbourPageIndices(direction))
.forEach(pageIndex ->
getPageAt(pageIndex).addFocusables(views, direction, focusableMode));
}
/**
@@ -1482,8 +1511,8 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
setCurrentPage(nextPage);
}
int page = indexToPage(indexOfChild(child));
if (page >= 0 && page != getCurrentPage() && !isInTouchMode()) {
int page = indexOfChild(child);
if (page >= 0 && !isVisible(page) && !isInTouchMode()) {
snapToPage(page);
}
}
@@ -36,6 +36,15 @@ public class IntSet implements Iterable<Integer> {
}
}
/**
* Appends the specified IntSet's values to the set if they does not exist, then returns the
* original set that now also contains the new values.
*/
public IntSet addAll(IntSet other) {
other.forEach(this::add);
return this;
}
/**
* Removes the specified value from the set if it exist.
*/