Focus on the right pane when choosing an app on left
As before, user can also do 4-finger swipe down to move to right pane. Bug: 345396938 Flag: EXEMPT bugfix Test: Manual - see video in comments Change-Id: If72862af2b05ae54c47e8d446a168252d3fc8194
This commit is contained in:
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.launcher3.widget.picker;
|
||||
|
||||
import static android.animation.ValueAnimator.areAnimatorsEnabled;
|
||||
|
||||
import static com.android.launcher3.widget.picker.WidgetsListAdapter.VIEW_TYPE_WIDGETS_LIST;
|
||||
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
@@ -26,6 +28,14 @@ public class WidgetsListItemAnimator extends DefaultItemAnimator {
|
||||
public static final int MOVE_DURATION_MS = 90;
|
||||
public static final int ADD_DURATION_MS = 120;
|
||||
|
||||
// DefaultItemAnimator runs change and move animations before running add animations (i.e.
|
||||
// before expanded list item's content start animating to become visible on screen).
|
||||
public static final int WIDGET_LIST_ITEM_APPEARANCE_START_DELAY =
|
||||
areAnimatorsEnabled() ? (CHANGE_DURATION_MS + MOVE_DURATION_MS) : 0;
|
||||
// Delay after which all item animations are ran and list item's content is visible.
|
||||
public static final int WIDGET_LIST_ITEM_APPEARANCE_DELAY =
|
||||
WIDGET_LIST_ITEM_APPEARANCE_START_DELAY + ADD_DURATION_MS;
|
||||
|
||||
public WidgetsListItemAnimator() {
|
||||
super();
|
||||
|
||||
|
||||
@@ -15,10 +15,7 @@
|
||||
*/
|
||||
package com.android.launcher3.widget.picker;
|
||||
|
||||
import static com.android.launcher3.widget.picker.WidgetsListItemAnimator.CHANGE_DURATION_MS;
|
||||
import static com.android.launcher3.widget.picker.WidgetsListItemAnimator.MOVE_DURATION_MS;
|
||||
|
||||
import static android.animation.ValueAnimator.areAnimatorsEnabled;
|
||||
import static com.android.launcher3.widget.picker.WidgetsListItemAnimator.WIDGET_LIST_ITEM_APPEARANCE_START_DELAY;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
@@ -157,8 +154,7 @@ public final class WidgetsListTableViewHolderBinder
|
||||
// Pass resize delay to let the "move" and "change" animations run before resizing the
|
||||
// row.
|
||||
tableRow.setupRow(widgetItems.size(),
|
||||
/*resizeDelayMs=*/
|
||||
areAnimatorsEnabled() ? (CHANGE_DURATION_MS + MOVE_DURATION_MS) : 0);
|
||||
/*resizeDelayMs=*/ WIDGET_LIST_ITEM_APPEARANCE_START_DELAY);
|
||||
if (tableRow.getChildCount() > widgetItems.size()) {
|
||||
for (int j = widgetItems.size(); j < tableRow.getChildCount(); j++) {
|
||||
tableRow.getChildAt(j).setVisibility(View.GONE);
|
||||
|
||||
@@ -21,6 +21,7 @@ import static com.android.launcher3.UtilitiesKt.CLIP_CHILDREN_FALSE_MODIFIER;
|
||||
import static com.android.launcher3.UtilitiesKt.CLIP_TO_PADDING_FALSE_MODIFIER;
|
||||
import static com.android.launcher3.UtilitiesKt.modifyAttributesOnViewTree;
|
||||
import static com.android.launcher3.UtilitiesKt.restoreAttributesOnViewTree;
|
||||
import static com.android.launcher3.widget.picker.WidgetsListItemAnimator.WIDGET_LIST_ITEM_APPEARANCE_DELAY;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
@@ -31,6 +32,7 @@ import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewParent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
@@ -281,10 +283,19 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
|
||||
mRightPane.removeAllViews();
|
||||
mRightPane.addView(mWidgetRecommendationsContainer);
|
||||
mRightPaneScrollView.setScrollY(0);
|
||||
mRightPane.setAccessibilityPaneTitle(suggestionsRightPaneTitle);
|
||||
mSuggestedWidgetsPackageUserKey = PackageUserKey.fromPackageItemInfo(packageItemInfo);
|
||||
final boolean isChangingHeaders = mSelectedHeader == null
|
||||
|| !mSelectedHeader.equals(mSuggestedWidgetsPackageUserKey);
|
||||
// If the initial focus view is still focused, it is likely a programmatic header
|
||||
// click.
|
||||
if (mSelectedHeader != null
|
||||
&& !getAccessibilityInitialFocusView().isAccessibilityFocused()) {
|
||||
post(() -> {
|
||||
mRightPaneScrollView.setAccessibilityPaneTitle(suggestionsRightPaneTitle);
|
||||
mRightPaneScrollView.performAccessibilityAction(
|
||||
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
|
||||
});
|
||||
}
|
||||
if (isChangingHeaders) {
|
||||
// If switching from another header, unselect any WidgetCells. This is necessary
|
||||
// because we do not clear/recycle the WidgetCells in the recommendations container
|
||||
@@ -296,7 +307,6 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
|
||||
mSelectedHeader = mSuggestedWidgetsPackageUserKey;
|
||||
});
|
||||
mSuggestedWidgetsContainer.addView(mSuggestedWidgetsHeader);
|
||||
mRightPane.setAccessibilityPaneTitle(suggestionsRightPaneTitle);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -323,12 +333,14 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
|
||||
|
||||
mActivePage = currentActivePage;
|
||||
|
||||
if (mSuggestedWidgetsHeader == null) {
|
||||
mAdapters.get(currentActivePage).mWidgetsListAdapter.selectFirstHeaderEntry();
|
||||
mAdapters.get(currentActivePage).mWidgetsRecyclerView.scrollToTop();
|
||||
} else if (currentActivePage == PERSONAL_TAB || currentActivePage == WORK_TAB) {
|
||||
mSuggestedWidgetsHeader.callOnClick();
|
||||
}
|
||||
// When using talkback, swiping left while on right pane, should navigate to the widgets
|
||||
// list on left.
|
||||
mAdapters.get(mActivePage).mWidgetsRecyclerView.setAccessibilityTraversalBefore(
|
||||
mRightPaneScrollView.getId());
|
||||
|
||||
// On page change, select the first item in the list to show in the right pane.
|
||||
mAdapters.get(currentActivePage).mWidgetsListAdapter.selectFirstHeaderEntry();
|
||||
mAdapters.get(currentActivePage).mWidgetsRecyclerView.scrollToTop();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -383,6 +395,10 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
|
||||
public void onHeaderChanged(@NonNull PackageUserKey selectedHeader) {
|
||||
final boolean isSameHeader = mSelectedHeader != null
|
||||
&& mSelectedHeader.equals(selectedHeader);
|
||||
// If the initial focus view is still focused, it is likely a programmatic header
|
||||
// click.
|
||||
final boolean isUserClick = mSelectedHeader != null
|
||||
&& !getAccessibilityInitialFocusView().isAccessibilityFocused();
|
||||
mSelectedHeader = selectedHeader;
|
||||
WidgetsListContentEntry contentEntry = mActivityContext.getPopupDataProvider()
|
||||
.getSelectedAppWidgets(selectedHeader);
|
||||
@@ -427,11 +443,14 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
|
||||
};
|
||||
mRightPane.removeAllViews();
|
||||
mRightPane.addView(widgetsRowViewHolder.itemView);
|
||||
if (isUserClick) {
|
||||
mRightPaneScrollView.setAccessibilityPaneTitle(getContext().getString(
|
||||
R.string.widget_picker_right_pane_accessibility_title,
|
||||
contentEntry.mPkgItem.title));
|
||||
postDelayed(() -> focusOnFirstWidgetCell(widgetsRowViewHolder.tableContainer),
|
||||
WIDGET_LIST_ITEM_APPEARANCE_DELAY);
|
||||
}
|
||||
mRightPaneScrollView.setScrollY(0);
|
||||
mRightPane.setAccessibilityPaneTitle(
|
||||
getContext().getString(
|
||||
R.string.widget_picker_right_pane_accessibility_title,
|
||||
contentEntry.mPkgItem.title));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -445,6 +464,18 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests focus on the first widget cell in the given widget section.
|
||||
*/
|
||||
private static void focusOnFirstWidgetCell(ViewGroup parent) {
|
||||
if (parent == null) return;
|
||||
WidgetCell cell = Utilities.findViewByPredicate(parent, v -> v instanceof WidgetCell);
|
||||
if (cell != null) {
|
||||
cell.performAccessibilityAction(
|
||||
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void unselectWidgetCell(ViewGroup parent, WidgetItem item) {
|
||||
if (parent == null || item == null) return;
|
||||
WidgetCell cell = Utilities.findViewByPredicate(parent, v -> v instanceof WidgetCell wc
|
||||
|
||||
Reference in New Issue
Block a user