Merge changes from topic "allapps_bottomsheet_motion" into tm-dev
* changes: Tune AllApps bottom sheet VisD and motion Put taskbar all apps in separate overlay window and stash taskbar.
This commit is contained in:
@@ -14,12 +14,12 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<com.android.launcher3.taskbar.TaskbarAllAppsSlideInView
|
||||
<com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.android.launcher3.taskbar.TaskbarAllAppsContainerView
|
||||
<com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView
|
||||
android:id="@+id/apps_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
@@ -52,5 +52,5 @@
|
||||
</com.android.launcher3.allapps.FloatingHeaderView>
|
||||
|
||||
<include layout="@layout/all_apps_fast_scroller" />
|
||||
</com.android.launcher3.taskbar.TaskbarAllAppsContainerView>
|
||||
</com.android.launcher3.taskbar.TaskbarAllAppsSlideInView>
|
||||
</com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView>
|
||||
</com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView>
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.LayoutInflater;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
|
||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
// TODO(b/218912746): Share more behavior to avoid all apps context depending directly on taskbar.
|
||||
/** Base for common behavior between taskbar window contexts. */
|
||||
public abstract class BaseTaskbarContext extends ContextThemeWrapper implements ActivityContext,
|
||||
DeviceProfileListenable {
|
||||
|
||||
protected final LayoutInflater mLayoutInflater;
|
||||
private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
|
||||
|
||||
protected DeviceProfile mDeviceProfile;
|
||||
|
||||
public BaseTaskbarContext(Context windowContext) {
|
||||
super(windowContext, Themes.getActivityThemeRes(windowContext));
|
||||
mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final LayoutInflater getLayoutInflater() {
|
||||
return mLayoutInflater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final DeviceProfile getDeviceProfile() {
|
||||
return mDeviceProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners() {
|
||||
return mDPChangeListeners;
|
||||
}
|
||||
|
||||
/** Updates the {@link DeviceProfile} instance to the latest representation of the screen. */
|
||||
public abstract void updateDeviceProfile(DeviceProfile dp);
|
||||
|
||||
/** Callback invoked when a drag is initiated within this context. */
|
||||
public abstract void onDragStart();
|
||||
|
||||
/** Callback invoked when a popup is shown or closed within this context. */
|
||||
public abstract void onPopupVisibilityChanged(boolean isVisible);
|
||||
}
|
||||
@@ -42,10 +42,8 @@ import android.os.Process;
|
||||
import android.os.SystemProperties;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.Display;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.RoundedCorner;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
@@ -58,11 +56,8 @@ import androidx.annotation.Nullable;
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DeviceProfile.DeviceProfileListenable;
|
||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||
import com.android.launcher3.LauncherSettings.Favorites;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.dot.DotInfo;
|
||||
import com.android.launcher3.folder.Folder;
|
||||
import com.android.launcher3.folder.FolderIcon;
|
||||
@@ -72,11 +67,10 @@ import com.android.launcher3.model.data.FolderInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
import com.android.launcher3.popup.PopupDataProvider;
|
||||
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
|
||||
import com.android.launcher3.touch.ItemClickHandler;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.PackageManagerHelper;
|
||||
import com.android.launcher3.util.SettingsCache;
|
||||
import com.android.launcher3.util.Themes;
|
||||
import com.android.launcher3.util.TraceHelper;
|
||||
import com.android.launcher3.util.ViewCache;
|
||||
import com.android.launcher3.views.ActivityContext;
|
||||
@@ -89,16 +83,13 @@ import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements
|
||||
* that are used by both Launcher and Taskbar (such as Folder) to reference a generic
|
||||
* ActivityContext and BaseDragLayer instead of the Launcher activity and its DragLayer.
|
||||
*/
|
||||
public class TaskbarActivityContext extends ContextThemeWrapper implements ActivityContext,
|
||||
DeviceProfileListenable {
|
||||
public class TaskbarActivityContext extends BaseTaskbarContext {
|
||||
|
||||
private static final boolean ENABLE_THREE_BUTTON_TASKBAR =
|
||||
SystemProperties.getBoolean("persist.debug.taskbar_three_button", false);
|
||||
@@ -106,13 +97,8 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
|
||||
private static final String WINDOW_TITLE = "Taskbar";
|
||||
|
||||
private final LayoutInflater mLayoutInflater;
|
||||
private final TaskbarDragLayer mDragLayer;
|
||||
private final TaskbarAllAppsContainerView mAppsView;
|
||||
private final TaskbarControllers mControllers;
|
||||
private final List<OnDeviceProfileChangeListener> mDPChangeListeners = new ArrayList<>();
|
||||
|
||||
private DeviceProfile mDeviceProfile;
|
||||
|
||||
private final WindowManager mWindowManager;
|
||||
private final @Nullable RoundedCorner mLeftCorner, mRightCorner;
|
||||
@@ -135,14 +121,12 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
private boolean mBindingItems = false;
|
||||
|
||||
private final TaskbarShortcutMenuAccessibilityDelegate mAccessibilityDelegate;
|
||||
private final OnboardingPrefs<TaskbarActivityContext> mOnboardingPrefs;
|
||||
|
||||
public TaskbarActivityContext(Context windowContext, DeviceProfile dp,
|
||||
TaskbarNavButtonController buttonController, ScopedUnfoldTransitionProgressProvider
|
||||
unfoldTransitionProgressProvider) {
|
||||
super(windowContext, Themes.getActivityThemeRes(windowContext));
|
||||
super(windowContext);
|
||||
mDeviceProfile = dp;
|
||||
mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
|
||||
|
||||
mNavMode = SysUINavigationMode.getMode(windowContext);
|
||||
mImeDrawsImeNavBar = SysUINavigationMode.getImeDrawsImeNavBar(windowContext);
|
||||
@@ -158,8 +142,6 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
|
||||
mTaskbarHeightForIme = resources.getDimensionPixelSize(R.dimen.taskbar_ime_size);
|
||||
|
||||
mLayoutInflater = LayoutInflater.from(this).cloneInContext(this);
|
||||
|
||||
// Inflate views.
|
||||
mDragLayer = (TaskbarDragLayer) mLayoutInflater.inflate(
|
||||
R.layout.taskbar, null, false);
|
||||
@@ -168,11 +150,6 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
FrameLayout navButtonsView = mDragLayer.findViewById(R.id.navbuttons_view);
|
||||
StashedHandleView stashedHandleView = mDragLayer.findViewById(R.id.stashed_handle);
|
||||
|
||||
TaskbarAllAppsSlideInView appsSlideInView =
|
||||
(TaskbarAllAppsSlideInView) mLayoutInflater.inflate(R.layout.taskbar_all_apps,
|
||||
mDragLayer, false);
|
||||
mAppsView = appsSlideInView.getAppsView();
|
||||
|
||||
Display display = windowContext.getDisplay();
|
||||
Context c = display.getDisplayId() == Display.DEFAULT_DISPLAY
|
||||
? windowContext.getApplicationContext()
|
||||
@@ -210,7 +187,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
new TaskbarAutohideSuspendController(this),
|
||||
new TaskbarPopupController(this),
|
||||
new TaskbarForceVisibleImmersiveController(this),
|
||||
new TaskbarAllAppsViewController(this, appsSlideInView));
|
||||
new TaskbarAllAppsController(this));
|
||||
}
|
||||
|
||||
public void init(TaskbarSharedState sharedState) {
|
||||
@@ -236,7 +213,7 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
mWindowManager.addView(mDragLayer, mWindowLayoutParams);
|
||||
}
|
||||
|
||||
/** Updates the Device profile instance to the latest representation of the screen. */
|
||||
@Override
|
||||
public void updateDeviceProfile(DeviceProfile dp) {
|
||||
mDeviceProfile = dp;
|
||||
updateIconSize(getResources());
|
||||
@@ -296,31 +273,11 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
return mRightCorner == null ? 0 : mRightCorner.getRadius();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LayoutInflater getLayoutInflater() {
|
||||
return mLayoutInflater;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskbarDragLayer getDragLayer() {
|
||||
return mDragLayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskbarAllAppsContainerView getAppsView() {
|
||||
return mAppsView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DeviceProfile getDeviceProfile() {
|
||||
return mDeviceProfile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OnDeviceProfileChangeListener> getOnDeviceProfileChangeListeners() {
|
||||
return mDPChangeListeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Rect getFolderBoundingBox() {
|
||||
return mControllers.taskbarDragLayerController.getFolderBoundingBox();
|
||||
@@ -411,11 +368,6 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
return mAccessibilityDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OnboardingPrefs<TaskbarActivityContext> getOnboardingPrefs() {
|
||||
return mOnboardingPrefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBindingItems() {
|
||||
return mBindingItems;
|
||||
@@ -425,6 +377,16 @@ public class TaskbarActivityContext extends ContextThemeWrapper implements Activ
|
||||
mBindingItems = bindingItems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragStart() {
|
||||
setTaskbarWindowFullscreen(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPopupVisibilityChanged(boolean isVisible) {
|
||||
setTaskbarWindowFocusable(isVisible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a new data-source for this taskbar instance
|
||||
*/
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
|
||||
|
||||
import com.android.launcher3.appprediction.AppsDividerView;
|
||||
import com.android.launcher3.appprediction.PredictionRowView;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/** Handles the {@link TaskbarAllAppsContainerView} initialization and updates. */
|
||||
public final class TaskbarAllAppsViewController {
|
||||
|
||||
private final TaskbarActivityContext mContext;
|
||||
private final TaskbarAllAppsSlideInView mSlideInView;
|
||||
private final TaskbarAllAppsContainerView mAppsView;
|
||||
|
||||
public TaskbarAllAppsViewController(
|
||||
TaskbarActivityContext context, TaskbarAllAppsSlideInView slideInView) {
|
||||
mContext = context;
|
||||
mSlideInView = slideInView;
|
||||
mAppsView = mSlideInView.getAppsView();
|
||||
}
|
||||
|
||||
/** Initialize the controller. */
|
||||
public void init(TaskbarControllers controllers) {
|
||||
if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mAppsView.setOnIconLongClickListener(
|
||||
controllers.taskbarDragController::startDragOnLongClick);
|
||||
mAppsView.getFloatingHeaderView().findFixedRowByType(
|
||||
PredictionRowView.class).setOnIconLongClickListener(
|
||||
controllers.taskbarDragController::startDragOnLongClick);
|
||||
}
|
||||
|
||||
/** Binds the current {@link AppInfo} instances to the {@link TaskbarAllAppsContainerView}. */
|
||||
public void setApps(AppInfo[] apps, int flags) {
|
||||
if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
|
||||
mAppsView.getAppsStore().setApps(apps, flags);
|
||||
}
|
||||
}
|
||||
|
||||
/** Binds the current app predictions to all apps {@link PredictionRowView}. */
|
||||
public void setPredictedApps(List<ItemInfo> predictedApps) {
|
||||
if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
|
||||
PredictionRowView<?> predictionRowView =
|
||||
mAppsView.getFloatingHeaderView().findFixedRowByType(PredictionRowView.class);
|
||||
predictionRowView.setPredictedApps(predictedApps);
|
||||
}
|
||||
}
|
||||
|
||||
/** Opens the {@link TaskbarAllAppsContainerView}. */
|
||||
public void show() {
|
||||
if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mAppsView.getFloatingHeaderView().findFixedRowByType(AppsDividerView.class)
|
||||
.setShowAllAppsLabel(
|
||||
!mContext.getOnboardingPrefs().hasReachedMaxCount(ALL_APPS_VISITED_COUNT));
|
||||
mContext.getOnboardingPrefs().incrementEventCount(ALL_APPS_VISITED_COUNT);
|
||||
mContext.setTaskbarWindowFullscreen(true);
|
||||
mSlideInView.show();
|
||||
}
|
||||
}
|
||||
@@ -20,6 +20,7 @@ import android.content.pm.ActivityInfo.Config;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController;
|
||||
import com.android.systemui.shared.rotation.RotationButtonController;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -48,7 +49,7 @@ public class TaskbarControllers {
|
||||
public final TaskbarAutohideSuspendController taskbarAutohideSuspendController;
|
||||
public final TaskbarPopupController taskbarPopupController;
|
||||
public final TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController;
|
||||
public final TaskbarAllAppsViewController taskbarAllAppsViewController;
|
||||
public final TaskbarAllAppsController taskbarAllAppsController;
|
||||
|
||||
@Nullable private LoggableTaskbarController[] mControllersToLog = null;
|
||||
|
||||
@@ -74,7 +75,7 @@ public class TaskbarControllers {
|
||||
TaskbarAutohideSuspendController taskbarAutoHideSuspendController,
|
||||
TaskbarPopupController taskbarPopupController,
|
||||
TaskbarForceVisibleImmersiveController taskbarForceVisibleImmersiveController,
|
||||
TaskbarAllAppsViewController taskbarAllAppsViewController) {
|
||||
TaskbarAllAppsController taskbarAllAppsController) {
|
||||
this.taskbarActivityContext = taskbarActivityContext;
|
||||
this.taskbarDragController = taskbarDragController;
|
||||
this.navButtonController = navButtonController;
|
||||
@@ -91,7 +92,7 @@ public class TaskbarControllers {
|
||||
this.taskbarAutohideSuspendController = taskbarAutoHideSuspendController;
|
||||
this.taskbarPopupController = taskbarPopupController;
|
||||
this.taskbarForceVisibleImmersiveController = taskbarForceVisibleImmersiveController;
|
||||
this.taskbarAllAppsViewController = taskbarAllAppsViewController;
|
||||
this.taskbarAllAppsController = taskbarAllAppsController;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,7 +116,7 @@ public class TaskbarControllers {
|
||||
taskbarEduController.init(this);
|
||||
taskbarPopupController.init(this);
|
||||
taskbarForceVisibleImmersiveController.init(this);
|
||||
taskbarAllAppsViewController.init(this);
|
||||
taskbarAllAppsController.init(this);
|
||||
|
||||
mControllersToLog = new LoggableTaskbarController[] {
|
||||
taskbarDragController, navButtonController, navbarButtonsViewController,
|
||||
|
||||
@@ -75,7 +75,7 @@ import java.util.Arrays;
|
||||
/**
|
||||
* Handles long click on Taskbar items to start a system drag and drop operation.
|
||||
*/
|
||||
public class TaskbarDragController extends DragController<TaskbarActivityContext> implements
|
||||
public class TaskbarDragController extends DragController<BaseTaskbarContext> implements
|
||||
TaskbarControllers.LoggableTaskbarController {
|
||||
|
||||
private static boolean DEBUG_DRAG_SHADOW_SURFACE = false;
|
||||
@@ -95,7 +95,7 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
|
||||
// Animation for the drag shadow back into position after an unsuccessful drag
|
||||
private ValueAnimator mReturnAnimator;
|
||||
|
||||
public TaskbarDragController(TaskbarActivityContext activity) {
|
||||
public TaskbarDragController(BaseTaskbarContext activity) {
|
||||
super(activity);
|
||||
Resources resources = mActivity.getResources();
|
||||
mDragIconSize = resources.getDimensionPixelSize(R.dimen.taskbar_icon_drag_icon_size);
|
||||
@@ -110,7 +110,7 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
|
||||
* generate the ClipDescription and Intent.
|
||||
* @return Whether {@link View#startDragAndDrop} started successfully.
|
||||
*/
|
||||
protected boolean startDragOnLongClick(View view) {
|
||||
public boolean startDragOnLongClick(View view) {
|
||||
return startDragOnLongClick(view, null, null);
|
||||
}
|
||||
|
||||
@@ -131,8 +131,7 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
|
||||
}
|
||||
|
||||
BubbleTextView btv = (BubbleTextView) view;
|
||||
|
||||
mActivity.setTaskbarWindowFullscreen(true);
|
||||
mActivity.onDragStart();
|
||||
btv.post(() -> {
|
||||
DragView dragView = startInternalDrag(btv, dragPreviewProvider);
|
||||
if (iconShift != null) {
|
||||
@@ -185,7 +184,7 @@ public class TaskbarDragController extends DragController<TaskbarActivityContext
|
||||
}
|
||||
};
|
||||
if (FeatureFlags.ENABLE_TASKBAR_POPUP_MENU.get()) {
|
||||
PopupContainerWithArrow<TaskbarActivityContext> popupContainer =
|
||||
PopupContainerWithArrow<BaseTaskbarContext> popupContainer =
|
||||
mControllers.taskbarPopupController.showForIcon(btv);
|
||||
if (popupContainer != null) {
|
||||
dragOptions.preDragCondition = popupContainer.createPreDragCondition(false);
|
||||
|
||||
@@ -25,8 +25,8 @@ import com.android.launcher3.dragndrop.DragView;
|
||||
* while the pre-drag is still in progress (i.e. when the long press popup is still open). After
|
||||
* that ends, we switch to a system drag and drop view instead.
|
||||
*/
|
||||
public class TaskbarDragView extends DragView<TaskbarActivityContext> {
|
||||
public TaskbarDragView(TaskbarActivityContext launcher, Drawable drawable, int registrationX,
|
||||
public class TaskbarDragView extends DragView<BaseTaskbarContext> {
|
||||
public TaskbarDragView(BaseTaskbarContext launcher, Drawable drawable, int registrationX,
|
||||
int registrationY, float initialScale, float scaleOnDrop, float finalScaleDps) {
|
||||
super(launcher, drawable, registrationX, registrationY, initialScale, scaleOnDrop,
|
||||
finalScaleDps);
|
||||
|
||||
@@ -158,7 +158,7 @@ public class TaskbarModelCallbacks implements
|
||||
mPredictedItems = item.items;
|
||||
commitItemsToUI();
|
||||
} else if (item.containerId == Favorites.CONTAINER_PREDICTION) {
|
||||
mControllers.taskbarAllAppsViewController.setPredictedApps(item.items);
|
||||
mControllers.taskbarAllAppsController.setPredictedApps(item.items);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ public class TaskbarModelCallbacks implements
|
||||
|
||||
@Override
|
||||
public void bindAllApplications(AppInfo[] apps, int flags) {
|
||||
mControllers.taskbarAllAppsViewController.setApps(apps, flags);
|
||||
mControllers.taskbarAllAppsController.setApps(apps, flags);
|
||||
}
|
||||
|
||||
protected void dumpLogs(String prefix, PrintWriter pw) {
|
||||
|
||||
@@ -52,7 +52,7 @@ import java.util.stream.Stream;
|
||||
*/
|
||||
public class TaskbarPopupController implements TaskbarControllers.LoggableTaskbarController {
|
||||
|
||||
private static final SystemShortcut.Factory<TaskbarActivityContext>
|
||||
private static final SystemShortcut.Factory<BaseTaskbarContext>
|
||||
APP_INFO = SystemShortcut.AppInfo::new;
|
||||
|
||||
private final TaskbarActivityContext mContext;
|
||||
@@ -121,8 +121,8 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
* Shows the notifications and deep shortcuts associated with a Taskbar {@param icon}.
|
||||
* @return the container if shown or null.
|
||||
*/
|
||||
public PopupContainerWithArrow<TaskbarActivityContext> showForIcon(BubbleTextView icon) {
|
||||
TaskbarActivityContext context = ActivityContext.lookupContext(icon.getContext());
|
||||
public PopupContainerWithArrow<BaseTaskbarContext> showForIcon(BubbleTextView icon) {
|
||||
BaseTaskbarContext context = ActivityContext.lookupContext(icon.getContext());
|
||||
if (PopupContainerWithArrow.getOpen(context) != null) {
|
||||
// There is already an items container open, so don't open this one.
|
||||
icon.clearFocus();
|
||||
@@ -133,11 +133,11 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
return null;
|
||||
}
|
||||
|
||||
final PopupContainerWithArrow<TaskbarActivityContext> container =
|
||||
(PopupContainerWithArrow) context.getLayoutInflater().inflate(
|
||||
final PopupContainerWithArrow<BaseTaskbarContext> container =
|
||||
(PopupContainerWithArrow<BaseTaskbarContext>) context.getLayoutInflater().inflate(
|
||||
R.layout.popup_container, context.getDragLayer(), false);
|
||||
container.addOnAttachStateChangeListener(
|
||||
new PopupLiveUpdateHandler<TaskbarActivityContext>(mContext, container) {
|
||||
new PopupLiveUpdateHandler<BaseTaskbarContext>(context, container) {
|
||||
@Override
|
||||
protected void showPopupContainerForIcon(BubbleTextView originalIcon) {
|
||||
showForIcon(originalIcon);
|
||||
@@ -157,10 +157,9 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
container.requestFocus();
|
||||
|
||||
// Make focusable to receive back events
|
||||
mControllers.taskbarActivityContext.setTaskbarWindowFocusable(true);
|
||||
context.onPopupVisibilityChanged(true);
|
||||
container.setOnCloseCallback(() -> {
|
||||
mControllers.taskbarActivityContext.getDragLayer().post(
|
||||
() -> mControllers.taskbarActivityContext.setTaskbarWindowFocusable(false));
|
||||
context.getDragLayer().post(() -> context.onPopupVisibilityChanged(false));
|
||||
container.setOnCloseCallback(null);
|
||||
});
|
||||
|
||||
@@ -207,7 +206,8 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba
|
||||
iconShift.x = mIconLastTouchPos.x - sv.getIconCenter().x;
|
||||
iconShift.y = mIconLastTouchPos.y - mContext.getDeviceProfile().iconSizePx;
|
||||
|
||||
mControllers.taskbarDragController.startDragOnLongClick(sv, iconShift);
|
||||
((TaskbarDragController) ActivityContext.lookupContext(
|
||||
v.getContext()).getDragController()).startDragOnLongClick(sv, iconShift);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -51,11 +51,12 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 4; // setup wizard and AllSetActivity
|
||||
public static final int FLAG_STASHED_IN_APP_IME = 1 << 5; // IME is visible
|
||||
public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 6;
|
||||
public static final int FLAG_STASHED_IN_APP_ALL_APPS = 1 << 7; // All apps is visible.
|
||||
|
||||
// If we're in an app and any of these flags are enabled, taskbar should be stashed.
|
||||
private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
|
||||
| FLAG_STASHED_IN_APP_PINNED | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP
|
||||
| FLAG_STASHED_IN_APP_IME;
|
||||
| FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_APP_ALL_APPS;
|
||||
|
||||
// If any of these flags are enabled, inset apps by our stashed height instead of our unstashed
|
||||
// height. This way the reported insets are consistent even during transitions out of the app.
|
||||
@@ -585,6 +586,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba
|
||||
str.add((flags & FLAG_STASHED_IN_APP_IME) != 0 ? "FLAG_STASHED_IN_APP_IME" : "");
|
||||
str.add((flags & FLAG_IN_STASHED_LAUNCHER_STATE) != 0
|
||||
? "FLAG_IN_STASHED_LAUNCHER_STATE" : "");
|
||||
str.add((flags & FLAG_STASHED_IN_APP_ALL_APPS) != 0 ? "FLAG_STASHED_IN_APP_ALL_APPS" : "");
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +306,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar
|
||||
}
|
||||
|
||||
public View.OnClickListener getAllAppsButtonClickListener() {
|
||||
return v -> mControllers.taskbarAllAppsViewController.show();
|
||||
return v -> mControllers.taskbarAllAppsController.show();
|
||||
}
|
||||
|
||||
public View.OnLongClickListener getIconOnLongClickListener() {
|
||||
|
||||
+5
-9
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
package com.android.launcher3.taskbar.allapps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
@@ -29,10 +29,7 @@ import com.android.launcher3.allapps.BaseAllAppsContainerView;
|
||||
import com.android.launcher3.allapps.search.SearchAdapterProvider;
|
||||
|
||||
/** All apps container accessible from taskbar. */
|
||||
public class TaskbarAllAppsContainerView extends BaseAllAppsContainerView<TaskbarActivityContext> {
|
||||
public TaskbarAllAppsContainerView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
public class TaskbarAllAppsContainerView extends BaseAllAppsContainerView<TaskbarAllAppsContext> {
|
||||
|
||||
public TaskbarAllAppsContainerView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
@@ -44,8 +41,8 @@ public class TaskbarAllAppsContainerView extends BaseAllAppsContainerView<Taskba
|
||||
|
||||
@Override
|
||||
protected SearchAdapterProvider<?> createMainAdapterProvider() {
|
||||
// Task bar all apps does not yet support search, so this implementation is minimal.
|
||||
return new SearchAdapterProvider<TaskbarActivityContext>(mActivityContext) {
|
||||
// Taskbar all apps does not yet support search, so this implementation is minimal.
|
||||
return new SearchAdapterProvider<TaskbarAllAppsContext>(mActivityContext) {
|
||||
@Override
|
||||
public boolean launchHighlightedItem() {
|
||||
return false;
|
||||
@@ -79,8 +76,7 @@ public class TaskbarAllAppsContainerView extends BaseAllAppsContainerView<Taskba
|
||||
|
||||
@Override
|
||||
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
|
||||
// TODO(b/204696617): Switch to status bar insets once they work.
|
||||
setInsets(insets.getInsets(WindowInsets.Type.tappableElement()).toRect());
|
||||
setInsets(insets.getInsets(WindowInsets.Type.systemBars()).toRect());
|
||||
return super.onApplyWindowInsets(insets);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.taskbar.allapps;
|
||||
|
||||
import static android.view.KeyEvent.ACTION_UP;
|
||||
import static android.view.KeyEvent.KEYCODE_BACK;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.dot.DotInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.popup.PopupDataProvider;
|
||||
import com.android.launcher3.taskbar.BaseTaskbarContext;
|
||||
import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
import com.android.launcher3.taskbar.TaskbarDragController;
|
||||
import com.android.launcher3.taskbar.TaskbarStashController;
|
||||
import com.android.launcher3.util.OnboardingPrefs;
|
||||
import com.android.launcher3.util.TouchController;
|
||||
import com.android.launcher3.views.BaseDragLayer;
|
||||
|
||||
/**
|
||||
* Window context for the taskbar all apps overlay.
|
||||
* <p>
|
||||
* All apps has its own window and needs a window context. Some properties are delegated to the
|
||||
* {@link TaskbarActivityContext} such as {@link DeviceProfile} and {@link PopupDataProvider}.
|
||||
*/
|
||||
class TaskbarAllAppsContext extends BaseTaskbarContext {
|
||||
private final TaskbarActivityContext mTaskbarContext;
|
||||
private final OnboardingPrefs<TaskbarAllAppsContext> mOnboardingPrefs;
|
||||
|
||||
private final TaskbarAllAppsViewController mAllAppsViewController;
|
||||
private final TaskbarDragController mDragController;
|
||||
private final TaskbarAllAppsDragLayer mDragLayer;
|
||||
private final TaskbarAllAppsContainerView mAppsView;
|
||||
|
||||
TaskbarAllAppsContext(
|
||||
TaskbarActivityContext taskbarContext,
|
||||
TaskbarAllAppsController windowController,
|
||||
TaskbarStashController taskbarStashController) {
|
||||
super(taskbarContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null));
|
||||
mTaskbarContext = taskbarContext;
|
||||
mDeviceProfile = taskbarContext.getDeviceProfile();
|
||||
mDragController = new TaskbarDragController(this);
|
||||
mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
|
||||
|
||||
mDragLayer = new TaskbarAllAppsDragLayer(this);
|
||||
TaskbarAllAppsSlideInView slideInView = (TaskbarAllAppsSlideInView) mLayoutInflater.inflate(
|
||||
R.layout.taskbar_all_apps, mDragLayer, false);
|
||||
mAllAppsViewController = new TaskbarAllAppsViewController(
|
||||
this,
|
||||
slideInView,
|
||||
windowController,
|
||||
taskbarStashController);
|
||||
mAppsView = slideInView.getAppsView();
|
||||
}
|
||||
|
||||
TaskbarAllAppsViewController getAllAppsViewController() {
|
||||
return mAllAppsViewController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskbarDragController getDragController() {
|
||||
return mDragController;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskbarAllAppsDragLayer getDragLayer() {
|
||||
return mDragLayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskbarAllAppsContainerView getAppsView() {
|
||||
return mAppsView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OnboardingPrefs<TaskbarAllAppsContext> getOnboardingPrefs() {
|
||||
return mOnboardingPrefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBindingItems() {
|
||||
return mTaskbarContext.isBindingItems();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View.OnClickListener getItemOnClickListener() {
|
||||
return mTaskbarContext.getItemOnClickListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PopupDataProvider getPopupDataProvider() {
|
||||
return mTaskbarContext.getPopupDataProvider();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DotInfo getDotInfoForItem(ItemInfo info) {
|
||||
return mTaskbarContext.getDotInfoForItem(info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateDeviceProfile(DeviceProfile dp) {
|
||||
mDeviceProfile = dp;
|
||||
dispatchDeviceProfileChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragStart() {}
|
||||
|
||||
@Override
|
||||
public void onPopupVisibilityChanged(boolean isVisible) {}
|
||||
|
||||
/** Root drag layer for this context. */
|
||||
private static class TaskbarAllAppsDragLayer extends BaseDragLayer<TaskbarAllAppsContext> {
|
||||
|
||||
private TaskbarAllAppsDragLayer(Context context) {
|
||||
super(context, null, 1);
|
||||
setClipChildren(false);
|
||||
recreateControllers();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
mActivity.mAllAppsViewController.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recreateControllers() {
|
||||
mControllers = new TouchController[]{mActivity.mDragController};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchKeyEvent(KeyEvent event) {
|
||||
if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) {
|
||||
AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity);
|
||||
if (topView != null && topView.onBackPressed()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return super.dispatchKeyEvent(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.taskbar.allapps;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowManager.LayoutParams;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.AbstractFloatingView;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener;
|
||||
import com.android.launcher3.appprediction.PredictionRowView;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.model.data.AppInfo;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.taskbar.TaskbarActivityContext;
|
||||
import com.android.launcher3.taskbar.TaskbarControllers;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Handles the all apps overlay window initialization, updates, and its data.
|
||||
* <p>
|
||||
* All apps is in an application overlay window instead of taskbar's navigation bar panel window,
|
||||
* because a navigation bar panel is higher than UI components that all apps should be below such as
|
||||
* the notification tray.
|
||||
* <p>
|
||||
* The all apps window is created and destroyed upon opening and closing all apps, respectively.
|
||||
* Application data may be bound while the window does not exist, so this controller will store
|
||||
* the models for the next all apps session.
|
||||
*/
|
||||
public final class TaskbarAllAppsController implements OnDeviceProfileChangeListener {
|
||||
|
||||
private static final String WINDOW_TITLE = "Taskbar All Apps";
|
||||
|
||||
private final TaskbarActivityContext mTaskbarContext;
|
||||
private final TaskbarAllAppsProxyView mProxyView;
|
||||
private final LayoutParams mLayoutParams;
|
||||
|
||||
private TaskbarControllers mControllers;
|
||||
/** Window context for all apps if it is open. */
|
||||
private @Nullable TaskbarAllAppsContext mAllAppsContext;
|
||||
|
||||
// Application data models.
|
||||
private AppInfo[] mApps;
|
||||
private int mAppsModelFlags;
|
||||
private List<ItemInfo> mPredictedApps;
|
||||
|
||||
public TaskbarAllAppsController(TaskbarActivityContext context) {
|
||||
mTaskbarContext = context;
|
||||
mProxyView = new TaskbarAllAppsProxyView(mTaskbarContext);
|
||||
mLayoutParams = createLayoutParams();
|
||||
}
|
||||
|
||||
/** Initialize the controller. */
|
||||
public void init(TaskbarControllers controllers) {
|
||||
if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
|
||||
mControllers = controllers;
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the current {@link AppInfo} instances. */
|
||||
public void setApps(AppInfo[] apps, int flags) {
|
||||
if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mApps = apps;
|
||||
mAppsModelFlags = flags;
|
||||
if (mAllAppsContext != null) {
|
||||
mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags);
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates the current predictions. */
|
||||
public void setPredictedApps(List<ItemInfo> predictedApps) {
|
||||
if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mPredictedApps = predictedApps;
|
||||
if (mAllAppsContext != null) {
|
||||
mAllAppsContext.getAppsView().getFloatingHeaderView()
|
||||
.findFixedRowByType(PredictionRowView.class)
|
||||
.setPredictedApps(mPredictedApps);
|
||||
}
|
||||
}
|
||||
|
||||
/** Opens the {@link TaskbarAllAppsContainerView} in a new window. */
|
||||
public void show() {
|
||||
if (mProxyView.isOpen()) {
|
||||
return;
|
||||
}
|
||||
mProxyView.show();
|
||||
|
||||
mAllAppsContext = new TaskbarAllAppsContext(mTaskbarContext,
|
||||
this,
|
||||
mControllers.taskbarStashController);
|
||||
mAllAppsContext.getDragController().init(mControllers);
|
||||
mTaskbarContext.addOnDeviceProfileChangeListener(this);
|
||||
Optional.ofNullable(mAllAppsContext.getSystemService(WindowManager.class))
|
||||
.ifPresent(m -> m.addView(mAllAppsContext.getDragLayer(), mLayoutParams));
|
||||
|
||||
mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags);
|
||||
mAllAppsContext.getAppsView().getFloatingHeaderView()
|
||||
.findFixedRowByType(PredictionRowView.class)
|
||||
.setPredictedApps(mPredictedApps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the all apps window from the hierarchy.
|
||||
* <p>
|
||||
* This method should be called after an exit animation finishes, if applicable.
|
||||
*/
|
||||
void closeWindow() {
|
||||
mProxyView.close(false);
|
||||
mTaskbarContext.removeOnDeviceProfileChangeListener(this);
|
||||
Optional.ofNullable(mAllAppsContext)
|
||||
.map(c -> c.getSystemService(WindowManager.class))
|
||||
.ifPresent(m -> m.removeView(mAllAppsContext.getDragLayer()));
|
||||
mAllAppsContext = null;
|
||||
}
|
||||
|
||||
private LayoutParams createLayoutParams() {
|
||||
LayoutParams layoutParams = new LayoutParams(
|
||||
TYPE_APPLICATION_OVERLAY,
|
||||
0,
|
||||
PixelFormat.TRANSLUCENT);
|
||||
layoutParams.setTitle(WINDOW_TITLE);
|
||||
layoutParams.gravity = Gravity.BOTTOM;
|
||||
layoutParams.packageName = mTaskbarContext.getPackageName();
|
||||
layoutParams.setFitInsetsTypes(0); // Handled by container view.
|
||||
layoutParams.setSystemApplicationOverlay(true);
|
||||
return layoutParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceProfileChanged(DeviceProfile dp) {
|
||||
Optional.ofNullable(mAllAppsContext).ifPresent(c -> c.updateDeviceProfile(dp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Proxy view connecting taskbar drag layer to the all apps window.
|
||||
* <p>
|
||||
* The all apps view is in a separate window and has its own drag layer, but this proxy lets it
|
||||
* behave as though its in the taskbar drag layer. For instance, when the taskbar closes all
|
||||
* {@link AbstractFloatingView} instances, the all apps window will also close.
|
||||
*/
|
||||
private class TaskbarAllAppsProxyView extends AbstractFloatingView {
|
||||
|
||||
private TaskbarAllAppsProxyView(Context context) {
|
||||
super(context, null);
|
||||
}
|
||||
|
||||
private void show() {
|
||||
mIsOpen = true;
|
||||
mTaskbarContext.getDragLayer().addView(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleClose(boolean animate) {
|
||||
mTaskbarContext.getDragLayer().removeView(this);
|
||||
Optional.ofNullable(mAllAppsContext)
|
||||
.map(TaskbarAllAppsContext::getAllAppsViewController)
|
||||
.ifPresent(v -> v.close(animate));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isOfType(int type) {
|
||||
return (type & TYPE_TASKBAR_ALL_APPS) != 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
-8
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.taskbar;
|
||||
package com.android.launcher3.taskbar.allapps;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.AGGRESSIVE_EASE;
|
||||
|
||||
@@ -23,18 +23,22 @@ import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
import com.android.launcher3.Insettable;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.views.AbstractSlideInView;
|
||||
|
||||
/** Wrapper for taskbar all apps with slide-in behavior. */
|
||||
public class TaskbarAllAppsSlideInView extends
|
||||
AbstractSlideInView<TaskbarActivityContext> implements Insettable {
|
||||
import java.util.Optional;
|
||||
|
||||
private static final int DEFAULT_OPEN_DURATION = 500;
|
||||
private static final int DEFAULT_CLOSE_DURATION = 200;
|
||||
/** Wrapper for taskbar all apps with slide-in behavior. */
|
||||
public class TaskbarAllAppsSlideInView extends AbstractSlideInView<TaskbarAllAppsContext>
|
||||
implements Insettable, DeviceProfile.OnDeviceProfileChangeListener {
|
||||
static final int DEFAULT_OPEN_DURATION = 500;
|
||||
static final int DEFAULT_CLOSE_DURATION = 200;
|
||||
|
||||
private TaskbarAllAppsContainerView mAppsView;
|
||||
private OnCloseListener mOnCloseBeginListener;
|
||||
private float mShiftRange;
|
||||
|
||||
public TaskbarAllAppsSlideInView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
@@ -46,7 +50,7 @@ public class TaskbarAllAppsSlideInView extends
|
||||
}
|
||||
|
||||
/** Opens the all apps view. */
|
||||
public void show() {
|
||||
void show() {
|
||||
if (mIsOpen || mOpenCloseAnimator.isRunning()) {
|
||||
return;
|
||||
}
|
||||
@@ -60,12 +64,18 @@ public class TaskbarAllAppsSlideInView extends
|
||||
}
|
||||
|
||||
/** The apps container inside this view. */
|
||||
public TaskbarAllAppsContainerView getAppsView() {
|
||||
TaskbarAllAppsContainerView getAppsView() {
|
||||
return mAppsView;
|
||||
}
|
||||
|
||||
/** Callback invoked when the view is beginning to close (e.g. close animation is started). */
|
||||
void setOnCloseBeginListener(OnCloseListener onCloseBeginListener) {
|
||||
mOnCloseBeginListener = onCloseBeginListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleClose(boolean animate) {
|
||||
Optional.ofNullable(mOnCloseBeginListener).ifPresent(OnCloseListener::onSlideInViewClosed);
|
||||
handleClose(animate, DEFAULT_CLOSE_DURATION);
|
||||
}
|
||||
|
||||
@@ -79,6 +89,17 @@ public class TaskbarAllAppsSlideInView extends
|
||||
super.onFinishInflate();
|
||||
mAppsView = findViewById(R.id.apps_view);
|
||||
mContent = mAppsView;
|
||||
|
||||
DeviceProfile dp = mActivityContext.getDeviceProfile();
|
||||
setShiftRange(dp.allAppsShiftRange);
|
||||
|
||||
mActivityContext.addOnDeviceProfileChangeListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
super.onLayout(changed, l, t, r, b);
|
||||
setTranslationShift(mTranslationShift);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,4 +119,24 @@ public class TaskbarAllAppsSlideInView extends
|
||||
public void setInsets(Rect insets) {
|
||||
mAppsView.setInsets(insets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeviceProfileChanged(DeviceProfile dp) {
|
||||
setShiftRange(dp.allAppsShiftRange);
|
||||
setTranslationShift(TRANSLATION_SHIFT_OPENED);
|
||||
}
|
||||
|
||||
private void setShiftRange(float shiftRange) {
|
||||
mShiftRange = shiftRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected float getShiftRange() {
|
||||
return mShiftRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isEventOverContent(MotionEvent ev) {
|
||||
return getPopupContainer().isEventOverView(mAppsView.getVisibleContainerView(), ev);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.android.launcher3.taskbar.allapps;
|
||||
|
||||
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_ALL_APPS;
|
||||
import static com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView.DEFAULT_CLOSE_DURATION;
|
||||
import static com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView.DEFAULT_OPEN_DURATION;
|
||||
import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT;
|
||||
|
||||
import com.android.launcher3.appprediction.AppsDividerView;
|
||||
import com.android.launcher3.appprediction.PredictionRowView;
|
||||
import com.android.launcher3.taskbar.TaskbarStashController;
|
||||
|
||||
/**
|
||||
* Handles the {@link TaskbarAllAppsContainerView} behavior and synchronizes its transitions with
|
||||
* taskbar stashing.
|
||||
*/
|
||||
final class TaskbarAllAppsViewController {
|
||||
|
||||
private final TaskbarAllAppsContext mContext;
|
||||
private final TaskbarAllAppsSlideInView mSlideInView;
|
||||
private final TaskbarAllAppsContainerView mAppsView;
|
||||
private final TaskbarStashController mTaskbarStashController;
|
||||
|
||||
TaskbarAllAppsViewController(
|
||||
TaskbarAllAppsContext context,
|
||||
TaskbarAllAppsSlideInView slideInView,
|
||||
TaskbarAllAppsController windowController,
|
||||
TaskbarStashController taskbarStashController) {
|
||||
|
||||
mContext = context;
|
||||
mSlideInView = slideInView;
|
||||
mAppsView = mSlideInView.getAppsView();
|
||||
mTaskbarStashController = taskbarStashController;
|
||||
|
||||
setUpIconLongClick();
|
||||
setUpAppDivider();
|
||||
setUpTaskbarStashing();
|
||||
mSlideInView.addOnCloseListener(windowController::closeWindow);
|
||||
}
|
||||
|
||||
/** Starts the {@link TaskbarAllAppsSlideInView} enter transition. */
|
||||
void show() {
|
||||
mSlideInView.show();
|
||||
}
|
||||
|
||||
/** Closes the {@link TaskbarAllAppsSlideInView}. */
|
||||
void close(boolean animate) {
|
||||
mSlideInView.close(animate);
|
||||
}
|
||||
|
||||
private void setUpIconLongClick() {
|
||||
mAppsView.setOnIconLongClickListener(
|
||||
mContext.getDragController()::startDragOnLongClick);
|
||||
mAppsView.getFloatingHeaderView()
|
||||
.findFixedRowByType(PredictionRowView.class)
|
||||
.setOnIconLongClickListener(
|
||||
mContext.getDragController()::startDragOnLongClick);
|
||||
}
|
||||
|
||||
private void setUpAppDivider() {
|
||||
mAppsView.getFloatingHeaderView()
|
||||
.findFixedRowByType(AppsDividerView.class)
|
||||
.setShowAllAppsLabel(!mContext.getOnboardingPrefs().hasReachedMaxCount(
|
||||
ALL_APPS_VISITED_COUNT));
|
||||
mContext.getOnboardingPrefs().incrementEventCount(ALL_APPS_VISITED_COUNT);
|
||||
}
|
||||
|
||||
private void setUpTaskbarStashing() {
|
||||
mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, true);
|
||||
mTaskbarStashController.applyState(DEFAULT_OPEN_DURATION);
|
||||
mSlideInView.setOnCloseBeginListener(() -> {
|
||||
mTaskbarStashController.updateStateForFlag(
|
||||
FLAG_STASHED_IN_APP_ALL_APPS, false);
|
||||
mTaskbarStashController.applyState(DEFAULT_CLOSE_DURATION);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -53,9 +53,16 @@ public class AllAppsState extends LauncherState {
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
|
||||
ScaleAndTranslation scaleAndTranslation = LauncherState.OVERVIEW
|
||||
.getWorkspaceScaleAndTranslation(launcher);
|
||||
scaleAndTranslation.scale = 1;
|
||||
ScaleAndTranslation scaleAndTranslation =
|
||||
new ScaleAndTranslation(NO_SCALE, NO_OFFSET, NO_OFFSET);
|
||||
if (launcher.getDeviceProfile().isTablet) {
|
||||
scaleAndTranslation.scale = 0.97f;
|
||||
} else {
|
||||
ScaleAndTranslation overviewScaleAndTranslation = LauncherState.OVERVIEW
|
||||
.getWorkspaceScaleAndTranslation(launcher);
|
||||
scaleAndTranslation.translationX = overviewScaleAndTranslation.translationX;
|
||||
scaleAndTranslation.translationY = overviewScaleAndTranslation.translationY;
|
||||
}
|
||||
return scaleAndTranslation;
|
||||
}
|
||||
|
||||
|
||||
+19
-6
@@ -23,8 +23,13 @@ import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.LauncherState.OVERVIEW;
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.DEACCEL;
|
||||
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR_TELEPORT;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@@ -126,23 +131,31 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr
|
||||
|
||||
private StateAnimationConfig getNormalToAllAppsAnimation() {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(ACCEL,
|
||||
ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
|
||||
ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
|
||||
boolean isTablet = mLauncher.getDeviceProfile().isTablet;
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
|
||||
? INSTANT
|
||||
: Interpolators.clampToProgress(ACCEL,
|
||||
ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD,
|
||||
ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD));
|
||||
builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(ACCEL,
|
||||
ALL_APPS_SCRIM_VISIBLE_THRESHOLD,
|
||||
ALL_APPS_SCRIM_OPAQUE_THRESHOLD));
|
||||
builder.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private StateAnimationConfig getAllAppsToNormalAnimation() {
|
||||
StateAnimationConfig builder = new StateAnimationConfig();
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, Interpolators.clampToProgress(DEACCEL,
|
||||
1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
|
||||
1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
|
||||
boolean isTablet = mLauncher.getDeviceProfile().isTablet;
|
||||
builder.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
|
||||
? FINAL_FRAME
|
||||
: Interpolators.clampToProgress(DEACCEL,
|
||||
1 - ALL_APPS_CONTENT_FADE_MAX_CLAMPING_THRESHOLD,
|
||||
1 - ALL_APPS_CONTENT_FADE_MIN_CLAMPING_THRESHOLD));
|
||||
builder.setInterpolator(ANIM_SCRIM_FADE, Interpolators.clampToProgress(DEACCEL,
|
||||
1 - ALL_APPS_SCRIM_OPAQUE_THRESHOLD,
|
||||
1 - ALL_APPS_SCRIM_VISIBLE_THRESHOLD));
|
||||
builder.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle" >
|
||||
<solid android:color="@color/surface" />
|
||||
<solid android:color="?android:attr/colorBackground" />
|
||||
<corners
|
||||
android:topLeftRadius="@dimen/dialogCornerRadius"
|
||||
android:topRightRadius="@dimen/dialogCornerRadius" />
|
||||
|
||||
+8
-15
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright (C) 2022 The Android Open Source Project
|
||||
<!-- Copyright (C) 2022 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -14,16 +13,10 @@
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<ripple android:color="?android:attr/colorControlHighlight"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
|
||||
<item>
|
||||
<shape android:shape="rectangle"
|
||||
android:tint="?colorButtonNormal">
|
||||
<corners
|
||||
android:topLeftRadius="@dimen/dialogCornerRadius"
|
||||
android:topRightRadius="@dimen/dialogCornerRadius"/>
|
||||
<solid android:color="?attr/allAppsScrimColor" />
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||
android:shape="rectangle" >
|
||||
<solid android:color="?androidprv:attr/colorSurfaceVariant"/>
|
||||
<corners android:radius="@dimen/bottom_sheet_handle_corner_radius" />
|
||||
</shape>
|
||||
@@ -17,19 +17,19 @@
|
||||
android:id="@+id/bottom_sheet_background"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/bg_all_apps_bottom_sheet">
|
||||
android:background="@drawable/bg_rounded_corner_bottom_sheet">
|
||||
|
||||
<View
|
||||
android:id="@+id/bottom_sheet_handle_area"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="34dp" />
|
||||
android:layout_height="36dp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/bottom_sheet_handle"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="2dp"
|
||||
android:layout_width="@dimen/bottom_sheet_handle_width"
|
||||
android:layout_height="@dimen/bottom_sheet_handle_height"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="?android:attr/textColorSecondary" />
|
||||
android:layout_marginTop="@dimen/bottom_sheet_handle_margin"
|
||||
android:layout_marginBottom="@dimen/bottom_sheet_handle_margin"
|
||||
android:background="@drawable/bg_rounded_corner_bottom_sheet_handle" />
|
||||
</FrameLayout>
|
||||
|
||||
@@ -19,16 +19,16 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/bg_rounded_corner_bottom_sheet"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingTop="@dimen/bottom_sheet_handle_margin"
|
||||
android:orientation="vertical">
|
||||
<View
|
||||
android:id="@+id/collapse_handle"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="2dp"
|
||||
android:layout_width="@dimen/bottom_sheet_handle_width"
|
||||
android:layout_height="@dimen/bottom_sheet_handle_height"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginBottom="@dimen/bottom_sheet_handle_margin"
|
||||
android:visibility="gone"
|
||||
android:background="?android:attr/textColorSecondary"/>
|
||||
android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/>
|
||||
<TextView
|
||||
style="@style/TextHeadline"
|
||||
android:id="@+id/title"
|
||||
|
||||
@@ -31,11 +31,11 @@
|
||||
|
||||
<View
|
||||
android:id="@+id/collapse_handle"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="2dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_width="@dimen/bottom_sheet_handle_width"
|
||||
android:layout_height="@dimen/bottom_sheet_handle_height"
|
||||
android:layout_marginTop="@dimen/bottom_sheet_handle_margin"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:background="?android:attr/textColorSecondary"/>
|
||||
android:background="@drawable/bg_rounded_corner_bottom_sheet_handle"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/no_widgets_text"
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
<dimen name="widget_list_horizontal_margin">32dp</dimen>
|
||||
|
||||
<!-- AllApps -->
|
||||
<dimen name="all_apps_bottom_sheet_horizontal_padding">32dp</dimen>
|
||||
<dimen name="all_apps_search_bar_content_overlap">0dp</dimen>
|
||||
<dimen name="all_apps_bottom_sheet_horizontal_padding">46dp</dimen>
|
||||
|
||||
<!-- Fast scroll -->
|
||||
<dimen name="fastscroll_popup_width">75dp</dimen>
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2022 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at`
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<!-- AllApps -->
|
||||
<dimen name="all_apps_top_padding">0dp</dimen>
|
||||
</resources>
|
||||
@@ -16,5 +16,6 @@
|
||||
|
||||
<resources>
|
||||
<!-- AllApps -->
|
||||
<dimen name="all_apps_bottom_sheet_horizontal_padding">41dp</dimen>
|
||||
<dimen name="all_apps_top_padding">300dp</dimen>
|
||||
<dimen name="all_apps_bottom_sheet_horizontal_padding">65dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -93,8 +93,11 @@
|
||||
<dimen name="fastscroll_end_margin">-26dp</dimen>
|
||||
|
||||
<!-- All Apps -->
|
||||
<dimen name="all_apps_open_vertical_translate">320dp</dimen>
|
||||
<dimen name="all_apps_starting_vertical_translate">320dp</dimen>
|
||||
<dimen name="all_apps_top_padding">0dp</dimen>
|
||||
<dimen name="all_apps_search_bar_field_height">48dp</dimen>
|
||||
<!-- all_apps_search_bar_field_height / 2 -->
|
||||
<dimen name="all_apps_search_bar_content_overlap">24dp</dimen>
|
||||
<dimen name="all_apps_search_bar_bottom_padding">30dp</dimen>
|
||||
<dimen name="all_apps_empty_search_message_top_offset">40dp</dimen>
|
||||
<dimen name="all_apps_empty_search_bg_top_offset">144dp</dimen>
|
||||
@@ -363,4 +366,9 @@
|
||||
<dimen name="search_row_small_icon_size">32dp</dimen>
|
||||
<dimen name="padded_rounded_button_padding">8dp</dimen>
|
||||
|
||||
<!-- Bottom sheet related parameters -->
|
||||
<dimen name="bottom_sheet_handle_width">32dp</dimen>
|
||||
<dimen name="bottom_sheet_handle_height">4dp</dimen>
|
||||
<dimen name="bottom_sheet_handle_margin">16dp</dimen>
|
||||
<dimen name="bottom_sheet_handle_corner_radius">2dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -171,7 +171,8 @@ public class DeviceProfile {
|
||||
|
||||
// All apps
|
||||
public Point allAppsBorderSpacePx;
|
||||
public int allAppsOpenVerticalTranslate;
|
||||
public int allAppsShiftRange;
|
||||
public int allAppsTopPadding;
|
||||
public int allAppsCellHeightPx;
|
||||
public int allAppsCellWidthPx;
|
||||
public int allAppsIconSizePx;
|
||||
@@ -288,8 +289,11 @@ public class DeviceProfile {
|
||||
desiredWorkspaceHorizontalMarginPx = getHorizontalMarginPx(inv, res);
|
||||
desiredWorkspaceHorizontalMarginOriginalPx = desiredWorkspaceHorizontalMarginPx;
|
||||
|
||||
allAppsOpenVerticalTranslate = res.getDimensionPixelSize(
|
||||
R.dimen.all_apps_open_vertical_translate);
|
||||
allAppsTopPadding = res.getDimensionPixelSize(R.dimen.all_apps_top_padding)
|
||||
+ (isTablet ? heightPx - availableHeightPx : 0);
|
||||
allAppsShiftRange = isTablet
|
||||
? heightPx - allAppsTopPadding
|
||||
: res.getDimensionPixelSize(R.dimen.all_apps_starting_vertical_translate);
|
||||
|
||||
folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale);
|
||||
folderContentPaddingLeftRight =
|
||||
|
||||
@@ -89,15 +89,15 @@ public class AllAppsTransitionController
|
||||
private float mShiftRange; // changes depending on the orientation
|
||||
private float mProgress; // [0, 1], mShiftRange * mProgress = shiftCurrent
|
||||
|
||||
private float mScrollRangeDelta = 0;
|
||||
private ScrimView mScrimView;
|
||||
|
||||
public AllAppsTransitionController(Launcher l) {
|
||||
mLauncher = l;
|
||||
mShiftRange = mLauncher.getDeviceProfile().heightPx;
|
||||
DeviceProfile dp = mLauncher.getDeviceProfile();
|
||||
setShiftRange(dp.allAppsShiftRange);
|
||||
mProgress = 1f;
|
||||
|
||||
mIsVerticalLayout = mLauncher.getDeviceProfile().isVerticalBarLayout();
|
||||
mIsVerticalLayout = dp.isVerticalBarLayout();
|
||||
mLauncher.addOnDeviceProfileChangeListener(this);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ public class AllAppsTransitionController
|
||||
@Override
|
||||
public void onDeviceProfileChanged(DeviceProfile dp) {
|
||||
mIsVerticalLayout = dp.isVerticalBarLayout();
|
||||
setScrollRangeDelta(mScrollRangeDelta);
|
||||
setShiftRange(dp.allAppsShiftRange);
|
||||
|
||||
if (mIsVerticalLayout) {
|
||||
mLauncher.getHotseat().setTranslationY(0);
|
||||
@@ -160,12 +160,14 @@ public class AllAppsTransitionController
|
||||
}
|
||||
|
||||
// need to decide depending on the release velocity
|
||||
Interpolator interpolator = (config.userControlled ? LINEAR : DEACCEL_1_7);
|
||||
|
||||
Interpolator verticalProgressInterpolator = config.getInterpolator(ANIM_VERTICAL_PROGRESS,
|
||||
config.userControlled ? LINEAR : DEACCEL_1_7);
|
||||
Animator anim = createSpringAnimation(mProgress, targetProgress);
|
||||
anim.setInterpolator(config.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
|
||||
anim.setInterpolator(verticalProgressInterpolator);
|
||||
anim.addListener(getProgressAnimatorListener());
|
||||
builder.add(anim);
|
||||
// Use ANIM_VERTICAL_PROGRESS's interpolator to determine state transition threshold.
|
||||
builder.setInterpolator(verticalProgressInterpolator);
|
||||
|
||||
setAlphas(toState, config, builder);
|
||||
|
||||
@@ -215,9 +217,8 @@ public class AllAppsTransitionController
|
||||
/**
|
||||
* Updates the total scroll range but does not update the UI.
|
||||
*/
|
||||
public void setScrollRangeDelta(float delta) {
|
||||
mScrollRangeDelta = delta;
|
||||
mShiftRange = mLauncher.getDeviceProfile().heightPx - mScrollRangeDelta;
|
||||
public void setShiftRange(float shiftRange) {
|
||||
mShiftRange = shiftRange;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -408,7 +408,7 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
|
||||
if (grid.isVerticalBarLayout()) {
|
||||
setPadding(grid.workspacePadding.left, 0, grid.workspacePadding.right, 0);
|
||||
} else {
|
||||
setPadding(0, grid.isTablet ? insets.top : 0, 0, 0);
|
||||
setPadding(0, grid.allAppsTopPadding, 0, 0);
|
||||
}
|
||||
|
||||
InsettableFrameLayout.dispatchInsets(this, insets);
|
||||
@@ -765,4 +765,11 @@ public abstract class BaseAllAppsContainerView<T extends Context & ActivityConte
|
||||
&& mVerticalFadingEdge);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a view that denotes the visible part of all apps container view.
|
||||
*/
|
||||
public View getVisibleContainerView() {
|
||||
return mActivityContext.getDeviceProfile().isTablet ? mBottomSheetBackground : this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.android.launcher3.allapps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
@@ -59,12 +58,4 @@ public class LauncherAllAppsContainerView extends ActivityAllAppsContainerView<L
|
||||
}
|
||||
return super.onTouchEvent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInsets(Rect insets) {
|
||||
super.setInsets(insets);
|
||||
int allAppsStartingPositionY = mActivityContext.getDeviceProfile().availableHeightPx
|
||||
- mActivityContext.getDeviceProfile().allAppsOpenVerticalTranslate;
|
||||
mActivityContext.getAllAppsController().setScrollRangeDelta(allAppsStartingPositionY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public class AppsSearchContainerLayout extends ExtendedEditText
|
||||
setHint(prefixTextWithIcon(getContext(), R.drawable.ic_allapps_search, getHint()));
|
||||
|
||||
mContentOverlap =
|
||||
getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height) / 2;
|
||||
getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_content_overlap);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -130,6 +130,23 @@ public class Interpolators {
|
||||
}
|
||||
};
|
||||
|
||||
public static final Interpolator LINEAR_TELEPORT = t -> {
|
||||
float startTeleport = 0.2f;
|
||||
float endTeleport = 0.4f;
|
||||
float teleportProgress = 0.5f;
|
||||
float v;
|
||||
if (t < startTeleport) {
|
||||
v = LINEAR.getInterpolation(t);
|
||||
} else if (t < endTeleport) {
|
||||
v = Utilities.mapToRange(t, startTeleport, endTeleport, startTeleport,
|
||||
endTeleport + teleportProgress, ACCEL_DEACCEL);
|
||||
} else {
|
||||
v = LINEAR.getInterpolation(t) + teleportProgress;
|
||||
}
|
||||
v = Utilities.boundToRange(v, 0f, 1f);
|
||||
return v;
|
||||
};
|
||||
|
||||
private static final float FAST_FLING_PX_MS = 10;
|
||||
|
||||
public static Interpolator scrollInterpolatorForVelocity(float velocity) {
|
||||
|
||||
@@ -77,6 +77,13 @@ public class PendingAnimation implements PropertySetter {
|
||||
addAnimationHoldersRecur(a, mDuration, springProperty, mAnimHolders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures interpolator of the underlying AnimatorSet.
|
||||
*/
|
||||
public void setInterpolator(TimeInterpolator interpolator) {
|
||||
mAnim.setInterpolator(interpolator);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewAlpha(View view, float alpha, TimeInterpolator interpolator) {
|
||||
if (view == null || view.getAlpha() == alpha) {
|
||||
|
||||
@@ -17,9 +17,13 @@ package com.android.launcher3.touch;
|
||||
|
||||
import static com.android.launcher3.LauncherState.ALL_APPS;
|
||||
import static com.android.launcher3.LauncherState.NORMAL;
|
||||
import static com.android.launcher3.anim.Interpolators.FINAL_FRAME;
|
||||
import static com.android.launcher3.anim.Interpolators.INSTANT;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR_TELEPORT;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_ALL_APPS_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_SCRIM_FADE;
|
||||
import static com.android.launcher3.states.StateAnimationConfig.ANIM_VERTICAL_PROGRESS;
|
||||
|
||||
import android.view.MotionEvent;
|
||||
import android.view.animation.Interpolator;
|
||||
@@ -94,9 +98,9 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
LauncherState toState) {
|
||||
StateAnimationConfig config = super.getConfigForStates(fromState, toState);
|
||||
if (fromState == NORMAL && toState == ALL_APPS) {
|
||||
applyNormalToAllAppsAnimConfig(config);
|
||||
applyNormalToAllAppsAnimConfig(mLauncher, config);
|
||||
} else if (fromState == ALL_APPS && toState == NORMAL) {
|
||||
applyAllAppsToNormalConfig(config);
|
||||
applyAllAppsToNormalConfig(mLauncher, config);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
@@ -104,17 +108,24 @@ public class AllAppsSwipeController extends AbstractStateChangeTouchController {
|
||||
/**
|
||||
* Applies Animation config values for transition from all apps to home
|
||||
*/
|
||||
public static void applyAllAppsToNormalConfig(StateAnimationConfig config) {
|
||||
public static void applyAllAppsToNormalConfig(Launcher launcher, StateAnimationConfig config) {
|
||||
boolean isTablet = launcher.getDeviceProfile().isTablet;
|
||||
config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
|
||||
? FINAL_FRAME : ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies Animation config values for transition from home to all apps
|
||||
*/
|
||||
public static void applyNormalToAllAppsAnimConfig(StateAnimationConfig config) {
|
||||
public static void applyNormalToAllAppsAnimConfig(Launcher launcher,
|
||||
StateAnimationConfig config) {
|
||||
boolean isTablet = launcher.getDeviceProfile().isTablet;
|
||||
config.setInterpolator(ANIM_SCRIM_FADE, ALLAPPS_STAGGERED_FADE_EARLY_RESPONDER);
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
|
||||
config.setInterpolator(ANIM_ALL_APPS_FADE, isTablet
|
||||
? INSTANT : ALLAPPS_STAGGERED_FADE_LATE_RESPONDER);
|
||||
config.setInterpolator(ANIM_VERTICAL_PROGRESS, isTablet ? LINEAR_TELEPORT : LINEAR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -113,9 +113,16 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the range in height that the slide in view can be dragged.
|
||||
*/
|
||||
protected float getShiftRange() {
|
||||
return mContent.getHeight();
|
||||
}
|
||||
|
||||
protected void setTranslationShift(float translationShift) {
|
||||
mTranslationShift = translationShift;
|
||||
mContent.setTranslationY(mTranslationShift * mContent.getHeight());
|
||||
mContent.setTranslationY(mTranslationShift * getShiftRange());
|
||||
if (mColorScrim != null) {
|
||||
mColorScrim.setAlpha(1 - mTranslationShift);
|
||||
}
|
||||
@@ -132,8 +139,7 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
|
||||
mSwipeDetector.setDetectableScrollConditions(
|
||||
directionsToDetectScroll, false);
|
||||
mSwipeDetector.onTouchEvent(ev);
|
||||
return mSwipeDetector.isDraggingOrSettling()
|
||||
|| !getPopupContainer().isEventOverView(mContent, ev);
|
||||
return mSwipeDetector.isDraggingOrSettling() || !isEventOverContent(ev);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,13 +148,23 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
|
||||
if (ev.getAction() == MotionEvent.ACTION_UP && mSwipeDetector.isIdleState()
|
||||
&& !isOpeningAnimationRunning()) {
|
||||
// If we got ACTION_UP without ever starting swipe, close the panel.
|
||||
if (!getPopupContainer().isEventOverView(mContent, ev)) {
|
||||
if (!isEventOverContent(ev)) {
|
||||
close(true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the touch event is over the visible area of the bottom sheet.
|
||||
*
|
||||
* By default will check if the touch event is over {@code mContent}, subclasses should override
|
||||
* this method if the visible area of the bottom sheet is different from {@code mContent}.
|
||||
*/
|
||||
protected boolean isEventOverContent(MotionEvent ev) {
|
||||
return getPopupContainer().isEventOverView(mContent, ev);
|
||||
}
|
||||
|
||||
private boolean isOpeningAnimationRunning() {
|
||||
return mIsOpen && mOpenCloseAnimator.isRunning();
|
||||
}
|
||||
@@ -160,7 +176,7 @@ public abstract class AbstractSlideInView<T extends Context & ActivityContext>
|
||||
|
||||
@Override
|
||||
public boolean onDrag(float displacement) {
|
||||
float range = mContent.getHeight();
|
||||
float range = getShiftRange();
|
||||
displacement = Utilities.boundToRange(displacement, 0, range);
|
||||
setTranslationShift(displacement / range);
|
||||
return true;
|
||||
|
||||
@@ -55,8 +55,15 @@ public class AllAppsState extends LauncherState {
|
||||
|
||||
@Override
|
||||
public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) {
|
||||
return new ScaleAndTranslation(1f, 0,
|
||||
-launcher.getAllAppsController().getShiftRange() * PARALLAX_COEFFICIENT);
|
||||
ScaleAndTranslation scaleAndTranslation =
|
||||
new ScaleAndTranslation(NO_SCALE, NO_OFFSET, NO_OFFSET);
|
||||
if (launcher.getDeviceProfile().isTablet) {
|
||||
scaleAndTranslation.scale = 0.97f;
|
||||
} else {
|
||||
scaleAndTranslation.translationY =
|
||||
-launcher.getAllAppsController().getShiftRange() * PARALLAX_COEFFICIENT;
|
||||
}
|
||||
return scaleAndTranslation;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user