Snap for 7752803 from b0ca4b3070 to tm-release
Change-Id: I25058f456bc561a2b1c87b1de07577fa27821a7f
This commit is contained in:
@@ -15,12 +15,15 @@
|
||||
*/
|
||||
package com.android.launcher3.hybridhotseat;
|
||||
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent
|
||||
.LAUNCHER_HOTSEAT_EDU_ONLY_TIP;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOTSEAT_EDU_ONLY_TIP;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.CellLayout;
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
@@ -47,6 +50,8 @@ import java.util.stream.IntStream;
|
||||
*/
|
||||
public class HotseatEduController {
|
||||
|
||||
private static final String TAG = "HotseatEduController";
|
||||
|
||||
public static final String SETTINGS_ACTION =
|
||||
"android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS";
|
||||
|
||||
@@ -188,8 +193,12 @@ public class HotseatEduController {
|
||||
.getInt(LauncherSettings.Settings.EXTRA_VALUE);
|
||||
mNewScreens = IntArray.wrap(pageId);
|
||||
}
|
||||
for (int i = 0; i < mLauncher.getDeviceProfile().numShownHotseatIcons; i++) {
|
||||
View child = mHotseat.getChildAt(i, 0);
|
||||
boolean isPortrait = !mLauncher.getDeviceProfile().isVerticalBarLayout();
|
||||
int hotseatItemsNum = mLauncher.getDeviceProfile().numShownHotseatIcons;
|
||||
for (int i = 0; i < hotseatItemsNum; i++) {
|
||||
int x = isPortrait ? i : 0;
|
||||
int y = isPortrait ? 0 : hotseatItemsNum - i - 1;
|
||||
View child = mHotseat.getChildAt(x, y);
|
||||
if (child == null || child.getTag() == null) continue;
|
||||
ItemInfo tag = (ItemInfo) child.getTag();
|
||||
if (tag.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION) continue;
|
||||
@@ -229,8 +238,7 @@ public class HotseatEduController {
|
||||
R.string.hotseat_prediction_settings, null,
|
||||
() -> mLauncher.startActivity(getSettingsIntent()));
|
||||
} else {
|
||||
new ArrowTipView(mLauncher).show(
|
||||
mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop());
|
||||
showHotseatArrowTip(true, mLauncher.getString(R.string.hotseat_tip_no_empty_slots));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,15 +259,50 @@ public class HotseatEduController {
|
||||
if (requiresMigration && canMigrateToFirstPage) {
|
||||
showDialog();
|
||||
} else {
|
||||
new ArrowTipView(mLauncher).show(mLauncher.getString(
|
||||
if (showHotseatArrowTip(requiresMigration, mLauncher.getString(
|
||||
requiresMigration ? R.string.hotseat_tip_no_empty_slots
|
||||
: R.string.hotseat_auto_enrolled),
|
||||
mHotseat.getTop());
|
||||
mLauncher.getStatsLogManager().logger().log(LAUNCHER_HOTSEAT_EDU_ONLY_TIP);
|
||||
: R.string.hotseat_auto_enrolled))) {
|
||||
mLauncher.getStatsLogManager().logger().log(LAUNCHER_HOTSEAT_EDU_ONLY_TIP);
|
||||
}
|
||||
finishOnboarding();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a child suitable child in hotseat and shows arrow tip pointing at it.
|
||||
*
|
||||
* @param usePinned used to determine target view. If true, will use the first matching pinned
|
||||
* item. Otherwise, will use the first predicted child
|
||||
* @param message String to be shown inside the arrowView
|
||||
* @return whether suitable child was found and tip was shown
|
||||
*/
|
||||
private boolean showHotseatArrowTip(boolean usePinned, String message) {
|
||||
int childCount = mHotseat.getShortcutsAndWidgets().getChildCount();
|
||||
boolean isPortrait = !mLauncher.getDeviceProfile().isVerticalBarLayout();
|
||||
|
||||
BubbleTextView tipTargetView = null;
|
||||
for (int i = childCount - 1; i > -1; i--) {
|
||||
int x = isPortrait ? i : 0;
|
||||
int y = isPortrait ? 0 : i;
|
||||
View v = mHotseat.getShortcutsAndWidgets().getChildAt(x, y);
|
||||
if (v instanceof BubbleTextView && v.getTag() instanceof WorkspaceItemInfo) {
|
||||
ItemInfo info = (ItemInfo) v.getTag();
|
||||
boolean isPinned = info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT;
|
||||
if (isPinned == usePinned) {
|
||||
tipTargetView = (BubbleTextView) v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tipTargetView == null) {
|
||||
Log.e(TAG, "Unable to find suitable view for ArrowTip");
|
||||
return false;
|
||||
}
|
||||
Rect bounds = mLauncher.getViewBounds(tipTargetView);
|
||||
new ArrowTipView(mLauncher).show(message, Gravity.END, bounds.centerX(), bounds.top);
|
||||
return true;
|
||||
}
|
||||
|
||||
void showDialog() {
|
||||
if (mPredictedApps == null || mPredictedApps.isEmpty()) {
|
||||
return;
|
||||
|
||||
@@ -77,6 +77,11 @@ public class HotseatEduDialog extends AbstractSlideInView<Launcher> implements I
|
||||
mContent = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
setTranslationShift(TRANSLATION_SHIFT_CLOSED);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
@@ -200,9 +205,9 @@ public class HotseatEduDialog extends AbstractSlideInView<Launcher> implements I
|
||||
}
|
||||
AbstractFloatingView.closeAllOpenViews(mActivityContext);
|
||||
attachToContainer();
|
||||
mActivityContext.getStatsLogManager().logger().log(LAUNCHER_HOTSEAT_EDU_SEEN);
|
||||
animateOpen();
|
||||
populatePreview(predictions);
|
||||
mActivityContext.getStatsLogManager().logger().log(LAUNCHER_HOTSEAT_EDU_SEEN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+15
-29
@@ -57,7 +57,6 @@ import com.android.launcher3.uioverrides.PredictedAppIcon;
|
||||
import com.android.launcher3.uioverrides.QuickstepLauncher;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.views.ArrowTipView;
|
||||
import com.android.launcher3.views.Snackbar;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -153,37 +152,14 @@ public class HotseatPredictionController implements DragController.DragListener,
|
||||
*/
|
||||
public void showEdu() {
|
||||
mLauncher.getStateManager().goToState(NORMAL, true, forSuccessCallback(() -> {
|
||||
if (mPredictedItems.isEmpty()) {
|
||||
// launcher has empty predictions set
|
||||
Snackbar.show(mLauncher, R.string.hotsaet_tip_prediction_disabled,
|
||||
R.string.hotseat_prediction_settings, null,
|
||||
() -> mLauncher.startActivity(getSettingsIntent()));
|
||||
} else if (getPredictedIcons().size() >= (mHotSeatItemsCount + 1) / 2) {
|
||||
showDiscoveryTip();
|
||||
} else {
|
||||
HotseatEduController eduController = new HotseatEduController(mLauncher);
|
||||
eduController.setPredictedApps(mPredictedItems.stream()
|
||||
.map(i -> (WorkspaceItemInfo) i)
|
||||
.collect(Collectors.toList()));
|
||||
eduController.showEdu();
|
||||
}
|
||||
HotseatEduController eduController = new HotseatEduController(mLauncher);
|
||||
eduController.setPredictedApps(mPredictedItems.stream()
|
||||
.map(i -> (WorkspaceItemInfo) i)
|
||||
.collect(Collectors.toList()));
|
||||
eduController.showEdu();
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows educational tip for hotseat if user does not go through Tips app.
|
||||
*/
|
||||
private void showDiscoveryTip() {
|
||||
if (getPredictedIcons().isEmpty()) {
|
||||
new ArrowTipView(mLauncher).show(
|
||||
mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop());
|
||||
} else {
|
||||
Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled,
|
||||
R.string.hotseat_prediction_settings, null,
|
||||
() -> mLauncher.startActivity(getSettingsIntent()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if hotseat client has predictions
|
||||
*/
|
||||
@@ -510,6 +486,16 @@ public class HotseatPredictionController implements DragController.DragListener,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when user completes adding item requiring a config activity to the hotseat
|
||||
*/
|
||||
public void onDeferredDrop(int cellX, int cellY) {
|
||||
View child = mHotseat.getChildAt(cellX, cellY);
|
||||
if (child instanceof PredictedAppIcon) {
|
||||
removeIconWithoutNotify((PredictedAppIcon) child);
|
||||
}
|
||||
}
|
||||
|
||||
private class PinPrediction extends SystemShortcut<QuickstepLauncher> {
|
||||
|
||||
private PinPrediction(QuickstepLauncher target, ItemInfo itemInfo) {
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.launcher3.uioverrides;
|
||||
|
||||
import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED;
|
||||
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
|
||||
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
|
||||
@@ -69,6 +70,7 @@ import com.android.launcher3.uioverrides.touchcontrollers.TransposedQuickSwitchT
|
||||
import com.android.launcher3.uioverrides.touchcontrollers.TwoButtonNavbarTouchController;
|
||||
import com.android.launcher3.util.ItemInfoMatcher;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.PendingRequestArgs;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.launcher3.util.UiThreadHelper;
|
||||
import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
|
||||
@@ -138,6 +140,15 @@ public class QuickstepLauncher extends BaseQuickstepLauncher {
|
||||
mHotseatPredictionController.logLaunchedAppRankingInfo(info, instanceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void completeAddShortcut(Intent data, int container, int screenId, int cellX,
|
||||
int cellY, PendingRequestArgs args) {
|
||||
if (container == CONTAINER_HOTSEAT) {
|
||||
mHotseatPredictionController.onDeferredDrop(cellX, cellY);
|
||||
}
|
||||
super.completeAddShortcut(data, container, screenId, cellX, cellY, args);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LauncherAccessibilityDelegate createAccessibilityDelegate() {
|
||||
return new QuickstepAccessibilityDelegate(this);
|
||||
|
||||
@@ -2725,7 +2725,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (showAsGrid) {
|
||||
dismissedTaskWidth = dismissedTaskView.getLayoutParams().width + mPageSpacing;
|
||||
isFocusedTaskDismissed = dismissedTaskViewId == mFocusedTaskViewId;
|
||||
if (isFocusedTaskDismissed) {
|
||||
if (isFocusedTaskDismissed && !isSplitSelectionActive()) {
|
||||
nextFocusedTaskFromTop =
|
||||
mTopRowIdSet.size() > 0 && mTopRowIdSet.size() >= (taskCount - 1) / 2f;
|
||||
// Pick the next focused task from the preferred row.
|
||||
@@ -2908,7 +2908,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
} else if (child instanceof TaskView) {
|
||||
TaskView taskView = (TaskView) child;
|
||||
if (isFocusedTaskDismissed) {
|
||||
if (!isSameGridRow(taskView, nextFocusedTaskView)) {
|
||||
if (nextFocusedTaskView != null &&
|
||||
!isSameGridRow(taskView, nextFocusedTaskView)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
@@ -2945,7 +2946,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
clampToProgress(LINEAR, 0f, ANIMATION_DISMISS_PROGRESS_MIDPOINT));
|
||||
} else {
|
||||
float primaryTranslation =
|
||||
isFocusedTaskDismissed ? nextFocusedTaskWidth : dismissedTaskWidth;
|
||||
nextFocusedTaskView != null ? nextFocusedTaskWidth : dismissedTaskWidth;
|
||||
anim.setFloat(taskView, taskView.getPrimaryDismissTranslationProperty(),
|
||||
mIsRtl ? primaryTranslation : -primaryTranslation,
|
||||
clampToProgress(LINEAR, animationStartProgress,
|
||||
@@ -3255,7 +3256,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// Never enough space on phones
|
||||
return true;
|
||||
} else if (!mActivity.getDeviceProfile().isLandscape) {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect splitBounds = new Rect();
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
<dimen name="widget_handle_margin">13dp</dimen>
|
||||
<dimen name="resize_frame_background_padding">24dp</dimen>
|
||||
<dimen name="resize_frame_margin">22dp</dimen>
|
||||
<dimen name="resize_frame_invalid_drag_across_two_panel_opacity_margin">24dp</dimen>
|
||||
|
||||
<!-- App widget reconfigure button -->
|
||||
<dimen name="widget_reconfigure_button_corner_radius">14dp</dimen>
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.android.launcher3;
|
||||
|
||||
import static android.appwidget.AppWidgetHostView.getDefaultPaddingForWidget;
|
||||
|
||||
import static com.android.launcher3.CellLayout.SPRING_LOADED_PROGRESS;
|
||||
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_HEIGHT;
|
||||
import static com.android.launcher3.LauncherAnimUtils.LAYOUT_WIDTH;
|
||||
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_RESIZE_COMPLETED;
|
||||
@@ -9,6 +10,8 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH
|
||||
import static com.android.launcher3.views.BaseDragLayer.LAYOUT_X;
|
||||
import static com.android.launcher3.views.BaseDragLayer.LAYOUT_Y;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.PropertyValuesHolder;
|
||||
@@ -29,6 +32,7 @@ import androidx.annotation.Px;
|
||||
|
||||
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
import com.android.launcher3.keyboard.ViewGroupFocusHelper;
|
||||
import com.android.launcher3.logging.InstanceId;
|
||||
import com.android.launcher3.logging.InstanceIdSequence;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
@@ -49,12 +53,14 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
|
||||
private static final String KEY_RECONFIGURABLE_WIDGET_EDUCATION_TIP_SEEN =
|
||||
"launcher.reconfigurable_widget_education_tip_seen";
|
||||
private static final Rect sTmpRect = new Rect();
|
||||
private static final Rect sTmpRect2 = new Rect();
|
||||
|
||||
private static final int HANDLE_COUNT = 4;
|
||||
private static final int INDEX_LEFT = 0;
|
||||
private static final int INDEX_TOP = 1;
|
||||
private static final int INDEX_RIGHT = 2;
|
||||
private static final int INDEX_BOTTOM = 3;
|
||||
private static final float MIN_OPACITY_FOR_CELL_LAYOUT_DURING_INVALID_RESIZE = 0.5f;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private final DragViewStateAnnouncer mStateAnnouncer;
|
||||
@@ -103,6 +109,16 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
|
||||
|
||||
private final InstanceId logInstanceId = new InstanceIdSequence().newInstanceId();
|
||||
|
||||
private final ViewGroupFocusHelper mDragLayerRelativeCoordinateHelper;
|
||||
|
||||
/**
|
||||
* In the two panel UI, it is not possible to resize a widget to cross its host
|
||||
* {@link CellLayout}'s sibling. When this happens, we gradually reduce the opacity of the
|
||||
* sibling {@link CellLayout} from 1f to
|
||||
* {@link #MIN_OPACITY_FOR_CELL_LAYOUT_DURING_INVALID_RESIZE}.
|
||||
*/
|
||||
private final float mDragAcrossTwoPanelOpacityMargin;
|
||||
|
||||
private boolean mLeftBorderActive;
|
||||
private boolean mRightBorderActive;
|
||||
private boolean mTopBorderActive;
|
||||
@@ -149,6 +165,10 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
|
||||
for (int i = 0; i < HANDLE_COUNT; i++) {
|
||||
mSystemGestureExclusionRects.add(new Rect());
|
||||
}
|
||||
|
||||
mDragAcrossTwoPanelOpacityMargin = mLauncher.getResources().getDimensionPixelSize(
|
||||
R.dimen.resize_frame_invalid_drag_across_two_panel_opacity_margin);
|
||||
mDragLayerRelativeCoordinateHelper = new ViewGroupFocusHelper(mLauncher.getDragLayer());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -359,6 +379,37 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
|
||||
lp.y = sTmpRect.top;
|
||||
}
|
||||
|
||||
// Handle invalid resize across CellLayouts in the two panel UI.
|
||||
if (mCellLayout.getParent() instanceof Workspace) {
|
||||
Workspace workspace = (Workspace) mCellLayout.getParent();
|
||||
CellLayout pairedCellLayout = workspace.getScreenPair(mCellLayout);
|
||||
if (pairedCellLayout != null) {
|
||||
Rect focusedCellLayoutBound = sTmpRect;
|
||||
mDragLayerRelativeCoordinateHelper.viewToRect(mCellLayout, focusedCellLayoutBound);
|
||||
Rect resizeFrameBound = sTmpRect2;
|
||||
findViewById(R.id.widget_resize_frame).getGlobalVisibleRect(resizeFrameBound);
|
||||
float progress = 1f;
|
||||
if (workspace.indexOfChild(pairedCellLayout) < workspace.indexOfChild(mCellLayout)
|
||||
&& mDeltaX < 0
|
||||
&& resizeFrameBound.left < focusedCellLayoutBound.left) {
|
||||
// Resize from right to left.
|
||||
progress = (mDragAcrossTwoPanelOpacityMargin + mDeltaX)
|
||||
/ mDragAcrossTwoPanelOpacityMargin;
|
||||
} else if (workspace.indexOfChild(pairedCellLayout)
|
||||
> workspace.indexOfChild(mCellLayout)
|
||||
&& mDeltaX > 0
|
||||
&& resizeFrameBound.right > focusedCellLayoutBound.right) {
|
||||
// Resize from left to right.
|
||||
progress = (mDragAcrossTwoPanelOpacityMargin - mDeltaX)
|
||||
/ mDragAcrossTwoPanelOpacityMargin;
|
||||
}
|
||||
float alpha = Math.max(MIN_OPACITY_FOR_CELL_LAYOUT_DURING_INVALID_RESIZE, progress);
|
||||
float springLoadedProgress = Math.min(1f, 1f - progress);
|
||||
updateInvalidResizeEffect(mCellLayout, pairedCellLayout, alpha,
|
||||
springLoadedProgress);
|
||||
}
|
||||
}
|
||||
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@@ -515,13 +566,24 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
|
||||
}
|
||||
|
||||
final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
|
||||
final CellLayout pairedCellLayout;
|
||||
if (mCellLayout.getParent() instanceof Workspace) {
|
||||
Workspace workspace = (Workspace) mCellLayout.getParent();
|
||||
pairedCellLayout = workspace.getScreenPair(mCellLayout);
|
||||
} else {
|
||||
pairedCellLayout = null;
|
||||
}
|
||||
if (!animate) {
|
||||
lp.width = newWidth;
|
||||
lp.height = newHeight;
|
||||
lp.x = newX;
|
||||
lp.y = newY;
|
||||
for (int i = 0; i < HANDLE_COUNT; i++) {
|
||||
mDragHandles[i].setAlpha(1.0f);
|
||||
mDragHandles[i].setAlpha(1f);
|
||||
}
|
||||
if (pairedCellLayout != null) {
|
||||
updateInvalidResizeEffect(mCellLayout, pairedCellLayout, /* alpha= */ 1f,
|
||||
/* springLoadedProgress= */ 0f);
|
||||
}
|
||||
requestLayout();
|
||||
} else {
|
||||
@@ -538,6 +600,10 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
|
||||
set.play(mFirstFrameAnimatorHelper.addTo(
|
||||
ObjectAnimator.ofFloat(mDragHandles[i], ALPHA, 1f)));
|
||||
}
|
||||
if (pairedCellLayout != null) {
|
||||
updateInvalidResizeEffect(mCellLayout, pairedCellLayout, /* alpha= */ 1f,
|
||||
/* springLoadedProgress= */ 0f, /* animatorSet= */ set);
|
||||
}
|
||||
set.setDuration(SNAP_DURATION);
|
||||
set.start();
|
||||
}
|
||||
@@ -624,6 +690,52 @@ public class AppWidgetResizeFrame extends AbstractFloatingView implements View.O
|
||||
}
|
||||
}
|
||||
|
||||
private void updateInvalidResizeEffect(CellLayout cellLayout, CellLayout pairedCellLayout,
|
||||
float alpha, float springLoadedProgress) {
|
||||
updateInvalidResizeEffect(cellLayout, pairedCellLayout, alpha,
|
||||
springLoadedProgress, /* animatorSet= */ null);
|
||||
}
|
||||
|
||||
private void updateInvalidResizeEffect(CellLayout cellLayout, CellLayout pairedCellLayout,
|
||||
float alpha, float springLoadedProgress, @Nullable AnimatorSet animatorSet) {
|
||||
int childCount = pairedCellLayout.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = pairedCellLayout.getChildAt(i);
|
||||
if (animatorSet != null) {
|
||||
animatorSet.play(
|
||||
mFirstFrameAnimatorHelper.addTo(
|
||||
ObjectAnimator.ofFloat(child, ALPHA, alpha)));
|
||||
} else {
|
||||
child.setAlpha(alpha);
|
||||
}
|
||||
}
|
||||
if (animatorSet != null) {
|
||||
animatorSet.play(mFirstFrameAnimatorHelper.addTo(
|
||||
ObjectAnimator.ofFloat(cellLayout, SPRING_LOADED_PROGRESS,
|
||||
springLoadedProgress)));
|
||||
animatorSet.play(mFirstFrameAnimatorHelper.addTo(
|
||||
ObjectAnimator.ofFloat(pairedCellLayout, SPRING_LOADED_PROGRESS,
|
||||
springLoadedProgress)));
|
||||
} else {
|
||||
cellLayout.setSpringLoadedProgress(springLoadedProgress);
|
||||
pairedCellLayout.setSpringLoadedProgress(springLoadedProgress);
|
||||
}
|
||||
|
||||
boolean shouldShowCellLayoutBorder = springLoadedProgress > 0f;
|
||||
if (animatorSet != null) {
|
||||
animatorSet.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
cellLayout.setIsDragOverlapping(shouldShowCellLayoutBorder);
|
||||
pairedCellLayout.setIsDragOverlapping(shouldShowCellLayoutBorder);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
cellLayout.setIsDragOverlapping(shouldShowCellLayoutBorder);
|
||||
pairedCellLayout.setIsDragOverlapping(shouldShowCellLayoutBorder);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isOfType(int type) {
|
||||
return (type & TYPE_WIDGET_RESIZE_FRAME) != 0;
|
||||
|
||||
@@ -1264,7 +1264,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
*
|
||||
* @param data The intent describing the shortcut.
|
||||
*/
|
||||
private void completeAddShortcut(Intent data, int container, int screenId, int cellX,
|
||||
protected void completeAddShortcut(Intent data, int container, int screenId, int cellX,
|
||||
int cellY, PendingRequestArgs args) {
|
||||
if (args.getRequestCode() != REQUEST_CREATE_SHORTCUT
|
||||
|| args.getPendingIntent().getComponent() == null) {
|
||||
@@ -2128,7 +2128,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
actualIds.add(id);
|
||||
}
|
||||
int firstId = visibleIds.getArray().get(0);
|
||||
int pairId = mWorkspace.getPagePair(firstId);
|
||||
int pairId = mWorkspace.getScreenPair(firstId);
|
||||
// Double check that actual screenIds contains the visibleId, as empty screens are hidden
|
||||
// in single panel.
|
||||
if (actualIds.contains(firstId)) {
|
||||
@@ -2212,7 +2212,7 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
// Some empty pages might have been removed while the phone was in a single panel
|
||||
// mode, so we want to add those empty pages back.
|
||||
IntSet screenIds = IntSet.wrap(orderedScreenIds);
|
||||
orderedScreenIds.forEach(screenId -> screenIds.add(mWorkspace.getPagePair(screenId)));
|
||||
orderedScreenIds.forEach(screenId -> screenIds.add(mWorkspace.getScreenPair(screenId)));
|
||||
orderedScreenIds = screenIds.getArray();
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
public void initParentViews(View parent) {
|
||||
if (mPageIndicatorViewId > -1) {
|
||||
mPageIndicator = parent.findViewById(mPageIndicatorViewId);
|
||||
mPageIndicator.setMarkersCount(getChildCount());
|
||||
mPageIndicator.setMarkersCount(getChildCount() / getPanelCount());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -830,7 +830,7 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
|
||||
|
||||
private void dispatchPageCountChanged() {
|
||||
if (mPageIndicator != null) {
|
||||
mPageIndicator.setMarkersCount(getChildCount());
|
||||
mPageIndicator.setMarkersCount(getChildCount() / getPanelCount());
|
||||
}
|
||||
// This ensures that when children are added, they get the correct transforms / alphas
|
||||
// in accordance with any scroll effects.
|
||||
|
||||
@@ -651,7 +651,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
|
||||
// If the icon was dragged from Hotseat, there is no page pair
|
||||
if (isTwoPanelEnabled() && !(mDragSourceInternal.getParent() instanceof Hotseat)) {
|
||||
int pagePairScreenId = getPagePair(dragObject.dragInfo.screenId);
|
||||
int pagePairScreenId = getScreenPair(dragObject.dragInfo.screenId);
|
||||
CellLayout pagePair = mWorkspaceScreens.get(pagePairScreenId);
|
||||
if (pagePair == null) {
|
||||
// TODO: after http://b/198820019 is fixed, remove this
|
||||
@@ -917,16 +917,33 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the page that is shown together with the given page when two panel is enabled.
|
||||
* Returns the screen ID of a page that is shown together with the given page screen ID when the
|
||||
* two panel UI is enabled.
|
||||
*/
|
||||
public int getPagePair(int page) {
|
||||
if (page % 2 == 0) {
|
||||
return page + 1;
|
||||
public int getScreenPair(int screenId) {
|
||||
if (screenId % 2 == 0) {
|
||||
return screenId + 1;
|
||||
} else {
|
||||
return page - 1;
|
||||
return screenId - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@link CellLayout} that is shown together with the given {@link CellLayout} when the
|
||||
* two panel UI is enabled.
|
||||
*/
|
||||
@Nullable
|
||||
public CellLayout getScreenPair(CellLayout cellLayout) {
|
||||
if (!isTwoPanelEnabled()) {
|
||||
return null;
|
||||
}
|
||||
int screenId = getIdForScreen(cellLayout);
|
||||
if (screenId == -1) {
|
||||
return null;
|
||||
}
|
||||
return getScreenWithId(getScreenPair(screenId));
|
||||
}
|
||||
|
||||
public void stripEmptyScreens() {
|
||||
if (mLauncher.isWorkspaceLoading()) {
|
||||
// Don't strip empty screens if the workspace is still loading.
|
||||
@@ -959,7 +976,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator>
|
||||
Iterator<Integer> removeScreensIterator = removeScreens.iterator();
|
||||
while (removeScreensIterator.hasNext()) {
|
||||
int pageToRemove = removeScreensIterator.next();
|
||||
int pagePair = getPagePair(pageToRemove);
|
||||
int pagePair = getScreenPair(pageToRemove);
|
||||
if (!removeScreens.contains(pagePair)) {
|
||||
// The page pair isn't empty so we want to remove the current page from the
|
||||
// removable pages' collection
|
||||
|
||||
@@ -37,6 +37,7 @@ import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BaseDraggingActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.Interpolators;
|
||||
import com.android.launcher3.dragndrop.DragLayer;
|
||||
@@ -56,6 +57,7 @@ public class ArrowTipView extends AbstractFloatingView {
|
||||
protected final BaseDraggingActivity mActivity;
|
||||
private final Handler mHandler = new Handler();
|
||||
private final int mArrowWidth;
|
||||
private final int mArrowMinOffset;
|
||||
private boolean mIsPointingUp;
|
||||
private Runnable mOnClosed;
|
||||
private View mArrowView;
|
||||
@@ -69,6 +71,8 @@ public class ArrowTipView extends AbstractFloatingView {
|
||||
mActivity = BaseDraggingActivity.fromContext(context);
|
||||
mIsPointingUp = isPointingUp;
|
||||
mArrowWidth = context.getResources().getDimensionPixelSize(R.dimen.arrow_toast_arrow_width);
|
||||
mArrowMinOffset = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.dynamic_grid_cell_border_spacing);
|
||||
init(context);
|
||||
}
|
||||
|
||||
@@ -126,10 +130,10 @@ public class ArrowTipView extends AbstractFloatingView {
|
||||
/**
|
||||
* Show the ArrowTipView (tooltip) center, start, or end aligned.
|
||||
*
|
||||
* @param text The text to be shown in the tooltip.
|
||||
* @param gravity The gravity aligns the tooltip center, start, or end.
|
||||
* @param text The text to be shown in the tooltip.
|
||||
* @param gravity The gravity aligns the tooltip center, start, or end.
|
||||
* @param arrowMarginStart The margin from start to place arrow (ignored if center)
|
||||
* @param top The Y coordinate of the bottom of tooltip.
|
||||
* @param top The Y coordinate of the bottom of tooltip.
|
||||
* @return The tooltip.
|
||||
*/
|
||||
public ArrowTipView show(String text, int gravity, int arrowMarginStart, int top) {
|
||||
@@ -152,23 +156,28 @@ public class ArrowTipView extends AbstractFloatingView {
|
||||
ViewGroup parent = mActivity.getDragLayer();
|
||||
parent.addView(this);
|
||||
|
||||
DeviceProfile grid = mActivity.getDeviceProfile();
|
||||
|
||||
DragLayer.LayoutParams params = (DragLayer.LayoutParams) getLayoutParams();
|
||||
params.gravity = gravity;
|
||||
params.leftMargin = mArrowMinOffset + grid.getInsets().left;
|
||||
params.rightMargin = mArrowMinOffset + grid.getInsets().right;
|
||||
LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mArrowView.getLayoutParams();
|
||||
|
||||
lp.gravity = gravity;
|
||||
|
||||
if (parent.getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
|
||||
arrowMarginStart = parent.getMeasuredWidth() - arrowMarginStart;
|
||||
}
|
||||
if (gravity == Gravity.END) {
|
||||
lp.setMarginEnd(parent.getMeasuredWidth() - arrowMarginStart - mArrowWidth);
|
||||
lp.setMarginEnd(Math.max(mArrowMinOffset,
|
||||
parent.getMeasuredWidth() - params.rightMargin - arrowMarginStart
|
||||
- mArrowWidth / 2));
|
||||
} else if (gravity == Gravity.START) {
|
||||
lp.setMarginStart(arrowMarginStart - mArrowWidth / 2);
|
||||
lp.setMarginStart(Math.max(mArrowMinOffset,
|
||||
arrowMarginStart - params.leftMargin - mArrowWidth / 2));
|
||||
}
|
||||
requestLayout();
|
||||
|
||||
params.leftMargin = mActivity.getDeviceProfile().workspacePadding.left;
|
||||
params.rightMargin = mActivity.getDeviceProfile().workspacePadding.right;
|
||||
post(() -> setY(top - (mIsPointingUp ? 0 : getHeight())));
|
||||
|
||||
mIsOpen = true;
|
||||
|
||||
Reference in New Issue
Block a user