diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 632aff04b8..5c1fec7e31 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 0321631cae..b394fa8359 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 74f7ca10bc..c4431be250 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 1f97d24607..0000000000
--- 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 85a436cf92..283808805a 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 c2d20a3101..358d9b6a0c 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 6fb2bf69af..0000000000
--- 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 308c71c417..3cfaf02d08 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 57a60a95d0..96942ee6f8 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 33e4e2a672..00ec4c2ffc 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 2b130e5a71..ac86f0b74a 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 7e2b42e498..084de70e31 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 9ce941b524..a49162c8bf 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 4e6911ca0c..38545e2d0f 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 b7f033ef49..651e91b7b2 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 7bcf5d00e2..643d48adfc 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 c016aa9890..d98734b0f7 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 78ef074c53..bcd87b5a96 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 cc969343c6..3ef510c3f7 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 0f0c333f4a..97c46b163a 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 8a58d34644..34bee1b47b 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);
}
//