Update shifting BottomNavigationView behavior to size active view width based on label size, rather than defaulting to maxWidth.

PiperOrigin-RevId: 155252923
This commit is contained in:
gauthams 2017-05-05 16:17:27 -07:00 committed by Travis Collins
parent 67bb191837
commit 7957a2d8aa
3 changed files with 49 additions and 30 deletions

View File

@ -15,35 +15,37 @@
~ limitations under the License.
-->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/design_bottom_navigation_margin"
android:layout_marginBottom="@dimen/design_bottom_navigation_margin"
android:duplicateParentState="true" />
<android.support.design.internal.BaselineLayout
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="@dimen/design_bottom_navigation_margin"
android:layout_marginBottom="@dimen/design_bottom_navigation_margin"
android:layout_gravity="center_horizontal"
android:duplicateParentState="true"/>
<android.support.design.internal.BaselineLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:paddingBottom="10dp"
android:clipToPadding="false"
android:duplicateParentState="true">
<TextView
android:id="@+id/smallLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:paddingBottom="10dp"
android:clipToPadding="false"
android:duplicateParentState="true">
<TextView
android:id="@+id/smallLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/design_bottom_navigation_text_size"
android:singleLine="true"
android:duplicateParentState="true" />
<TextView
android:id="@+id/largeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
android:textSize="@dimen/design_bottom_navigation_active_text_size"
android:singleLine="true"
android:duplicateParentState="true" />
</android.support.design.internal.BaselineLayout>
android:duplicateParentState="true"
android:singleLine="true"
android:textSize="@dimen/design_bottom_navigation_text_size"/>
<TextView
android:id="@+id/largeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:duplicateParentState="true"
android:singleLine="true"
android:textSize="@dimen/design_bottom_navigation_active_text_size"
android:visibility="invisible"/>
</android.support.design.internal.BaselineLayout>
</merge>

View File

@ -67,5 +67,6 @@
<dimen name="design_bottom_navigation_item_min_width">56dp</dimen>
<dimen name="design_bottom_navigation_item_max_width">96dp</dimen>
<dimen name="design_bottom_navigation_active_item_max_width">168dp</dimen>
<dimen name="design_bottom_navigation_active_item_min_width">96dp</dimen>
</resources>

View File

@ -47,6 +47,7 @@ public class BottomNavigationMenuView extends ViewGroup implements MenuView {
private final int mInactiveItemMaxWidth;
private final int mInactiveItemMinWidth;
private final int mActiveItemMaxWidth;
private final int mActiveItemMinWidth;
private final int mItemHeight;
private final OnClickListener mOnClickListener;
private final Pools.Pool<BottomNavigationItemView> mItemPool = new Pools.SynchronizedPool<>(5);
@ -77,6 +78,8 @@ public class BottomNavigationMenuView extends ViewGroup implements MenuView {
res.getDimensionPixelSize(R.dimen.design_bottom_navigation_item_min_width);
mActiveItemMaxWidth =
res.getDimensionPixelSize(R.dimen.design_bottom_navigation_active_item_max_width);
mActiveItemMinWidth =
res.getDimensionPixelSize(R.dimen.design_bottom_navigation_active_item_min_width);
mItemHeight = res.getDimensionPixelSize(R.dimen.design_bottom_navigation_height);
mSet = new AutoTransition();
@ -112,14 +115,27 @@ public class BottomNavigationMenuView extends ViewGroup implements MenuView {
final int heightSpec = MeasureSpec.makeMeasureSpec(mItemHeight, MeasureSpec.EXACTLY);
if (mShiftingMode) {
final View child = getChildAt(mSelectedItemPosition);
int activeItemWidth = mActiveItemMinWidth;
if (child.getVisibility() != View.GONE) {
// Do an AT_MOST measure pass on the active child to get its desired width, and resize the
// active child view based on that width
child.measure(
MeasureSpec.makeMeasureSpec(mActiveItemMaxWidth, MeasureSpec.AT_MOST), heightSpec);
activeItemWidth = Math.max(activeItemWidth, child.getMeasuredWidth());
}
final int inactiveCount = count - 1;
final int activeMaxAvailable = width - inactiveCount * mInactiveItemMinWidth;
final int activeWidth = Math.min(activeMaxAvailable, mActiveItemMaxWidth);
final int activeWidth =
Math.min(activeMaxAvailable, Math.min(activeItemWidth, mActiveItemMaxWidth));
final int inactiveMaxAvailable = (width - activeWidth) / inactiveCount;
final int inactiveWidth = Math.min(inactiveMaxAvailable, mInactiveItemMaxWidth);
int extra = width - activeWidth - inactiveWidth * inactiveCount;
for (int i = 0; i < count; i++) {
mTempChildWidths[i] = (i == mSelectedItemPosition) ? activeWidth : inactiveWidth;
// Account for integer division which sometimes leaves some extra pixel spaces.
// e.g. If the nav was 10px wide, and 3 children were measured to be 3px-3px-3px, there
// would be a 1px gap somewhere, which this fills in.
if (extra > 0) {
mTempChildWidths[i]++;
extra--;