Move NavButtons to end of taskbar
* Layout hotseat icons from the end instead of the start * IME down and system back arrow are now separate views Bug: 191399224 Test: Tested w/ RTL + LTR in gesture and 3 button nav w/ and w/o IME Change-Id: I4d0ecd0bee0c519892c63eeefef45055b26d349b
This commit is contained in:
parent
5bd217414c
commit
8dcbde87c0
|
@ -36,18 +36,27 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="bottom" >
|
android:layout_gravity="bottom" >
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/start_contextual_buttons"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingLeft="@dimen/taskbar_nav_buttons_spacing"
|
||||||
|
android:paddingRight="@dimen/taskbar_nav_buttons_spacing"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_gravity="start"/>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/start_nav_buttons"
|
android:id="@+id/end_nav_buttons"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingLeft="@dimen/taskbar_nav_buttons_spacing"
|
android:paddingLeft="@dimen/taskbar_nav_buttons_spacing"
|
||||||
android:paddingRight="@dimen/taskbar_nav_buttons_spacing"
|
android:paddingRight="@dimen/taskbar_nav_buttons_spacing"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:layout_gravity="start"/>
|
android:layout_gravity="end"/>
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:id="@+id/end_nav_buttons"
|
android:id="@+id/end_contextual_buttons"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:paddingLeft="@dimen/taskbar_nav_buttons_spacing"
|
android:paddingLeft="@dimen/taskbar_nav_buttons_spacing"
|
||||||
|
|
|
@ -79,8 +79,10 @@ public class NavbarButtonsViewController {
|
||||||
|
|
||||||
private final TaskbarActivityContext mContext;
|
private final TaskbarActivityContext mContext;
|
||||||
private final FrameLayout mNavButtonsView;
|
private final FrameLayout mNavButtonsView;
|
||||||
private final ViewGroup mStartContainer;
|
private final ViewGroup mNavButtonContainer;
|
||||||
private final ViewGroup mEndContainer;
|
// Used for IME+A11Y buttons
|
||||||
|
private final ViewGroup mEndContextualContainer;
|
||||||
|
private final ViewGroup mStartContextualContainer;
|
||||||
|
|
||||||
// Initialized in init.
|
// Initialized in init.
|
||||||
private TaskbarControllers mControllers;
|
private TaskbarControllers mControllers;
|
||||||
|
@ -91,8 +93,9 @@ public class NavbarButtonsViewController {
|
||||||
public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) {
|
public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mNavButtonsView = navButtonsView;
|
mNavButtonsView = navButtonsView;
|
||||||
mStartContainer = mNavButtonsView.findViewById(R.id.start_nav_buttons);
|
mNavButtonContainer = mNavButtonsView.findViewById(R.id.end_nav_buttons);
|
||||||
mEndContainer = mNavButtonsView.findViewById(R.id.end_nav_buttons);
|
mEndContextualContainer = mNavButtonsView.findViewById(R.id.end_contextual_buttons);
|
||||||
|
mStartContextualContainer = mNavButtonsView.findViewById(R.id.start_contextual_buttons);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -114,21 +117,22 @@ public class NavbarButtonsViewController {
|
||||||
|
|
||||||
// IME switcher
|
// IME switcher
|
||||||
View imeSwitcherButton = addButton(R.drawable.ic_ime_switcher, BUTTON_IME_SWITCH,
|
View imeSwitcherButton = addButton(R.drawable.ic_ime_switcher, BUTTON_IME_SWITCH,
|
||||||
mEndContainer, mControllers.navButtonController, R.id.ime_switcher);
|
mEndContextualContainer, mControllers.navButtonController, R.id.ime_switcher);
|
||||||
mPropertyHolders.add(new StatePropertyHolder(imeSwitcherButton,
|
mPropertyHolders.add(new StatePropertyHolder(imeSwitcherButton,
|
||||||
flags -> ((flags & MASK_IME_SWITCHER_VISIBLE) == MASK_IME_SWITCHER_VISIBLE)
|
flags -> ((flags & MASK_IME_SWITCHER_VISIBLE) == MASK_IME_SWITCHER_VISIBLE)
|
||||||
&& ((flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0)
|
&& ((flags & FLAG_ROTATION_BUTTON_VISIBLE) == 0)
|
||||||
&& ((flags & FLAG_A11Y_VISIBLE) == 0)));
|
&& ((flags & FLAG_A11Y_VISIBLE) == 0)));
|
||||||
|
|
||||||
mBackButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
|
View imeDownButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
|
||||||
mStartContainer, mControllers.navButtonController, R.id.back);
|
mStartContextualContainer, mControllers.navButtonController, R.id.back);
|
||||||
|
imeDownButton.setRotation(Utilities.isRtl(mContext.getResources()) ? 90 : -90);
|
||||||
// Rotate when Ime visible
|
// Rotate when Ime visible
|
||||||
mPropertyHolders.add(new StatePropertyHolder(mBackButton,
|
mPropertyHolders.add(new StatePropertyHolder(imeDownButton,
|
||||||
flags -> (flags & FLAG_IME_VISIBLE) == 0, View.ROTATION, 0,
|
flags -> (flags & FLAG_IME_VISIBLE) != 0));
|
||||||
Utilities.isRtl(mContext.getResources()) ? 90 : -90));
|
|
||||||
|
|
||||||
if (mContext.isThreeButtonNav()) {
|
if (mContext.isThreeButtonNav()) {
|
||||||
initButtons(mStartContainer, mEndContainer, mControllers.navButtonController);
|
initButtons(mNavButtonContainer, mEndContextualContainer,
|
||||||
|
mControllers.navButtonController);
|
||||||
|
|
||||||
// Animate taskbar background when IME shows
|
// Animate taskbar background when IME shows
|
||||||
mPropertyHolders.add(new StatePropertyHolder(
|
mPropertyHolders.add(new StatePropertyHolder(
|
||||||
|
@ -142,21 +146,18 @@ public class NavbarButtonsViewController {
|
||||||
|
|
||||||
// Rotation button
|
// Rotation button
|
||||||
RotationButton rotationButton = new RotationButtonImpl(
|
RotationButton rotationButton = new RotationButtonImpl(
|
||||||
addButton(mEndContainer, R.id.rotate_suggestion));
|
addButton(mEndContextualContainer, R.id.rotate_suggestion));
|
||||||
rotationButton.hide();
|
rotationButton.hide();
|
||||||
mControllers.rotationButtonController.setRotationButton(rotationButton);
|
mControllers.rotationButtonController.setRotationButton(rotationButton);
|
||||||
} else {
|
} else {
|
||||||
mControllers.rotationButtonController.setRotationButton(new RotationButton() {});
|
mControllers.rotationButtonController.setRotationButton(new RotationButton() {});
|
||||||
// Show when IME is visible
|
|
||||||
mPropertyHolders.add(new StatePropertyHolder(mBackButton,
|
|
||||||
flags -> (flags & FLAG_IME_VISIBLE) != 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
applyState();
|
applyState();
|
||||||
mPropertyHolders.forEach(StatePropertyHolder::endAnimation);
|
mPropertyHolders.forEach(StatePropertyHolder::endAnimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initButtons(ViewGroup startContainer, ViewGroup endContainer,
|
private void initButtons(ViewGroup navContainer, ViewGroup endContainer,
|
||||||
TaskbarNavButtonController navButtonController) {
|
TaskbarNavButtonController navButtonController) {
|
||||||
|
|
||||||
// Hide when keyguard is showing, show when bouncer is showing
|
// Hide when keyguard is showing, show when bouncer is showing
|
||||||
|
@ -164,14 +165,19 @@ public class NavbarButtonsViewController {
|
||||||
flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 ||
|
flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 ||
|
||||||
(flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0));
|
(flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0));
|
||||||
|
|
||||||
|
mBackButton = addButton(R.drawable.ic_sysbar_back, BUTTON_BACK,
|
||||||
|
mNavButtonContainer, mControllers.navButtonController, R.id.back);
|
||||||
|
mPropertyHolders.add(new StatePropertyHolder(mBackButton,
|
||||||
|
flags -> (flags & FLAG_IME_VISIBLE) == 0));
|
||||||
|
|
||||||
// home and recents buttons
|
// home and recents buttons
|
||||||
View homeButton = addButton(R.drawable.ic_sysbar_home, BUTTON_HOME, startContainer,
|
View homeButton = addButton(R.drawable.ic_sysbar_home, BUTTON_HOME, navContainer,
|
||||||
navButtonController, R.id.home);
|
navButtonController, R.id.home);
|
||||||
mPropertyHolders.add(new StatePropertyHolder(homeButton,
|
mPropertyHolders.add(new StatePropertyHolder(homeButton,
|
||||||
flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
|
flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
|
||||||
(flags & FLAG_KEYGUARD_VISIBLE) == 0));
|
(flags & FLAG_KEYGUARD_VISIBLE) == 0));
|
||||||
View recentsButton = addButton(R.drawable.ic_sysbar_recent, BUTTON_RECENTS,
|
View recentsButton = addButton(R.drawable.ic_sysbar_recent, BUTTON_RECENTS,
|
||||||
startContainer, navButtonController, R.id.recent_apps);
|
navContainer, navButtonController, R.id.recent_apps);
|
||||||
mPropertyHolders.add(new StatePropertyHolder(recentsButton,
|
mPropertyHolders.add(new StatePropertyHolder(recentsButton,
|
||||||
flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
|
flags -> (flags & FLAG_IME_VISIBLE) == 0 &&
|
||||||
(flags & FLAG_KEYGUARD_VISIBLE) == 0));
|
(flags & FLAG_KEYGUARD_VISIBLE) == 0));
|
||||||
|
|
|
@ -194,24 +194,30 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar
|
||||||
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
|
||||||
int count = getChildCount();
|
int count = getChildCount();
|
||||||
int spaceNeeded = count * (mItemMarginLeftRight * 2 + mIconTouchSize);
|
int spaceNeeded = count * (mItemMarginLeftRight * 2 + mIconTouchSize);
|
||||||
int iconStart = (right - left - spaceNeeded) / 2;
|
int navSpaceNeeded = ApiWrapper.getHotseatEndOffset(getContext());
|
||||||
int startOffset = ApiWrapper.getHotseatStartOffset(getContext());
|
boolean layoutRtl = isLayoutRtl();
|
||||||
if (startOffset > iconStart) {
|
int iconEnd = right - (right - left - spaceNeeded) / 2;
|
||||||
int diff = startOffset - iconStart;
|
boolean needMoreSpaceForNav = layoutRtl ?
|
||||||
iconStart = isLayoutRtl() ? (iconStart - diff) : iconStart + diff;
|
navSpaceNeeded > (iconEnd - spaceNeeded) :
|
||||||
|
iconEnd > (right - navSpaceNeeded);
|
||||||
|
if (needMoreSpaceForNav) {
|
||||||
|
int offset = layoutRtl ?
|
||||||
|
navSpaceNeeded - (iconEnd - spaceNeeded) :
|
||||||
|
(right - navSpaceNeeded) - iconEnd;
|
||||||
|
iconEnd += offset;
|
||||||
}
|
}
|
||||||
// Layout the children
|
// Layout the children
|
||||||
mIconLayoutBounds.left = iconStart;
|
mIconLayoutBounds.right = iconEnd;
|
||||||
mIconLayoutBounds.top = (bottom - top - mIconTouchSize) / 2;
|
mIconLayoutBounds.top = (bottom - top - mIconTouchSize) / 2;
|
||||||
mIconLayoutBounds.bottom = mIconLayoutBounds.top + mIconTouchSize;
|
mIconLayoutBounds.bottom = mIconLayoutBounds.top + mIconTouchSize;
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = count; i > 0; i--) {
|
||||||
View child = getChildAt(i);
|
View child = getChildAt(i - 1);
|
||||||
iconStart += mItemMarginLeftRight;
|
iconEnd -= mItemMarginLeftRight;
|
||||||
int iconEnd = iconStart + mIconTouchSize;
|
int iconStart = iconEnd - mIconTouchSize;
|
||||||
child.layout(iconStart, mIconLayoutBounds.top, iconEnd, mIconLayoutBounds.bottom);
|
child.layout(iconStart, mIconLayoutBounds.top, iconEnd, mIconLayoutBounds.bottom);
|
||||||
iconStart = iconEnd + mItemMarginLeftRight;
|
iconEnd = iconStart - mItemMarginLeftRight;
|
||||||
}
|
}
|
||||||
mIconLayoutBounds.right = iconStart;
|
mIconLayoutBounds.left = iconEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -44,9 +44,9 @@ public class ApiWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the minimum space that should be left empty at the start of hotseat
|
* Returns the minimum space that should be left empty at the end of hotseat
|
||||||
*/
|
*/
|
||||||
public static int getHotseatStartOffset(Context context) {
|
public static int getHotseatEndOffset(Context context) {
|
||||||
if (SysUINavigationMode.INSTANCE.get(context).getMode() == Mode.THREE_BUTTONS) {
|
if (SysUINavigationMode.INSTANCE.get(context).getMode() == Mode.THREE_BUTTONS) {
|
||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
return 2 * res.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_spacing)
|
return 2 * res.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_spacing)
|
||||||
|
|
|
@ -777,7 +777,7 @@ public class DeviceProfile {
|
||||||
int taskbarOffset = getTaskbarOffsetY();
|
int taskbarOffset = getTaskbarOffsetY();
|
||||||
int hotseatTopDiff = hotseatHeight - taskbarSize - taskbarOffset;
|
int hotseatTopDiff = hotseatHeight - taskbarSize - taskbarOffset;
|
||||||
|
|
||||||
int startOffset = ApiWrapper.getHotseatStartOffset(context);
|
int endOffset = ApiWrapper.getHotseatEndOffset(context);
|
||||||
int requiredWidth = iconSizePx * numShownHotseatIcons;
|
int requiredWidth = iconSizePx * numShownHotseatIcons;
|
||||||
|
|
||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
|
@ -785,16 +785,16 @@ public class DeviceProfile {
|
||||||
float taskbarIconSpacing = 2 * res.getDimension(R.dimen.taskbar_icon_spacing);
|
float taskbarIconSpacing = 2 * res.getDimension(R.dimen.taskbar_icon_spacing);
|
||||||
int maxSize = (int) (requiredWidth
|
int maxSize = (int) (requiredWidth
|
||||||
* (taskbarIconSize + taskbarIconSpacing) / taskbarIconSize);
|
* (taskbarIconSize + taskbarIconSpacing) / taskbarIconSize);
|
||||||
int hotseatSize = Math.min(maxSize, availableWidthPx - startOffset);
|
int hotseatSize = Math.min(maxSize, availableWidthPx - endOffset);
|
||||||
int sideSpacing = (availableWidthPx - hotseatSize) / 2;
|
int sideSpacing = (availableWidthPx - hotseatSize) / 2;
|
||||||
mHotseatPadding.set(sideSpacing, hotseatTopDiff, sideSpacing, taskbarOffset);
|
mHotseatPadding.set(sideSpacing, hotseatTopDiff, sideSpacing, taskbarOffset);
|
||||||
|
|
||||||
if (startOffset > sideSpacing) {
|
if (endOffset > sideSpacing) {
|
||||||
int diff = Utilities.isRtl(context.getResources())
|
int diff = Utilities.isRtl(context.getResources())
|
||||||
? sideSpacing - startOffset
|
? sideSpacing - endOffset
|
||||||
: startOffset - sideSpacing;
|
: endOffset - sideSpacing;
|
||||||
mHotseatPadding.left += diff;
|
mHotseatPadding.left -= diff;
|
||||||
mHotseatPadding.right -= diff;
|
mHotseatPadding.right += diff;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We want the edges of the hotseat to line up with the edges of the workspace, but the
|
// We want the edges of the hotseat to line up with the edges of the workspace, but the
|
||||||
|
|
|
@ -39,9 +39,9 @@ public class ApiWrapper {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the minimum space that should be left empty at the start of hotseat
|
* Returns the minimum space that should be left empty at the end of hotseat
|
||||||
*/
|
*/
|
||||||
public static int getHotseatStartOffset(Context context) {
|
public static int getHotseatEndOffset(Context context) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue