Add Hotseat items to Taskbar
- Currently supports WorkspaceItemInfo (e.g. normal app icons including hotseat predictions and pinned deep shortcuts). - Currently doesn't support Folders, Notification dots, or long press. Some technical details: - Always allow HotseatPredictionController updates given the Hotseat is always showing even when Launcher is stopped. - Represent Taskbar Hotseat items as BubbleTextViews, to allow for normal click handling etc. When the hotseat is updated, we reuse the same BubbleTextViews that were initially inflated, and just reapply the new info. - Add new BubbleTextView iconDisplay for Taskbar, to allow for different treatment such as icon size. Bug: 171917176 Change-Id: I325eb39051f2dc69228b39b5c40ed0cbdad8e200
This commit is contained in:
@@ -24,6 +24,8 @@
|
||||
android:id="@+id/taskbar_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/taskbar_background"/>
|
||||
android:background="@color/taskbar_background"
|
||||
android:gravity="center"
|
||||
android:animateLayoutChanges="true"/>
|
||||
|
||||
</com.android.launcher3.taskbar.TaskbarContainerView>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<com.android.launcher3.views.DoubleShadowBubbleTextView style="@style/BaseIcon.Workspace.Taskbar" />
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2021 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.
|
||||
-->
|
||||
|
||||
<com.android.launcher3.uioverrides.PredictedAppIcon style="@style/BaseIcon.Workspace.Taskbar" />
|
||||
@@ -122,4 +122,7 @@
|
||||
|
||||
<!-- Taskbar -->
|
||||
<dimen name="taskbar_size">48dp</dimen>
|
||||
<dimen name="taskbar_icon_size">32dp</dimen>
|
||||
<!-- Note that this applies to both sides of all icons, so visible space is double this. -->
|
||||
<dimen name="taskbar_icon_spacing">14dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -85,4 +85,10 @@
|
||||
<item name="android:drawablePadding">8dp</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
</style>
|
||||
|
||||
<!-- Icon displayed on the taskbar -->
|
||||
<style name="BaseIcon.Workspace.Taskbar" >
|
||||
<item name="iconDisplay">taskbar</item>
|
||||
<item name="iconSizeOverride">@dimen/taskbar_icon_size</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -264,6 +264,11 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
return mTaskbarStateHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isViewInTaskbar(View v) {
|
||||
return mTaskbarController != null && mTaskbarController.isViewInTaskbar(v);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useFadeOutAnimationForLauncherStart(CancellationSignal signal) {
|
||||
QuickstepAppTransitionManagerImpl appTransitionManager =
|
||||
@@ -350,6 +355,10 @@ public abstract class BaseQuickstepLauncher extends Launcher
|
||||
// populating workspace.
|
||||
// TODO: Find a better place for this
|
||||
WellbeingModel.INSTANCE.get(this);
|
||||
|
||||
if (mTaskbarController != null) {
|
||||
mTaskbarController.onHotseatUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -202,9 +202,10 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAdaptiveIconAnimation() {
|
||||
public boolean supportsAdaptiveIconAnimation(View clickedView) {
|
||||
return hasControlRemoteAppTransitionPermission()
|
||||
&& FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM.get();
|
||||
&& FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM.get()
|
||||
&& !mLauncher.isViewInTaskbar(clickedView);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -972,9 +973,12 @@ public abstract class QuickstepAppTransitionManagerImpl extends LauncherAppTrans
|
||||
launcherIsATargetWithMode(appTargets, MODE_CLOSING);
|
||||
|
||||
final boolean launchingFromRecents = isLaunchingFromRecents(mV, appTargets);
|
||||
final boolean launchingFromTaskbar = mLauncher.isViewInTaskbar(mV);
|
||||
if (launchingFromRecents) {
|
||||
composeRecentsLaunchAnimator(anim, mV, appTargets, wallpaperTargets,
|
||||
launcherClosing);
|
||||
} else if (launchingFromTaskbar) {
|
||||
// TODO
|
||||
} else {
|
||||
composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets,
|
||||
launcherClosing);
|
||||
|
||||
@@ -37,7 +37,6 @@ import com.android.launcher3.DragSource;
|
||||
import com.android.launcher3.DropTarget;
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.InvariantDeviceProfile;
|
||||
import com.android.launcher3.Launcher;
|
||||
import com.android.launcher3.LauncherSettings;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.Utilities;
|
||||
@@ -75,7 +74,7 @@ public class HotseatPredictionController implements DragController.DragListener,
|
||||
|
||||
private int mHotSeatItemsCount;
|
||||
|
||||
private Launcher mLauncher;
|
||||
private QuickstepLauncher mLauncher;
|
||||
private final Hotseat mHotseat;
|
||||
|
||||
private List<ItemInfo> mPredictedItems = Collections.emptyList();
|
||||
@@ -108,7 +107,7 @@ public class HotseatPredictionController implements DragController.DragListener,
|
||||
return true;
|
||||
};
|
||||
|
||||
public HotseatPredictionController(Launcher launcher) {
|
||||
public HotseatPredictionController(QuickstepLauncher launcher) {
|
||||
mLauncher = launcher;
|
||||
mHotseat = launcher.getHotseat();
|
||||
mHotSeatItemsCount = mLauncher.getDeviceProfile().inv.numHotseatIcons;
|
||||
@@ -229,6 +228,10 @@ public class HotseatPredictionController implements DragController.DragListener,
|
||||
} else {
|
||||
if (callback != null) callback.run();
|
||||
}
|
||||
|
||||
if (mLauncher.getTaskbarController() != null) {
|
||||
mLauncher.getTaskbarController().onHotseatUpdated();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,6 +245,10 @@ public class HotseatPredictionController implements DragController.DragListener,
|
||||
* start and pauses predicted apps update on the hotseat
|
||||
*/
|
||||
public void setPauseUIUpdate(boolean paused) {
|
||||
if (mLauncher.getTaskbarController() != null) {
|
||||
// Taskbar is present, always allow updates since hotseat is still visible.
|
||||
return;
|
||||
}
|
||||
mUIUpdatePaused = paused;
|
||||
if (!paused) {
|
||||
fillGapsWithPrediction();
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.animation.Animator;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.Point;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -36,7 +37,9 @@ import com.android.launcher3.QuickstepAppTransitionManagerImpl;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.anim.AlphaUpdateListener;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.states.StateAnimationConfig;
|
||||
import com.android.launcher3.touch.ItemClickHandler;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.systemui.shared.system.WindowManagerWrapper;
|
||||
|
||||
@@ -55,6 +58,7 @@ public class TaskbarController {
|
||||
private final Point mTaskbarSize;
|
||||
private final TaskbarStateHandler mTaskbarStateHandler;
|
||||
private final TaskbarVisibilityController mTaskbarVisibilityController;
|
||||
private final TaskbarHotseatController mHotseatController;
|
||||
|
||||
// Initialized in init().
|
||||
private WindowManager.LayoutParams mWindowLayoutParams;
|
||||
@@ -64,12 +68,15 @@ public class TaskbarController {
|
||||
mLauncher = launcher;
|
||||
mTaskbarContainerView = taskbarContainerView;
|
||||
mTaskbarView = mTaskbarContainerView.findViewById(R.id.taskbar_view);
|
||||
mTaskbarView.setCallbacks(createTaskbarViewCallbacks());
|
||||
mWindowManager = mLauncher.getWindowManager();
|
||||
mTaskbarSize = new Point(MATCH_PARENT,
|
||||
mLauncher.getResources().getDimensionPixelSize(R.dimen.taskbar_size));
|
||||
mTaskbarStateHandler = mLauncher.getTaskbarStateHandler();
|
||||
mTaskbarVisibilityController = new TaskbarVisibilityController(mLauncher,
|
||||
createTaskbarVisibilityControllerCallbacks());
|
||||
mHotseatController = new TaskbarHotseatController(mLauncher,
|
||||
createTaskbarHotseatControllerCallbacks());
|
||||
}
|
||||
|
||||
private TaskbarVisibilityControllerCallbacks createTaskbarVisibilityControllerCallbacks() {
|
||||
@@ -87,13 +94,33 @@ public class TaskbarController {
|
||||
};
|
||||
}
|
||||
|
||||
private TaskbarViewCallbacks createTaskbarViewCallbacks() {
|
||||
return new TaskbarViewCallbacks() {
|
||||
@Override
|
||||
public View.OnClickListener getItemOnClickListener() {
|
||||
return ItemClickHandler.INSTANCE;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private TaskbarHotseatControllerCallbacks createTaskbarHotseatControllerCallbacks() {
|
||||
return new TaskbarHotseatControllerCallbacks() {
|
||||
@Override
|
||||
public void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
|
||||
mTaskbarView.updateHotseatItems(hotseatItemInfos);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the Taskbar, including adding it to the screen.
|
||||
*/
|
||||
public void init() {
|
||||
mTaskbarView.init(mHotseatController.getNumHotseatIcons());
|
||||
addToWindowManager();
|
||||
mTaskbarStateHandler.setTaskbarCallbacks(createTaskbarStateHandlerCallbacks());
|
||||
mTaskbarVisibilityController.init();
|
||||
mHotseatController.init();
|
||||
}
|
||||
|
||||
private TaskbarStateHandlerCallbacks createTaskbarStateHandlerCallbacks() {
|
||||
@@ -109,9 +136,11 @@ public class TaskbarController {
|
||||
* Removes the Taskbar from the screen, and removes any obsolete listeners etc.
|
||||
*/
|
||||
public void cleanup() {
|
||||
mTaskbarView.cleanup();
|
||||
removeFromWindowManager();
|
||||
mTaskbarStateHandler.setTaskbarCallbacks(null);
|
||||
mTaskbarVisibilityController.cleanup();
|
||||
mHotseatController.cleanup();
|
||||
}
|
||||
|
||||
private void removeFromWindowManager() {
|
||||
@@ -190,6 +219,20 @@ public class TaskbarController {
|
||||
mTaskbarVisibilityController.animateToVisibilityForIme(isImeVisible ? 0 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should be called when one or more items in the Hotseat have changed.
|
||||
*/
|
||||
public void onHotseatUpdated() {
|
||||
mHotseatController.onHotseatUpdated();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the given View is in the same window as Taskbar.
|
||||
*/
|
||||
public boolean isViewInTaskbar(View v) {
|
||||
return mTaskbarContainerView.getWindowId().equals(v.getWindowId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains methods that TaskbarStateHandler can call to interface with TaskbarController.
|
||||
*/
|
||||
@@ -205,4 +248,18 @@ public class TaskbarController {
|
||||
void updateTaskbarBackgroundAlpha(float alpha);
|
||||
void updateTaskbarVisibilityAlpha(float alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains methods that TaskbarView can call to interface with TaskbarController.
|
||||
*/
|
||||
protected interface TaskbarViewCallbacks {
|
||||
View.OnClickListener getItemOnClickListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains methods that TaskbarHotseatController can call to interface with TaskbarController.
|
||||
*/
|
||||
protected interface TaskbarHotseatControllerCallbacks {
|
||||
void updateHotseatItems(ItemInfo[] hotseatItemInfos);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.view.View;
|
||||
|
||||
import com.android.launcher3.BaseQuickstepLauncher;
|
||||
import com.android.launcher3.CellLayout;
|
||||
import com.android.launcher3.DropTarget;
|
||||
import com.android.launcher3.Hotseat;
|
||||
import com.android.launcher3.ShortcutAndWidgetContainer;
|
||||
import com.android.launcher3.dragndrop.DragController;
|
||||
import com.android.launcher3.dragndrop.DragOptions;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
|
||||
/**
|
||||
* Works with TaskbarController to update the TaskbarView's Hotseat items.
|
||||
*/
|
||||
public class TaskbarHotseatController {
|
||||
|
||||
private final BaseQuickstepLauncher mLauncher;
|
||||
private final Hotseat mHotseat;
|
||||
private final TaskbarController.TaskbarHotseatControllerCallbacks mTaskbarCallbacks;
|
||||
private final int mNumHotseatIcons;
|
||||
|
||||
private final DragController.DragListener mDragListener = new DragController.DragListener() {
|
||||
@Override
|
||||
public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDragEnd() {
|
||||
onHotseatUpdated();
|
||||
}
|
||||
};
|
||||
|
||||
public TaskbarHotseatController(BaseQuickstepLauncher launcher,
|
||||
TaskbarController.TaskbarHotseatControllerCallbacks taskbarCallbacks) {
|
||||
mLauncher = launcher;
|
||||
mHotseat = mLauncher.getHotseat();
|
||||
mTaskbarCallbacks = taskbarCallbacks;
|
||||
mNumHotseatIcons = mLauncher.getDeviceProfile().inv.numHotseatIcons;
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
mLauncher.getDragController().addDragListener(mDragListener);
|
||||
}
|
||||
|
||||
protected void cleanup() {
|
||||
mLauncher.getDragController().removeDragListener(mDragListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when any Hotseat item changes, and reports the new list of items to TaskbarController.
|
||||
*/
|
||||
protected void onHotseatUpdated() {
|
||||
ShortcutAndWidgetContainer shortcutsAndWidgets = mHotseat.getShortcutsAndWidgets();
|
||||
ItemInfo[] hotseatItemInfos = new ItemInfo[mNumHotseatIcons];
|
||||
for (int i = 0; i < shortcutsAndWidgets.getChildCount(); i++) {
|
||||
View child = shortcutsAndWidgets.getChildAt(i);
|
||||
Object tag = shortcutsAndWidgets.getChildAt(i).getTag();
|
||||
if (tag instanceof ItemInfo) {
|
||||
ItemInfo itemInfo = (ItemInfo) tag;
|
||||
CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
|
||||
// Since the hotseat might be laid out vertically or horizontally, use whichever
|
||||
// index is higher.
|
||||
hotseatItemInfos[Math.max(lp.cellX, lp.cellY)] = itemInfo;
|
||||
}
|
||||
}
|
||||
|
||||
mTaskbarCallbacks.updateHotseatItems(hotseatItemInfos);
|
||||
}
|
||||
|
||||
protected int getNumHotseatIcons() {
|
||||
return mNumHotseatIcons;
|
||||
}
|
||||
}
|
||||
@@ -16,19 +16,35 @@
|
||||
package com.android.launcher3.taskbar;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.LayoutRes;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BubbleTextView;
|
||||
import com.android.launcher3.R;
|
||||
import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.model.data.WorkspaceItemInfo;
|
||||
|
||||
/**
|
||||
* Hosts the Taskbar content such as Hotseat and Recent Apps. Drawn on top of other apps.
|
||||
*/
|
||||
public class TaskbarView extends LinearLayout {
|
||||
|
||||
private final ColorDrawable mBackgroundDrawable;
|
||||
private final int mItemMarginLeftRight;
|
||||
|
||||
// Initialized in init().
|
||||
private int mHotseatStartIndex;
|
||||
private int mHotseatEndIndex;
|
||||
|
||||
private TaskbarController.TaskbarViewCallbacks mControllerCallbacks;
|
||||
|
||||
public TaskbarView(@NonNull Context context) {
|
||||
this(context, null);
|
||||
@@ -46,7 +62,24 @@ public class TaskbarView extends LinearLayout {
|
||||
public TaskbarView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
|
||||
Resources resources = getResources();
|
||||
mBackgroundDrawable = (ColorDrawable) getBackground();
|
||||
mItemMarginLeftRight = resources.getDimensionPixelSize(R.dimen.taskbar_icon_spacing);
|
||||
}
|
||||
|
||||
protected void setCallbacks(TaskbarController.TaskbarViewCallbacks taskbarViewCallbacks) {
|
||||
mControllerCallbacks = taskbarViewCallbacks;
|
||||
}
|
||||
|
||||
protected void init(int numHotseatIcons) {
|
||||
mHotseatStartIndex = 0;
|
||||
mHotseatEndIndex = mHotseatStartIndex + numHotseatIcons - 1;
|
||||
updateHotseatItems(new ItemInfo[numHotseatIcons]);
|
||||
}
|
||||
|
||||
protected void cleanup() {
|
||||
removeAllViews();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,4 +89,47 @@ public class TaskbarView extends LinearLayout {
|
||||
public void setBackgroundAlpha(float alpha) {
|
||||
mBackgroundDrawable.setAlpha((int) (alpha * 255));
|
||||
}
|
||||
|
||||
/**
|
||||
* Inflates/binds the Hotseat views to show in the Taskbar given their ItemInfos.
|
||||
*/
|
||||
protected void updateHotseatItems(ItemInfo[] hotseatItemInfos) {
|
||||
for (int i = 0; i < hotseatItemInfos.length; i++) {
|
||||
ItemInfo hotseatItemInfo = hotseatItemInfos[i];
|
||||
int hotseatIndex = mHotseatStartIndex + i;
|
||||
View hotseatView = getChildAt(hotseatIndex);
|
||||
|
||||
// Replace any Hotseat views with the appropriate type if it's not already that type.
|
||||
final int expectedLayoutResId;
|
||||
if (hotseatItemInfo != null && hotseatItemInfo.isPredictedItem()) {
|
||||
expectedLayoutResId = R.layout.taskbar_predicted_app_icon;
|
||||
} else {
|
||||
expectedLayoutResId = R.layout.taskbar_app_icon;
|
||||
}
|
||||
if (hotseatView == null || hotseatView.getSourceLayoutResId() != expectedLayoutResId) {
|
||||
removeView(hotseatView);
|
||||
BubbleTextView btv = (BubbleTextView) inflate(expectedLayoutResId);
|
||||
LayoutParams lp = new LayoutParams(btv.getIconSize(), btv.getIconSize());
|
||||
lp.setMargins(mItemMarginLeftRight, 0, mItemMarginLeftRight, 0);
|
||||
hotseatView = btv;
|
||||
addView(hotseatView, hotseatIndex, lp);
|
||||
}
|
||||
|
||||
// Apply the Hotseat ItemInfos, or hide the view if there is none for a given index.
|
||||
if (hotseatView instanceof BubbleTextView
|
||||
&& hotseatItemInfo instanceof WorkspaceItemInfo) {
|
||||
((BubbleTextView) hotseatView).applyFromWorkspaceItem(
|
||||
(WorkspaceItemInfo) hotseatItemInfo);
|
||||
hotseatView.setVisibility(VISIBLE);
|
||||
hotseatView.setOnClickListener(mControllerCallbacks.getItemOnClickListener());
|
||||
} else {
|
||||
hotseatView.setVisibility(GONE);
|
||||
hotseatView.setOnClickListener(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private View inflate(@LayoutRes int layoutResId) {
|
||||
return LayoutInflater.from(getContext()).inflate(layoutResId, this, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,10 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView implements
|
||||
}
|
||||
|
||||
private int getOutlineOffsetY() {
|
||||
return getPaddingTop() + mDeviceProfile.folderIconOffsetYPx;
|
||||
if (mDisplay != DISPLAY_TASKBAR) {
|
||||
return getPaddingTop() + mDeviceProfile.folderIconOffsetYPx;
|
||||
}
|
||||
return (getMeasuredHeight() / 2) - mNormalizedIconRadius;
|
||||
}
|
||||
|
||||
private void drawEffect(Canvas canvas, boolean isBadged) {
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
<enum name="widget_section" value="3" />
|
||||
<enum name="shortcut_popup" value="4" />
|
||||
<enum name="hero_app" value="5" />
|
||||
<enum name="taskbar" value="6" />
|
||||
</attr>
|
||||
<attr name="centerVertically" format="boolean" />
|
||||
</declare-styleable>
|
||||
|
||||
@@ -92,6 +92,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
private static final int DISPLAY_ALL_APPS = 1;
|
||||
private static final int DISPLAY_FOLDER = 2;
|
||||
private static final int DISPLAY_HERO_APP = 5;
|
||||
protected static final int DISPLAY_TASKBAR = 6;
|
||||
|
||||
private static final int[] STATE_PRESSED = new int[]{android.R.attr.state_pressed};
|
||||
private static final float HIGHLIGHT_SCALE = 1.16f;
|
||||
@@ -140,7 +141,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
private Drawable mIcon;
|
||||
private boolean mCenterVertically;
|
||||
|
||||
private final int mDisplay;
|
||||
protected final int mDisplay;
|
||||
|
||||
private final CheckLongPressHelper mLongPressHelper;
|
||||
|
||||
@@ -206,6 +207,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
defaultIconSize = grid.folderChildIconSizePx;
|
||||
} else if (mDisplay == DISPLAY_HERO_APP) {
|
||||
defaultIconSize = grid.allAppsIconSizePx;
|
||||
} else if (mDisplay == DISPLAY_TASKBAR) {
|
||||
defaultIconSize = grid.iconSizePx;
|
||||
} else {
|
||||
// widget_selection or shortcut_popup
|
||||
defaultIconSize = grid.iconSizePx;
|
||||
@@ -487,6 +490,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
|
||||
* @param canvas The canvas to draw to.
|
||||
*/
|
||||
protected void drawDotIfNecessary(Canvas canvas) {
|
||||
if (mDisplay == DISPLAY_TASKBAR) {
|
||||
// TODO: support notification dots in Taskbar
|
||||
return;
|
||||
}
|
||||
if (!mForceHideDot && (hasDot() || mDotParams.scale > 0)) {
|
||||
getIconBounds(mDotParams.iconBounds);
|
||||
Utilities.scaleRectAboutCenter(mDotParams.iconBounds,
|
||||
|
||||
@@ -1917,6 +1917,13 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
|
||||
@Override
|
||||
public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
|
||||
if (isViewInTaskbar(v)) {
|
||||
// Start the activity without the hacky workarounds below, which assume the View was
|
||||
// clicked when Launcher was resumed and will be hidden until Launcher is re-resumed
|
||||
// (this isn't the case for Taskbar).
|
||||
return super.startActivitySafely(v, intent, item);
|
||||
}
|
||||
|
||||
if (!hasBeenResumed()) {
|
||||
// Workaround an issue where the WM launch animation is clobbered when finishing the
|
||||
// recents animation into launcher. Defer launching the activity until Launcher is
|
||||
@@ -2818,6 +2825,13 @@ public class Launcher extends StatefulActivity<LauncherState> implements Launche
|
||||
.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Whether the View is in the same window as the Taskbar window.
|
||||
*/
|
||||
public boolean isViewInTaskbar(View v) {
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class NonConfigInstance {
|
||||
public Configuration config;
|
||||
public Bitmap snapshot;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class LauncherAppTransitionManager implements ResourceBasedOverride {
|
||||
return ActivityOptions.makeClipRevealAnimation(v, left, top, width, height);
|
||||
}
|
||||
|
||||
public boolean supportsAdaptiveIconAnimation() {
|
||||
public boolean supportsAdaptiveIconAnimation(View clickedView) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -302,7 +302,7 @@ public class ItemClickHandler {
|
||||
intent.setPackage(null);
|
||||
}
|
||||
}
|
||||
if (v != null && launcher.getAppTransitionManager().supportsAdaptiveIconAnimation()) {
|
||||
if (v != null && launcher.getAppTransitionManager().supportsAdaptiveIconAnimation(v)) {
|
||||
// Preload the icon to reduce latency b/w swapping the floating view with the original.
|
||||
FloatingIconView.fetchIcon(launcher, v, item, true /* isOpening */);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user