Merge changes from topic "standalone-fix" into main
* changes: [part 2] Update standalone picker to align widget loading and animations [part-1] Perform doMeasure only once in WidgetsFullSheet
This commit is contained in:
committed by
Android (Google) Code Review
commit
b8f4e16fa7
@@ -120,10 +120,6 @@ public class WidgetPickerActivity extends BaseActivity {
|
||||
WindowInsetsController wc = mDragLayer.getWindowInsetsController();
|
||||
wc.hide(navigationBars() + statusBars());
|
||||
|
||||
BaseWidgetSheet widgetSheet = WidgetsFullSheet.show(this, true);
|
||||
widgetSheet.disableNavBarScrim(true);
|
||||
widgetSheet.addOnCloseListener(this::finish);
|
||||
|
||||
parseIntentExtras();
|
||||
refreshAndBindWidgets();
|
||||
}
|
||||
@@ -224,9 +220,10 @@ public class WidgetPickerActivity extends BaseActivity {
|
||||
};
|
||||
}
|
||||
|
||||
/** Updates the model with widgets and provides them after applying the provided filter. */
|
||||
/** Updates the model with widgets, applies filters and launches the widgets sheet once
|
||||
* widgets are available */
|
||||
private void refreshAndBindWidgets() {
|
||||
MODEL_EXECUTOR.execute(() -> {
|
||||
MODEL_EXECUTOR.getHandler().postDelayed(() -> {
|
||||
LauncherAppState app = LauncherAppState.getInstance(this);
|
||||
mModel.update(app, null);
|
||||
final List<WidgetsListBaseEntry> allWidgets =
|
||||
@@ -240,6 +237,9 @@ public class WidgetPickerActivity extends BaseActivity {
|
||||
}
|
||||
);
|
||||
bindWidgets(allWidgets);
|
||||
// Open sheet once widgets are available, so that it doesn't interrupt the open
|
||||
// animation.
|
||||
openWidgetsSheet();
|
||||
if (mUiSurface != null) {
|
||||
Map<ComponentKey, WidgetItem> allWidgetItems = allWidgets.stream()
|
||||
.filter(entry -> entry instanceof WidgetsListContentEntry)
|
||||
@@ -253,15 +253,26 @@ public class WidgetPickerActivity extends BaseActivity {
|
||||
mUiSurface, allWidgetItems);
|
||||
mWidgetPredictionsRequester.request(mAddedWidgets, this::bindRecommendedWidgets);
|
||||
}
|
||||
});
|
||||
}, mDeviceProfile.bottomSheetOpenDuration);
|
||||
}
|
||||
|
||||
private void bindWidgets(List<WidgetsListBaseEntry> widgets) {
|
||||
MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setAllWidgets(widgets));
|
||||
}
|
||||
|
||||
private void openWidgetsSheet() {
|
||||
MAIN_EXECUTOR.execute(() -> {
|
||||
BaseWidgetSheet widgetSheet = WidgetsFullSheet.show(this, true);
|
||||
widgetSheet.disableNavBarScrim(true);
|
||||
widgetSheet.addOnCloseListener(this::finish);
|
||||
});
|
||||
}
|
||||
|
||||
private void bindRecommendedWidgets(List<ItemInfo> recommendedWidgets) {
|
||||
MAIN_EXECUTOR.execute(() -> mPopupDataProvider.setRecommendedWidgets(recommendedWidgets));
|
||||
// Bind recommendations once picker has finished open animation.
|
||||
MAIN_EXECUTOR.getHandler().postDelayed(
|
||||
() -> mPopupDataProvider.setRecommendedWidgets(recommendedWidgets),
|
||||
mDeviceProfile.bottomSheetOpenDuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -65,6 +65,7 @@ public class WidgetPredictionsRequester {
|
||||
private final Context mContext;
|
||||
@NonNull
|
||||
private final String mUiSurface;
|
||||
private boolean mPredictionsAvailable;
|
||||
@NonNull
|
||||
private final Map<ComponentKey, WidgetItem> mAllWidgets;
|
||||
|
||||
@@ -76,8 +77,8 @@ public class WidgetPredictionsRequester {
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests predictions from the app predictions manager and registers the provided callback to
|
||||
* receive updates when predictions are available.
|
||||
* Requests one time predictions from the app predictions manager and invokes provided callback
|
||||
* once predictions are available.
|
||||
*
|
||||
* @param existingWidgets widgets that are currently added to the surface;
|
||||
* @param callback consumer of prediction results to be called when predictions are
|
||||
@@ -159,10 +160,14 @@ public class WidgetPredictionsRequester {
|
||||
@WorkerThread
|
||||
private void bindPredictions(List<AppTarget> targets, Predicate<WidgetItem> filter,
|
||||
Consumer<List<ItemInfo>> callback) {
|
||||
List<WidgetItem> filteredPredictions = filterPredictions(targets, mAllWidgets, filter);
|
||||
List<ItemInfo> mappedPredictions = mapWidgetItemsToItemInfo(filteredPredictions);
|
||||
if (!mPredictionsAvailable) {
|
||||
mPredictionsAvailable = true;
|
||||
List<WidgetItem> filteredPredictions = filterPredictions(targets, mAllWidgets, filter);
|
||||
List<ItemInfo> mappedPredictions = mapWidgetItemsToItemInfo(filteredPredictions);
|
||||
|
||||
MAIN_EXECUTOR.execute(() -> callback.accept(mappedPredictions));
|
||||
MAIN_EXECUTOR.execute(() -> callback.accept(mappedPredictions));
|
||||
MODEL_EXECUTOR.execute(this::clear);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -214,5 +219,6 @@ public class WidgetPredictionsRequester {
|
||||
mAppPredictor.destroy();
|
||||
mAppPredictor = null;
|
||||
}
|
||||
mPredictionsAvailable = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,8 +331,21 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<BaseActivity>
|
||||
* status bar, into account.
|
||||
*/
|
||||
protected void doMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int widthUsed = getInsetsWidth();
|
||||
|
||||
DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
|
||||
measureChildWithMargins(mContent, widthMeasureSpec,
|
||||
widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
|
||||
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
|
||||
MeasureSpec.getSize(heightMeasureSpec));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width used on left and right by the insets / padding.
|
||||
*/
|
||||
protected int getInsetsWidth() {
|
||||
int widthUsed;
|
||||
DeviceProfile deviceProfile = mActivityContext.getDeviceProfile();
|
||||
if (deviceProfile.isTablet) {
|
||||
widthUsed = Math.max(2 * getTabletHorizontalMargin(deviceProfile),
|
||||
2 * (mInsets.left + mInsets.right));
|
||||
@@ -343,11 +356,7 @@ public abstract class BaseWidgetSheet extends AbstractSlideInView<BaseActivity>
|
||||
widthUsed = Math.max(padding.left + padding.right,
|
||||
2 * (mInsets.left + mInsets.right));
|
||||
}
|
||||
|
||||
measureChildWithMargins(mContent, widthMeasureSpec,
|
||||
widthUsed, heightMeasureSpec, deviceProfile.bottomSheetTopPadding);
|
||||
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
|
||||
MeasureSpec.getSize(heightMeasureSpec));
|
||||
return widthUsed;
|
||||
}
|
||||
|
||||
/** Returns the horizontal margins to be applied to the widget sheet. **/
|
||||
|
||||
@@ -55,7 +55,6 @@ import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.compat.AccessibilityManagerCompat;
|
||||
@@ -416,19 +415,18 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int availableWidth = MeasureSpec.getSize(widthMeasureSpec);
|
||||
updateMaxSpansPerRow(availableWidth);
|
||||
doMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
|
||||
if (updateMaxSpansPerRow()) {
|
||||
doMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns {@code true} if the max spans have been updated. */
|
||||
private boolean updateMaxSpansPerRow() {
|
||||
if (getMeasuredWidth() == 0) return false;
|
||||
|
||||
@Px int maxHorizontalSpan = getContentView().getMeasuredWidth()
|
||||
- (2 * mContentHorizontalMargin);
|
||||
/** Returns {@code true} if the max spans have been updated.
|
||||
*
|
||||
* @param availableWidth Total width available within parent (includes insets).
|
||||
*/
|
||||
private void updateMaxSpansPerRow(int availableWidth) {
|
||||
@Px int maxHorizontalSpan = getAvailableWidthForSuggestions(
|
||||
availableWidth - getInsetsWidth());
|
||||
if (mMaxSpanPerRow != maxHorizontalSpan) {
|
||||
mMaxSpanPerRow = maxHorizontalSpan;
|
||||
mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.setMaxHorizontalSpansPxPerRow(
|
||||
@@ -439,16 +437,15 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
||||
mAdapters.get(AdapterHolder.WORK).mWidgetsListAdapter.setMaxHorizontalSpansPxPerRow(
|
||||
maxHorizontalSpan);
|
||||
}
|
||||
onRecommendedWidgetsBound();
|
||||
return true;
|
||||
post(this::onRecommendedWidgetsBound);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected View getContentView() {
|
||||
return mHasWorkProfile
|
||||
? mViewPager
|
||||
: mAdapters.get(AdapterHolder.PRIMARY).mWidgetsRecyclerView;
|
||||
/**
|
||||
* Returns the width available to display suggestions.
|
||||
*/
|
||||
protected int getAvailableWidthForSuggestions(int pickerAvailableWidth) {
|
||||
return pickerAvailableWidth - (2 * mContentHorizontalMargin);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -493,7 +490,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
||||
.mWidgetsListAdapter.hasVisibleEntries());
|
||||
if (mIsNoWidgetsViewNeeded != isNoWidgetsViewNeeded) {
|
||||
mIsNoWidgetsViewNeeded = isNoWidgetsViewNeeded;
|
||||
onRecommendedWidgetsBound();
|
||||
post(this::onRecommendedWidgetsBound);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,7 +546,7 @@ public class WidgetsFullSheet extends BaseWidgetSheet
|
||||
mAdapters.get(AdapterHolder.SEARCH).mWidgetsRecyclerView.setVisibility(GONE);
|
||||
// Visibility of recommended widgets, recycler views and headers are handled in methods
|
||||
// below.
|
||||
onRecommendedWidgetsBound();
|
||||
post(this::onRecommendedWidgetsBound);
|
||||
onWidgetsBound();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,6 +322,30 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
|
||||
* RECOMMENDATION_SECTION_HEIGHT_RATIO_TWO_PANE;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Px
|
||||
protected int getAvailableWidthForSuggestions(int pickerAvailableWidth) {
|
||||
int rightPaneWidth = (int) Math.ceil(0.67 * pickerAvailableWidth);
|
||||
|
||||
if (mDeviceProfile.isTwoPanels && enableUnfoldedTwoPanePicker()) {
|
||||
// See onLayout
|
||||
int leftPaneWidth = (int) (0.33 * pickerAvailableWidth);
|
||||
@Px int minLeftPaneWidthPx = Utilities.dpToPx(MINIMUM_WIDTH_LEFT_PANE_FOLDABLE_DP);
|
||||
@Px int maxLeftPaneWidthPx = Utilities.dpToPx(MAXIMUM_WIDTH_LEFT_PANE_FOLDABLE_DP);
|
||||
if (leftPaneWidth < minLeftPaneWidthPx) {
|
||||
leftPaneWidth = minLeftPaneWidthPx;
|
||||
} else if (leftPaneWidth > maxLeftPaneWidthPx) {
|
||||
leftPaneWidth = maxLeftPaneWidthPx;
|
||||
}
|
||||
rightPaneWidth = pickerAvailableWidth - leftPaneWidth;
|
||||
}
|
||||
|
||||
// Since suggestions are shown in right pane, the available width is 2/3 of total width of
|
||||
// bottom sheet.
|
||||
return rightPaneWidth - getResources().getDimensionPixelSize(
|
||||
R.dimen.widget_list_horizontal_margin_two_pane); // right pane end margin.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivePageChanged(int currentActivePage) {
|
||||
super.onActivePageChanged(currentActivePage);
|
||||
@@ -384,11 +408,6 @@ public class WidgetsTwoPaneSheet extends WidgetsFullSheet {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected View getContentView() {
|
||||
return mRightPane;
|
||||
}
|
||||
|
||||
private HeaderChangeListener getHeaderChangeListener() {
|
||||
return new HeaderChangeListener() {
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user