Skip to content

Commit

Permalink
[BottomNavigationView] Updated menu item selection animation to match…
Browse files Browse the repository at this point in the history
… spec

Bottom nav item labels now slide up when fading in instead of scaling.

PiperOrigin-RevId: 331163684
  • Loading branch information
hunterstich authored and ymarian committed Sep 11, 2020
1 parent 0c1cc3d commit 8ec11a1
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@

<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_alarm"
android:enabled="true"
android:icon="@drawable/asld_clock_alarm"
android:title="@string/cat_bottom_nav_alarm"/>
<item
android:id="@+id/action_clock"
android:enabled="true"
android:icon="@drawable/asld_clock_clock"
android:title="@string/cat_bottom_nav_clock"/>
<item
android:id="@+id/action_timer"
android:enabled="true"
android:icon="@drawable/asld_clock_timer"
android:title="@string/cat_bottom_nav_timer"/>
<item
android:id="@+id/action_stopwatch"
android:enabled="true"
android:icon="@drawable/asld_clock_stopwatch"
android:title="@string/cat_bottom_nav_stopwatch"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public class BottomNavigationItemView extends FrameLayout implements MenuView.It
private boolean isShifting;

private ImageView icon;
private final ViewGroup labelGroup;
private final TextView smallLabel;
private final TextView largeLabel;
private int itemPosition = INVALID_ITEM_POSITION;
Expand Down Expand Up @@ -98,8 +99,14 @@ public BottomNavigationItemView(
defaultMargin = res.getDimensionPixelSize(R.dimen.design_bottom_navigation_margin);

icon = findViewById(R.id.icon);
labelGroup = findViewById(R.id.labelGroup);
smallLabel = findViewById(R.id.smallLabel);
largeLabel = findViewById(R.id.largeLabel);

// Save the original bottom padding from the label group so it can be animated to and from
// during label visibility changes.
labelGroup.setTag(R.id.mtrl_view_tag_bottom_padding, labelGroup.getPaddingBottom());

// The labels used aren't always visible, so they are unreliable for accessibility. Instead,
// the content description of the BottomNavigationItemView should be used for accessibility.
ViewCompat.setImportantForAccessibility(smallLabel, ViewCompat.IMPORTANT_FOR_ACCESSIBILITY_NO);
Expand Down Expand Up @@ -143,9 +150,10 @@ public void initialize(@NonNull MenuItemImpl itemData, int menuType) {
setContentDescription(itemData.getContentDescription());
}

CharSequence tooltipText = !TextUtils.isEmpty(itemData.getTooltipText())
? itemData.getTooltipText()
: itemData.getTitle();
CharSequence tooltipText =
!TextUtils.isEmpty(itemData.getTooltipText())
? itemData.getTooltipText()
: itemData.getTitle();
TooltipCompat.setTooltipText(this, tooltipText);
setVisibility(itemData.isVisible() ? View.VISIBLE : View.GONE);
}
Expand Down Expand Up @@ -193,9 +201,10 @@ public void setTitle(CharSequence title) {
setContentDescription(title);
}

CharSequence tooltipText = itemData == null || TextUtils.isEmpty(itemData.getTooltipText())
? title
: itemData.getTooltipText();
CharSequence tooltipText =
itemData == null || TextUtils.isEmpty(itemData.getTooltipText())
? title
: itemData.getTooltipText();
TooltipCompat.setTooltipText(this, tooltipText);
}

Expand All @@ -216,47 +225,57 @@ public void setChecked(boolean checked) {
if (isShifting) {
if (checked) {
setViewLayoutParams(icon, defaultMargin, Gravity.CENTER_HORIZONTAL | Gravity.TOP);
setViewValues(largeLabel, 1f, 1f, VISIBLE);
updateViewPaddingBottom(
labelGroup, (int) labelGroup.getTag(R.id.mtrl_view_tag_bottom_padding));
largeLabel.setVisibility(VISIBLE);
} else {
setViewLayoutParams(icon, defaultMargin, Gravity.CENTER);
setViewValues(largeLabel, 0.5f, 0.5f, INVISIBLE);
updateViewPaddingBottom(labelGroup, 0);
largeLabel.setVisibility(INVISIBLE);
}
smallLabel.setVisibility(INVISIBLE);
} else {
updateViewPaddingBottom(
labelGroup, (int) labelGroup.getTag(R.id.mtrl_view_tag_bottom_padding));
if (checked) {
setViewLayoutParams(
icon, (int) (defaultMargin + shiftAmount), Gravity.CENTER_HORIZONTAL | Gravity.TOP);
setViewValues(largeLabel, 1f, 1f, VISIBLE);
setViewValues(smallLabel, scaleUpFactor, scaleUpFactor, INVISIBLE);
setViewScaleValues(largeLabel, 1f, 1f, VISIBLE);
setViewScaleValues(smallLabel, scaleUpFactor, scaleUpFactor, INVISIBLE);
} else {
setViewLayoutParams(icon, defaultMargin, Gravity.CENTER_HORIZONTAL | Gravity.TOP);
setViewValues(largeLabel, scaleDownFactor, scaleDownFactor, INVISIBLE);
setViewValues(smallLabel, 1f, 1f, VISIBLE);
setViewScaleValues(largeLabel, scaleDownFactor, scaleDownFactor, INVISIBLE);
setViewScaleValues(smallLabel, 1f, 1f, VISIBLE);
}
}
break;

case LabelVisibilityMode.LABEL_VISIBILITY_SELECTED:
if (checked) {
setViewLayoutParams(icon, defaultMargin, Gravity.CENTER_HORIZONTAL | Gravity.TOP);
setViewValues(largeLabel, 1f, 1f, VISIBLE);
updateViewPaddingBottom(
labelGroup, (int) labelGroup.getTag(R.id.mtrl_view_tag_bottom_padding));
largeLabel.setVisibility(VISIBLE);
} else {
setViewLayoutParams(icon, defaultMargin, Gravity.CENTER);
setViewValues(largeLabel, 0.5f, 0.5f, INVISIBLE);
updateViewPaddingBottom(labelGroup, 0);
largeLabel.setVisibility(INVISIBLE);
}
smallLabel.setVisibility(INVISIBLE);
break;

case LabelVisibilityMode.LABEL_VISIBILITY_LABELED:
updateViewPaddingBottom(
labelGroup, (int) labelGroup.getTag(R.id.mtrl_view_tag_bottom_padding));
if (checked) {
setViewLayoutParams(
icon, (int) (defaultMargin + shiftAmount), Gravity.CENTER_HORIZONTAL | Gravity.TOP);
setViewValues(largeLabel, 1f, 1f, VISIBLE);
setViewValues(smallLabel, scaleUpFactor, scaleUpFactor, INVISIBLE);
setViewScaleValues(largeLabel, 1f, 1f, VISIBLE);
setViewScaleValues(smallLabel, scaleUpFactor, scaleUpFactor, INVISIBLE);
} else {
setViewLayoutParams(icon, defaultMargin, Gravity.CENTER_HORIZONTAL | Gravity.TOP);
setViewValues(largeLabel, scaleDownFactor, scaleDownFactor, INVISIBLE);
setViewValues(smallLabel, 1f, 1f, VISIBLE);
setViewScaleValues(largeLabel, scaleDownFactor, scaleDownFactor, INVISIBLE);
setViewScaleValues(smallLabel, 1f, 1f, VISIBLE);
}
break;

Expand Down Expand Up @@ -307,6 +326,7 @@ public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo inf
/**
* Iterate through all the preceding bottom navigating items to determine this item's visible
* position.
*
* @return This item's visible position in a bottom navigation.
*/
private int getItemVisiblePosition() {
Expand All @@ -322,19 +342,25 @@ private int getItemVisiblePosition() {
return visiblePosition;
}

private void setViewLayoutParams(@NonNull View view, int topMargin, int gravity) {
private static void setViewLayoutParams(@NonNull View view, int topMargin, int gravity) {
LayoutParams viewParams = (LayoutParams) view.getLayoutParams();
viewParams.topMargin = topMargin;
viewParams.gravity = gravity;
view.setLayoutParams(viewParams);
}

private void setViewValues(@NonNull View view, float scaleX, float scaleY, int visibility) {
private static void setViewScaleValues(
@NonNull View view, float scaleX, float scaleY, int visibility) {
view.setScaleX(scaleX);
view.setScaleY(scaleY);
view.setVisibility(visibility);
}

private static void updateViewPaddingBottom(@NonNull View view, int paddingBottom) {
view.setPadding(
view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), paddingBottom);
}

@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@
android:contentDescription="@null"
android:duplicateParentState="true"/>
<com.google.android.material.internal.BaselineLayout
android:id="@+id/labelGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:paddingBottom="10dp"
android:paddingBottom="@dimen/design_bottom_navigation_label_padding"
android:clipChildren="false"
android:clipToPadding="false"
android:duplicateParentState="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<dimen name="design_bottom_navigation_icon_size">24dp</dimen>
<dimen name="design_bottom_navigation_height">56dp</dimen>
<dimen name="design_bottom_navigation_margin">8dp</dimen>
<dimen name="design_bottom_navigation_label_padding">10dp</dimen>
<dimen name="design_bottom_navigation_text_size">12sp</dimen>
<dimen name="design_bottom_navigation_active_text_size">14sp</dimen>
<dimen name="design_bottom_navigation_item_min_width">56dp</dimen>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2020 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<resources>
<item type="id" name="mtrl_view_tag_bottom_padding" />
</resources>

0 comments on commit 8ec11a1

Please sign in to comment.