From 1f06427266c0cb5de4561fc7c620ff542f625300 Mon Sep 17 00:00:00 2001 From: Winson Date: Mon, 18 Jul 2016 17:18:02 -0700 Subject: Initial changes to tweak layout. - Adding DeviceProfile callback for when the launcher layout changes due to insets. This is necessary since there are now different layouts depending on which side the navigation bar is on - Consolidating hotseat and other layout into the device profile launcher layout logic - Making the all apps icons match the workspace icon height - Tweaking caret drawable to draw to the bounds specified to simplify layout in each orientation - Fixing minor issue with page indicator shifting in landscape - Centering overview buttons to the workspace page Bug: 30021487 Change-Id: I1866bce00b2948f3edd06168c0f88d81207e3f13 --- res/layout-land/launcher.xml | 5 +- res/layout-port/launcher.xml | 3 +- res/layout-sw720dp/launcher.xml | 3 +- res/layout/all_apps.xml | 8 +- res/layout/all_apps_icon.xml | 5 +- res/layout/widgets_view.xml | 2 - res/values-sw600dp-land/dimens.xml | 20 --- res/values-sw600dp/dimens.xml | 6 - res/values-sw720dp/dimens.xml | 1 - res/values-sw768dp-port/dimens.xml | 20 --- res/values/attrs.xml | 1 + res/values/dimens.xml | 30 ++-- src/com/android/launcher3/BaseContainerView.java | 98 +++++++---- src/com/android/launcher3/BubbleTextView.java | 19 +- src/com/android/launcher3/DeviceProfile.java | 196 +++++++++++++-------- src/com/android/launcher3/Hotseat.java | 27 +-- src/com/android/launcher3/IconCache.java | 3 +- .../android/launcher3/InvariantDeviceProfile.java | 6 +- src/com/android/launcher3/Launcher.java | 7 +- src/com/android/launcher3/LauncherRootView.java | 7 + .../launcher3/ShortcutAndWidgetContainer.java | 2 +- src/com/android/launcher3/Workspace.java | 18 +- .../launcher3/allapps/AllAppsContainerView.java | 12 +- .../launcher3/allapps/AllAppsGridAdapter.java | 13 ++ .../launcher3/allapps/AllAppsRecyclerView.java | 7 +- .../allapps/AllAppsTransitionController.java | 12 +- .../launcher3/pageindicators/CaretDrawable.java | 16 +- .../PageIndicatorCaretLandscape.java | 27 +-- .../pageindicators/PageIndicatorLineCaret.java | 14 +- .../launcher3/widget/WidgetsContainerView.java | 27 +-- 30 files changed, 330 insertions(+), 285 deletions(-) delete mode 100644 res/values-sw600dp-land/dimens.xml delete mode 100644 res/values-sw768dp-port/dimens.xml diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml index 632aff04b..5c1fec7e3 100644 --- a/res/layout-land/launcher.xml +++ b/res/layout-land/launcher.xml @@ -44,7 +44,8 @@ android:id="@+id/hotseat" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_gravity="right" /> + android:layout_gravity="right" + launcher:layout_ignoreInsets="true" /> diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml index 0321631ca..b394fa835 100644 --- a/res/layout-port/launcher.xml +++ b/res/layout-port/launcher.xml @@ -45,7 +45,8 @@ + android:layout_height="match_parent" + launcher:layout_ignoreInsets="true" /> + android:layout_height="match_parent" + launcher:layout_ignoreInsets="true" /> + android:saveEnabled="false"> + launcher:iconDisplay="all_apps" + launcher:centerVertically="true" /> diff --git a/res/layout/widgets_view.xml b/res/layout/widgets_view.xml index 74f7ca10b..c4431be25 100644 --- a/res/layout/widgets_view.xml +++ b/res/layout/widgets_view.xml @@ -22,8 +22,6 @@ android:id="@+id/widgets_view" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingTop="@dimen/container_bounds_inset" - android:paddingBottom="@dimen/container_bounds_inset" android:descendantFocusability="afterDescendants" launcher:revealBackground="@drawable/quantum_panel_shape_dark" android:theme="@style/WidgetContainerTheme"> diff --git a/res/values-sw600dp-land/dimens.xml b/res/values-sw600dp-land/dimens.xml deleted file mode 100644 index 1f97d2460..000000000 --- a/res/values-sw600dp-land/dimens.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - 736dp - diff --git a/res/values-sw600dp/dimens.xml b/res/values-sw600dp/dimens.xml index 85a436cf9..283808805 100644 --- a/res/values-sw600dp/dimens.xml +++ b/res/values-sw600dp/dimens.xml @@ -15,21 +15,15 @@ --> - - 16dp - 0dp 26sp - 12dp 850dp 525dp - 36dp 56dp - -1000dp diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml index c2d20a310..358d9b6a0 100644 --- a/res/values-sw720dp/dimens.xml +++ b/res/values-sw720dp/dimens.xml @@ -18,7 +18,6 @@ 8dp 54dp - 14dp 64dp 180dp diff --git a/res/values-sw768dp-port/dimens.xml b/res/values-sw768dp-port/dimens.xml deleted file mode 100644 index 6fb2bf69a..000000000 --- a/res/values-sw768dp-port/dimens.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - 736dp - diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 308c71c41..3cfaf02d0 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -29,6 +29,7 @@ + - 6dp - 24dp + 8dp + 28dp 1dp 12dp - 4dp - 8dp + 38dp + 48dp + 8dp 80dp 120dp 80dp - 20dp - + 25dp + 88dp + 12dp + 24dp 12dp + 8dp 8dp + 118dp + 66dp 48dp @@ -54,28 +60,23 @@ 72dp 48dp - 0% - 8dp - 0dp - 0dp 0dp 8dp 24sp 60dp - 5dp + 12dp 4dp 1dp - 8dp - 24dp 8dp 40dp 144dp 700dp 475dp 2dp - 8dp + 13dp + 4dp 3dp @@ -85,6 +86,7 @@ 8dp 24dp + 8dp 8dp diff --git a/src/com/android/launcher3/BaseContainerView.java b/src/com/android/launcher3/BaseContainerView.java index 57a60a95d..96942ee6f 100644 --- a/src/com/android/launcher3/BaseContainerView.java +++ b/src/com/android/launcher3/BaseContainerView.java @@ -18,7 +18,6 @@ package com.android.launcher3; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.Color; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.InsetDrawable; @@ -32,12 +31,16 @@ import com.android.launcher3.config.FeatureFlags; /** * A base container view, which supports resizing. */ -public abstract class BaseContainerView extends FrameLayout { +public abstract class BaseContainerView extends FrameLayout + implements DeviceProfile.LauncherLayoutChangeListener { - protected final int mHorizontalPadding; + protected int mContainerPaddingLeft; + protected int mContainerPaddingRight; + protected int mContainerPaddingTop; + protected int mContainerPaddingBottom; - private final InsetDrawable mRevealDrawable; - private final ColorDrawable mDrawable; + private InsetDrawable mRevealDrawable; + protected final Drawable mBaseDrawable; private View mRevealView; private View mContent; @@ -53,31 +56,32 @@ public abstract class BaseContainerView extends FrameLayout { public BaseContainerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); - Launcher launcher = Launcher.getLauncher(context); - int width = launcher.getDeviceProfile().availableWidthPx; - if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && - this instanceof AllAppsContainerView && - !launcher.getDeviceProfile().isVerticalBarLayout()) { - mHorizontalPadding = 0; - } else { - mHorizontalPadding = DeviceProfile.getContainerPadding(context, width); - } - if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && this instanceof AllAppsContainerView) { - mDrawable = new ColorDrawable(); - mRevealDrawable = new InsetDrawable(mDrawable, - mHorizontalPadding, 0, mHorizontalPadding, 0); + mBaseDrawable = new ColorDrawable(); } else { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BaseContainerView, defStyleAttr, 0); - mRevealDrawable = new InsetDrawable( - a.getDrawable(R.styleable.BaseContainerView_revealBackground), - mHorizontalPadding, 0, mHorizontalPadding, 0); - mDrawable = null; + mBaseDrawable = a.getDrawable(R.styleable.BaseContainerView_revealBackground); a.recycle(); } } + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + + DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile(); + grid.addLauncherLayoutChangedListener(this); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + + DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile(); + grid.removeLauncherLayoutChangedListener(this); + } + @Override protected void onFinishInflate() { super.onFinishInflate(); @@ -85,16 +89,16 @@ public abstract class BaseContainerView extends FrameLayout { mContent = findViewById(R.id.main_content); mRevealView = findViewById(R.id.reveal_view); - if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && this instanceof AllAppsContainerView) { - mRevealView.setBackground(mRevealDrawable); - } else { - mRevealView.setBackground(mRevealDrawable.getConstantState().newDrawable()); - mContent.setBackground(mRevealDrawable); - } + updatePaddings(); + } - // We let the content have a intent background, but still have full width. - // This allows the scroll bar to be used responsive outside the background bounds as well. - mContent.setPadding(0, 0, 0, 0); + @Override + public void onLauncherLayoutChanged() { + updatePaddings(); + } + + public void setRevealDrawableColor(int color) { + ((ColorDrawable) mBaseDrawable).setColor(color); } public final View getContentView() { @@ -105,7 +109,35 @@ public abstract class BaseContainerView extends FrameLayout { return mRevealView; } - public void setRevealDrawableColor(int color) { - mDrawable.setColor(color); + private void updatePaddings() { + Context context = getContext(); + Launcher launcher = Launcher.getLauncher(context); + + if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && + this instanceof AllAppsContainerView && + !launcher.getDeviceProfile().isVerticalBarLayout()) { + mContainerPaddingLeft = mContainerPaddingRight = 0; + mContainerPaddingTop = mContainerPaddingBottom = 0; + } else { + DeviceProfile grid = launcher.getDeviceProfile(); + int[] padding = grid.getContainerPadding(context); + mContainerPaddingLeft = padding[0] + grid.edgeMarginPx; + mContainerPaddingRight = padding[1] + grid.edgeMarginPx; + if (!launcher.getDeviceProfile().isVerticalBarLayout()) { + mContainerPaddingTop = mContainerPaddingBottom = grid.edgeMarginPx; + } else { + mContainerPaddingTop = mContainerPaddingBottom = 0; + } + } + + mRevealDrawable = new InsetDrawable(mBaseDrawable, + mContainerPaddingLeft, mContainerPaddingTop, mContainerPaddingRight, + mContainerPaddingBottom); + mRevealView.setBackground(mRevealDrawable); + if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP && this instanceof AllAppsContainerView) { + // Skip updating the content background + } else { + mContent.setBackground(mRevealDrawable); + } } } diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 33e4e2a67..00ec4c2ff 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -24,6 +24,7 @@ import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; +import android.graphics.Paint; import android.graphics.Region; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -66,6 +67,7 @@ public class BubbleTextView extends TextView private final Launcher mLauncher; private Drawable mIcon; + private final boolean mCenterVertically; private final Drawable mBackground; private OnLongClickListener mOnLongClickListener; private final CheckLongPressHelper mLongPressHelper; @@ -119,9 +121,11 @@ public class BubbleTextView extends TextView if (display == DISPLAY_WORKSPACE) { setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx); } else if (display == DISPLAY_ALL_APPS) { - setTextSize(TypedValue.COMPLEX_UNIT_SP, grid.allAppsIconTextSizeSp); + setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx); + setCompoundDrawablePadding(grid.allAppsIconDrawablePaddingPx); defaultIconSize = grid.allAppsIconSizePx; } + mCenterVertically = a.getBoolean(R.styleable.BubbleTextView_centerVertically, false); mIconSize = a.getDimensionPixelSize(R.styleable.BubbleTextView_iconSizeOverride, defaultIconSize); @@ -427,6 +431,19 @@ public class BubbleTextView extends TextView mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + if (mCenterVertically) { + Paint.FontMetrics fm = getPaint().getFontMetrics(); + int cellHeightPx = mIconSize + getCompoundDrawablePadding() + + (int) Math.ceil(fm.bottom - fm.top); + int height = MeasureSpec.getSize(heightMeasureSpec); + setPadding(getPaddingLeft(), (height - cellHeightPx) / 2, getPaddingRight(), + getPaddingBottom()); + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 2b130e5a7..ac86f0b74 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -29,13 +29,18 @@ import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; -import android.view.ViewGroup.MarginLayoutParams; import android.widget.FrameLayout; import com.android.launcher3.config.FeatureFlags; +import java.util.ArrayList; + public class DeviceProfile { + public interface LauncherLayoutChangeListener { + void onLauncherLayoutChanged(); + } + public final InvariantDeviceProfile inv; // Device properties @@ -68,13 +73,18 @@ public class DeviceProfile { private int desiredWorkspaceLeftRightMarginPx; public final int edgeMarginPx; public final Rect defaultWidgetPadding; - private final int pageIndicatorHeightPx; private final int defaultPageSpacingPx; private final int topWorkspacePadding; private float dragViewScale; public float workspaceSpringLoadShrinkFactor; public final int workspaceSpringLoadedBottomSpace; + // Page indicator + private final int pageIndicatorHeightPx; + private final int pageIndicatorLandGutterLeftNavBarPx; + private final int pageIndicatorLandGutterRightNavBarPx; + private final int pageIndicatorLandWorkspaceOffsetPx; + // Workspace icons public int iconSizePx; public int iconTextSizePx; @@ -96,17 +106,30 @@ public class DeviceProfile { public int hotseatCellHeightPx; public int hotseatIconSizePx; private int hotseatBarHeightPx; + private int hotseatBarTopPaddingPx; + private int hotseatLandGutterPx; // All apps public int allAppsNumCols; public int allAppsNumPredictiveCols; public int allAppsButtonVisualSize; - public final int allAppsIconSizePx; - public final float allAppsIconTextSizeSp; + public int allAppsIconSizePx; + public int allAppsIconDrawablePaddingPx; + public float allAppsIconTextSizePx; + + // Containers + private final int containerLeftPaddingPx; + private final int containerRightPaddingPx; // Drop Target public int dropTargetBarSizePx; + // Insets + private Rect mInsets = new Rect(); + + // Listeners + private ArrayList mListeners = new ArrayList<>(); + public DeviceProfile(Context context, InvariantDeviceProfile inv, Point minSize, Point maxSize, int width, int height, boolean isLandscape) { @@ -130,9 +153,15 @@ public class DeviceProfile { this.getClass().getName()); defaultWidgetPadding = AppWidgetHostView.getDefaultPaddingForWidget(context, cn, null); edgeMarginPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_edge_margin); - desiredWorkspaceLeftRightMarginPx = 2 * edgeMarginPx; + desiredWorkspaceLeftRightMarginPx = edgeMarginPx; pageIndicatorHeightPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_height); + pageIndicatorLandGutterLeftNavBarPx = res.getDimensionPixelSize( + R.dimen.dynamic_grid_page_indicator_gutter_width_left_nav_bar); + pageIndicatorLandWorkspaceOffsetPx = + res.getDimensionPixelSize(R.dimen.all_apps_caret_workspace_offset); + pageIndicatorLandGutterRightNavBarPx = res.getDimensionPixelSize( + R.dimen.dynamic_grid_page_indicator_gutter_width_right_nav_bar); defaultPageSpacingPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_workspace_page_spacing); topWorkspacePadding = @@ -152,12 +181,14 @@ public class DeviceProfile { dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size); workspaceSpringLoadedBottomSpace = res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space); - - // AllApps uses the original non-scaled icon text size - allAppsIconTextSizeSp = inv.iconTextSize; - - // AllApps uses the original non-scaled icon size - allAppsIconSizePx = Utilities.pxFromDp(inv.iconSize, dm); + hotseatBarHeightPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height); + hotseatBarTopPaddingPx = + res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding); + hotseatLandGutterPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_gutter_width); + containerLeftPaddingPx = + res.getDimensionPixelSize(R.dimen.dynamic_grid_container_land_left_padding); + containerRightPaddingPx = + res.getDimensionPixelSize(R.dimen.dynamic_grid_container_land_right_padding); // Determine sizes. widthPx = width; @@ -175,6 +206,18 @@ public class DeviceProfile { computeAllAppsButtonSize(context); } + public void addLauncherLayoutChangedListener(LauncherLayoutChangeListener listener) { + if (!mListeners.contains(listener)) { + mListeners.add(listener); + } + } + + public void removeLauncherLayoutChangedListener(LauncherLayoutChangeListener listener) { + if (mListeners.contains(listener)) { + mListeners.remove(listener); + } + } + /** * Determine the exact visual footprint of the all apps button, taking into account scaling * and internal padding of the drawable. @@ -208,6 +251,9 @@ public class DeviceProfile { iconTextSizePx = (int) (Utilities.pxFromSp(inv.iconTextSize, dm) * scale); iconDrawablePaddingPx = drawablePadding; hotseatIconSizePx = (int) (Utilities.pxFromDp(inv.hotseatIconSize, dm) * scale); + allAppsIconSizePx = iconSizePx; + allAppsIconDrawablePaddingPx = iconDrawablePaddingPx; + allAppsIconTextSizePx = iconTextSizePx; // Calculate the actual text height Paint textPaint = new Paint(); @@ -220,7 +266,6 @@ public class DeviceProfile { dragViewScale = (iconSizePx + scaleDps) / iconSizePx; // Hotseat - hotseatBarHeightPx = iconSizePx + 4 * edgeMarginPx; hotseatCellWidthPx = iconSizePx; hotseatCellHeightPx = iconSizePx; @@ -247,20 +292,15 @@ public class DeviceProfile { folderIconPreviewPadding = res.getDimensionPixelSize(R.dimen.folder_preview_padding); } + public void updateInsets(Rect insets) { + mInsets.set(insets); + } + /** * @param recyclerViewWidth the available width of the AllAppsRecyclerView */ - public void updateAppsViewNumCols(Resources res, int recyclerViewWidth) { - int appsViewLeftMarginPx = - res.getDimensionPixelSize(R.dimen.all_apps_grid_view_start_margin); - int allAppsCellWidthGap = - res.getDimensionPixelSize(R.dimen.all_apps_icon_width_gap); - int availableAppsWidthPx = (recyclerViewWidth > 0) ? recyclerViewWidth : availableWidthPx; - int numAppsCols = (availableAppsWidthPx + allAppsCellWidthGap - appsViewLeftMarginPx) / - (allAppsIconSizePx + allAppsCellWidthGap); - int numPredictiveAppCols = Math.max(inv.minAllAppsPredictionColumns, numAppsCols); - allAppsNumCols = numAppsCols; - allAppsNumPredictiveCols = numPredictiveAppCols; + public void updateAppsViewNumCols() { + allAppsNumCols = allAppsNumPredictiveCols = inv.numColumns; } /** Returns the width and height of the search bar, ignoring any padding. */ @@ -309,9 +349,13 @@ public class DeviceProfile { public Rect getWorkspacePadding(Rect recycle) { Rect padding = recycle == null ? new Rect() : recycle; if (isVerticalBarLayout()) { - // in case of isVerticalBarLayout, the hotseat is always on the right and the drop - // target bar is on the left, independent of the layout direction. - padding.set(dropTargetBarSizePx, edgeMarginPx, hotseatBarHeightPx, edgeMarginPx); + if (mInsets.left > 0) { + padding.set(mInsets.left + pageIndicatorLandGutterLeftNavBarPx, 0, + hotseatBarHeightPx + hotseatLandGutterPx - mInsets.left, 2 * edgeMarginPx); + } else { + padding.set(pageIndicatorLandGutterRightNavBarPx, 0, + hotseatBarHeightPx + hotseatLandGutterPx, 2 * edgeMarginPx); + } } else { int paddingBottom = hotseatBarHeightPx + pageIndicatorHeightPx; if (isTablet) { @@ -331,10 +375,10 @@ public class DeviceProfile { availablePaddingX / 2, paddingBottom + availablePaddingY / 2); } else { // Pad the top and bottom of the workspace with search/hotseat bar sizes - padding.set(desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.left, + padding.set(desiredWorkspaceLeftRightMarginPx, topWorkspacePadding, - desiredWorkspaceLeftRightMarginPx - defaultWidgetPadding.right, - paddingBottom); + desiredWorkspaceLeftRightMarginPx, + hotseatBarHeightPx + pageIndicatorHeightPx); } } return padding; @@ -389,7 +433,7 @@ public class DeviceProfile { return visibleChildren; } - public void layout(Launcher launcher) { + public void layout(Launcher launcher, boolean notifyListeners) { FrameLayout.LayoutParams lp; boolean hasVerticalBarLayout = isVerticalBarLayout(); final boolean isLayoutRtl = Utilities.isRtl(launcher.getResources()); @@ -400,18 +444,19 @@ public class DeviceProfile { lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams(); lp.width = searchBarBounds.x; lp.height = searchBarBounds.y; - lp.topMargin = edgeMarginPx; + lp.topMargin = mInsets.top + edgeMarginPx; searchBar.setLayoutParams(lp); // Layout the workspace PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace); - Rect padding = getWorkspacePadding(null); - workspace.setPadding(padding.left, padding.top, padding.right, padding.bottom); + Rect workspacePadding = getWorkspacePadding(null); + workspace.setPadding(workspacePadding.left, workspacePadding.top, workspacePadding.right, + workspacePadding.bottom); workspace.setPageSpacing(getWorkspacePageSpacing()); View qsbContainer = launcher.getQsbContainer(); lp = (FrameLayout.LayoutParams) qsbContainer.getLayoutParams(); - lp.topMargin = padding.top; + lp.topMargin = mInsets.top + workspacePadding.top; qsbContainer.setLayoutParams(lp); // Layout the hotseat @@ -428,26 +473,29 @@ public class DeviceProfile { // Vertical hotseat -- The hotseat is fixed in the layout to be on the right of the // screen regardless of RTL lp.gravity = Gravity.RIGHT; - lp.width = hotseatBarHeightPx; + lp.width = hotseatBarHeightPx + mInsets.left + mInsets.right; lp.height = LayoutParams.MATCH_PARENT; hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx); + hotseat.setPadding(mInsets.left, 0, mInsets.right, 0); } else if (isTablet) { // Pad the hotseat with the workspace padding calculated above lp.gravity = Gravity.BOTTOM; lp.width = LayoutParams.MATCH_PARENT; - lp.height = hotseatBarHeightPx; + lp.height = hotseatBarHeightPx + mInsets.bottom; hotseat.findViewById(R.id.layout).setPadding( - hotseatAdjustment + padding.left, 0, - hotseatAdjustment + padding.right, 2 * edgeMarginPx); + hotseatAdjustment + workspacePadding.left, 0, + hotseatAdjustment + workspacePadding.right, 2 * edgeMarginPx); + hotseat.setPadding(0, hotseatBarTopPaddingPx, 0, mInsets.bottom); } else { // For phones, layout the hotseat without any bottom margin // to ensure that we have space for the folders lp.gravity = Gravity.BOTTOM; lp.width = LayoutParams.MATCH_PARENT; - lp.height = hotseatBarHeightPx; + lp.height = hotseatBarHeightPx + mInsets.bottom; hotseat.findViewById(R.id.layout).setPadding( - hotseatAdjustment + padding.left, 0, - hotseatAdjustment + padding.right, 0); + hotseatAdjustment + workspacePadding.left, 0, + hotseatAdjustment + workspacePadding.right, 0); + hotseat.setPadding(0, hotseatBarTopPaddingPx, 0, mInsets.bottom); } hotseat.setLayoutParams(lp); @@ -455,11 +503,21 @@ public class DeviceProfile { View pageIndicator = launcher.findViewById(R.id.page_indicator); if (pageIndicator != null) { lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams(); - if (!hasVerticalBarLayout) { + if (isVerticalBarLayout()) { + if (mInsets.left > 0) { + lp.leftMargin = mInsets.left + pageIndicatorLandGutterLeftNavBarPx - + lp.width - pageIndicatorLandWorkspaceOffsetPx; + } else if (mInsets.right > 0) { + lp.leftMargin = pageIndicatorLandGutterRightNavBarPx - lp.width - + pageIndicatorLandWorkspaceOffsetPx; + } + lp.bottomMargin = workspacePadding.bottom; + } else { // Put the page indicators above the hotseat lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; lp.width = LayoutParams.WRAP_CONTENT; - lp.bottomMargin = hotseatBarHeightPx; + lp.height = pageIndicatorHeightPx; + lp.bottomMargin = hotseatBarHeightPx + mInsets.bottom; } pageIndicator.setLayoutParams(lp); } @@ -468,7 +526,7 @@ public class DeviceProfile { ViewGroup overviewMode = launcher.getOverviewPanel(); if (overviewMode != null) { lp = (FrameLayout.LayoutParams) overviewMode.getLayoutParams(); - lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; + lp.gravity = Gravity.LEFT | Gravity.BOTTOM; int visibleChildCount = getVisibleChildCount(overviewMode); int totalItemWidth = visibleChildCount * overviewModeBarItemWidthPx; @@ -476,30 +534,15 @@ public class DeviceProfile { lp.width = Math.min(availableWidthPx, maxWidth); lp.height = getOverviewModeButtonBarHeight(); + // Center the overview buttons on the workspace page + lp.leftMargin = workspacePadding.left + (availableWidthPx - + workspacePadding.left - workspacePadding.right - lp.width) / 2; overviewMode.setLayoutParams(lp); + } - if (lp.width > totalItemWidth && visibleChildCount > 1) { - // We have enough space. Lets add some margin too. - int margin = (lp.width - totalItemWidth) / (visibleChildCount-1); - View lastChild = null; - - // Set margin of all visible children except the last visible child - for (int i = 0; i < visibleChildCount; i++) { - if (lastChild != null) { - MarginLayoutParams clp = (MarginLayoutParams) lastChild.getLayoutParams(); - if (isLayoutRtl) { - clp.leftMargin = margin; - } else { - clp.rightMargin = margin; - } - lastChild.setLayoutParams(clp); - lastChild = null; - } - View thisChild = overviewMode.getChildAt(i); - if (thisChild.getVisibility() != View.GONE) { - lastChild = thisChild; - } - } + if (notifyListeners) { + for (int i = mListeners.size() - 1; i >= 0; i--) { + mListeners.get(i).onLauncherLayoutChanged(); } } } @@ -517,17 +560,20 @@ public class DeviceProfile { } - public static final int getContainerPadding(Context context, int availableWidth) { + /** + * @return the left/right paddings for all containers. + */ + public final int[] getContainerPadding(Context context) { Resources res = context.getResources(); - int maxSize = res.getDimensionPixelSize(R.dimen.container_max_width); - int minMargin = res.getDimensionPixelSize(R.dimen.container_min_margin); - - if (maxSize > 0) { - return Math.max(minMargin, (availableWidth - maxSize) / 2); - } else { - return Math.max(minMargin, - (int) res.getFraction(R.fraction.container_margin, availableWidth, 1)); + // No paddings for portrait phone + if (isPhone && !isVerticalBarLayout()) { + return new int[] {0, 0}; } + + // In landscape, we just match the vertical display width + int containerWidth = heightPx; + int padding = (availableWidthPx - containerWidth) / 2; + return new int[]{ padding, padding }; } } diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java index 7e2b42e49..084de70e3 100644 --- a/src/com/android/launcher3/Hotseat.java +++ b/src/com/android/launcher3/Hotseat.java @@ -39,7 +39,7 @@ import com.android.launcher3.userevent.nano.LauncherLogProto; import com.android.launcher3.userevent.nano.LauncherLogProto.Target; public class Hotseat extends FrameLayout - implements UserEventDispatcher.LaunchSourceProvider, Insettable { + implements UserEventDispatcher.LaunchSourceProvider { private CellLayout mContent; @@ -48,9 +48,6 @@ public class Hotseat extends FrameLayout @ViewDebug.ExportedProperty(category = "launcher") private final boolean mHasVerticalHotseat; - @ViewDebug.ExportedProperty(category = "launcher") - private Rect mInsets = new Rect(); - @ViewDebug.ExportedProperty(category = "launcher") private int mBackgroundColor; @ViewDebug.ExportedProperty(category = "launcher") @@ -180,28 +177,6 @@ public class Hotseat extends FrameLayout targetParent.containerType = LauncherLogProto.HOTSEAT; } - //Overridden so that the background color extends behind the navigation buttons. - @Override - public void setInsets(Rect insets) { - int rightInset = insets.right - mInsets.right; - int bottomInset = insets.bottom - mInsets.bottom; - mInsets.set(insets); - LayoutParams lp = (LayoutParams) getLayoutParams(); - if (mHasVerticalHotseat) { - setPadding(getPaddingLeft(), getPaddingTop(), - getPaddingRight() + rightInset, getPaddingBottom()); - if (lp.width != LayoutParams.MATCH_PARENT && lp.width != LayoutParams.WRAP_CONTENT) { - lp.width += rightInset; - } - } else { - setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), - getPaddingBottom() + bottomInset); - if (lp.height != LayoutParams.MATCH_PARENT && lp.height != LayoutParams.WRAP_CONTENT) { - lp.height += bottomInset; - } - } - } - public void updateColor(ExtractedColors extractedColors, boolean animate) { if (!mHasVerticalHotseat) { int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT); diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java index 9ce941b52..a49162c8b 100644 --- a/src/com/android/launcher3/IconCache.java +++ b/src/com/android/launcher3/IconCache.java @@ -72,6 +72,7 @@ public class IconCache { private static final String EMPTY_CLASS_NAME = "."; private static final boolean DEBUG = false; + private static final boolean DEBUG_IGNORE_CACHE = false; private static final int LOW_RES_SCALE_FACTOR = 5; @@ -552,7 +553,7 @@ public class IconCache { mCache.put(cacheKey, entry); // Check the DB first. - if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) { + if (!getEntryFromDB(cacheKey, entry, useLowResIcon) || DEBUG_IGNORE_CACHE) { if (info != null) { entry.icon = Utilities.createBadgedIconBitmap( mIconProvider.getIcon(info, mIconDpi), info.getUser(), diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 4e6911ca0..38545e2d0 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -67,6 +67,7 @@ public class InvariantDeviceProfile { /** * The minimum number of predicted apps in all apps. */ + @Deprecated int minAllAppsPredictionColumns; /** @@ -103,11 +104,6 @@ public class InvariantDeviceProfile { InvariantDeviceProfile(String n, float w, float h, int r, int c, int fr, int fc, int maapc, float is, float its, int hs, float his, int dlId) { - // Ensure that we have an odd number of hotseat items (since we need to place all apps) - if (hs % 2 == 0) { - throw new RuntimeException("All Device Profiles must have an odd number of hotseat spaces"); - } - name = n; minWidthDps = w; minHeightDps = h; diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index b7f033ef4..651e91b7b 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -438,7 +438,7 @@ public class Launcher extends Activity setContentView(R.layout.launcher); setupViews(); - mDeviceProfile.layout(this); + mDeviceProfile.layout(this, false /* notifyListeners */); mExtractedColors = new ExtractedColors(); loadExtractedColorsAndColorItems(); @@ -521,6 +521,11 @@ public class Launcher extends Activity } } + public void onInsetsChanged(Rect insets) { + mDeviceProfile.updateInsets(insets); + mDeviceProfile.layout(this, true /* notifyListeners */); + } + /** * Call this after onCreate to set or clear overlay. */ diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java index 7bcf5d00e..643d48adf 100644 --- a/src/com/android/launcher3/LauncherRootView.java +++ b/src/com/android/launcher3/LauncherRootView.java @@ -44,6 +44,7 @@ public class LauncherRootView extends InsettableFrameLayout { @TargetApi(23) @Override protected boolean fitSystemWindows(Rect insets) { + boolean rawInsetsChanged = !mInsets.equals(insets); mDrawSideInsetBar = (insets.right > 0 || insets.left > 0) && (!Utilities.ATLEAST_MARSHMALLOW || getContext().getSystemService(ActivityManager.class).isLowRamDevice()); @@ -61,6 +62,12 @@ public class LauncherRootView extends InsettableFrameLayout { } } + if (rawInsetsChanged) { + // Update the grid again + Launcher launcher = Launcher.getLauncher(getContext()); + launcher.onInsetsChanged(insets); + } + return true; // I'll take it from here } diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java index c016aa989..d98734b0f 100644 --- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java +++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java @@ -129,7 +129,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup { if (child instanceof LauncherAppWidgetHostView) { // Widgets have their own padding, so skip } else { - // Otherwise, center the icon + // Otherwise, center the icon/folder int cHeight = getCellContentHeight(); int cellPaddingY = (int) Math.max(0, ((lp.height - cHeight) / 2f)); int cellPaddingX = (int) (grid.edgeMarginPx / 2f); diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 78ef074c5..bcd87b5a9 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -53,11 +53,9 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; -import android.view.ViewGroup.LayoutParams; import android.view.accessibility.AccessibilityManager; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; -import android.widget.Space; import android.widget.TextView; import com.android.launcher3.Launcher.CustomContentCallbacks; @@ -366,16 +364,7 @@ public class Workspace extends PagedView @Override public void setInsets(Rect insets) { - int extraLeftPadding = insets.left - mInsets.left; mInsets.set(insets); - if (extraLeftPadding != 0) { - /** - * Initial layout assumes that the insets is on the right, - * {@link DeviceProfile#getWorkspacePadding()}. Compensate for the difference. - */ - setPadding(getPaddingLeft() + extraLeftPadding, getPaddingTop(), - getPaddingRight() - extraLeftPadding, getPaddingBottom()); - } CellLayout customScreen = getScreenWithId(CUSTOM_CONTENT_SCREEN_ID); if (customScreen != null) { @@ -1517,12 +1506,15 @@ public class Workspace extends PagedView /** * Moves the Hotseat UI in the provided direction. * @param direction the direction to move the workspace - * @param translation the amound of shift. + * @param translation the amount of shift. * @param alpha the alpha for the hotseat page */ public void setHotseatTranslationAndAlpha(Direction direction, float translation, float alpha) { Property property = direction.viewProperty; - property.set(mPageIndicator, translation); + // Skip the page indicator movement in the vertical bar layout + if (direction != Direction.Y || !mLauncher.getDeviceProfile().isVerticalBarLayout()) { + property.set(mPageIndicator, translation); + } property.set(mLauncher.getHotseat(), translation); setHotseatAlphaAtIndex(alpha, direction.ordinal()); } diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java index cc969343c..3ef510c3f 100644 --- a/src/com/android/launcher3/allapps/AllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java @@ -347,12 +347,10 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc int widthPx = MeasureSpec.getSize(widthMeasureSpec); int heightPx = MeasureSpec.getSize(heightMeasureSpec); updatePaddingsAndMargins(widthPx, heightPx); - mContentBounds.set(mHorizontalPadding, 0, widthPx - mHorizontalPadding, heightPx); + mContentBounds.set(mContainerPaddingLeft, 0, widthPx - mContainerPaddingRight, heightPx); DeviceProfile grid = mLauncher.getDeviceProfile(); - int availableWidth = (!mContentBounds.isEmpty() ? mContentBounds.width() : widthPx) - - 2 * mAppsRecyclerView.getMaxScrollbarWidth(); - grid.updateAppsViewNumCols(getResources(), availableWidth); + grid.updateAppsViewNumCols(); if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) { if (mNumAppsPerRow != grid.inv.numColumns || mNumPredictedAppsPerRow != grid.inv.numColumns) { @@ -368,9 +366,9 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc getResources().getDimensionPixelSize( R.dimen.container_fastscroll_thumb_max_width); mSearchContainer.setPadding( - rvPadding - mHorizontalPadding + thumbMaxWidth, + rvPadding - mContainerPaddingLeft + thumbMaxWidth, mSearchContainer.getPaddingTop(), - rvPadding - mHorizontalPadding + thumbMaxWidth, + rvPadding - mContainerPaddingRight + thumbMaxWidth, mSearchContainer.getPaddingBottom()); } } @@ -383,7 +381,7 @@ public class AllAppsContainerView extends BaseContainerView implements DragSourc // Update the number of items in the grid before we measure the view // TODO: mSectionNamesMargin is currently 0, but also account for it, // if it's enabled in the future. - grid.updateAppsViewNumCols(getResources(), availableWidth); + grid.updateAppsViewNumCols(); if (mNumAppsPerRow != grid.allAppsNumCols || mNumPredictedAppsPerRow != grid.allAppsNumPredictiveCols) { mNumAppsPerRow = grid.allAppsNumCols; diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index 0f0c333f4..97c46b163 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -20,6 +20,7 @@ import android.content.Intent; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; import android.support.v4.view.accessibility.AccessibilityEventCompat; @@ -37,6 +38,8 @@ import android.widget.TextView; import com.android.launcher3.AppInfo; import com.android.launcher3.BubbleTextView; +import com.android.launcher3.CellLayout; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -331,7 +334,9 @@ public class AllAppsGridAdapter extends RecyclerView.Adapter PAINT_ALPHA = new Property(Integer.class, "paint_alpha") { @@ -123,14 +125,18 @@ public class PageIndicatorLineCaret extends PageIndicator { public PageIndicatorLineCaret(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + + Resources res = context.getResources(); mLinePaint = new Paint(); mLinePaint.setAlpha(0); + mCaretSizePx = res.getDimensionPixelSize(R.dimen.all_apps_caret_size); + mCaretWorkspaceOffsetPx = res.getDimensionPixelSize( + R.dimen.all_apps_caret_workspace_offset); mLauncher = (Launcher) context; setOnTouchListener(mLauncher.getHapticFeedbackTouchListener()); setOnClickListener(mLauncher); setOnFocusChangeListener(mLauncher.mFocusHandler); - Resources res = context.getResources(); setCaretDrawable(new CaretDrawable(context)); mLineHeight = res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_line_height); mTouchExtensionHeight = res.getDimensionPixelSize( @@ -140,9 +146,9 @@ public class PageIndicatorLineCaret extends PageIndicator { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - int size = bottom - top; - int l = (right - left) / 2 - size / 2; - getCaretDrawable().setBounds(l, 0, l + size, size); + // Top/center align the caret in the page indicator space + int l = (right - left) / 2 - mCaretSizePx / 2; + getCaretDrawable().setBounds(l, mCaretWorkspaceOffsetPx, l + mCaretSizePx, mCaretSizePx); // The touch area is expanded below this view by #mTouchExtensionHeight // which extends to the top of the hotseat. diff --git a/src/com/android/launcher3/widget/WidgetsContainerView.java b/src/com/android/launcher3/widget/WidgetsContainerView.java index 8a58d3464..34bee1b47 100644 --- a/src/com/android/launcher3/widget/WidgetsContainerView.java +++ b/src/com/android/launcher3/widget/WidgetsContainerView.java @@ -20,7 +20,6 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.graphics.drawable.InsetDrawable; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView.State; import android.util.AttributeSet; @@ -32,7 +31,6 @@ import android.widget.Toast; import com.android.launcher3.BaseContainerView; import com.android.launcher3.CellLayout; import com.android.launcher3.DeleteDropTarget; -import com.android.launcher3.DeviceProfile; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.folder.Folder; @@ -62,6 +60,9 @@ public class WidgetsContainerView extends BaseContainerView private DragController mDragController; private IconCache mIconCache; + private final Rect mTmpBgPaddingRect = new Rect(); + private final Rect mTmpRect = new Rect(); + /* Recycler view related member variables */ private WidgetsRecyclerView mRecyclerView; private WidgetsListAdapter mAdapter; @@ -97,18 +98,24 @@ public class WidgetsContainerView extends BaseContainerView mRecyclerView = (WidgetsRecyclerView) getContentView().findViewById(R.id.widgets_list_view); mRecyclerView.setAdapter(mAdapter); mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + } - Rect bgPadding = new Rect(); - getRevealView().getBackground().getPadding(bgPadding); + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + getRevealView().getBackground().getPadding(mTmpBgPaddingRect); if (Utilities.isRtl(getResources())) { - getContentView().setPadding(0, bgPadding.top, - bgPadding.right, bgPadding.bottom); - mRecyclerView.updateBackgroundPadding(new Rect(bgPadding.left, 0, 0, 0)); + getContentView().setPadding(0, mTmpBgPaddingRect.top, mTmpBgPaddingRect.right, + mTmpBgPaddingRect.bottom); + mTmpRect.set(mTmpBgPaddingRect.left, 0, 0, 0); + mRecyclerView.updateBackgroundPadding(mTmpRect); } else { - getContentView().setPadding(bgPadding.left, bgPadding.top, - 0, bgPadding.bottom); - mRecyclerView.updateBackgroundPadding(new Rect(0, 0, bgPadding.right, 0)); + getContentView().setPadding(mTmpBgPaddingRect.left, mTmpBgPaddingRect.top, 0, + mTmpBgPaddingRect.bottom); + mTmpRect.set(0, 0, mTmpBgPaddingRect.right, 0); + mRecyclerView.updateBackgroundPadding(mTmpRect); } + + super.onMeasure(widthMeasureSpec, heightMeasureSpec); } // -- cgit v1.2.3