1.禁用item>=3时的平移及缩放
@SuppressLint("RestrictedApi")
public static void disableShiftingMode(BottomNavigationView view) {
try {
BottomNavigationMenuView mMenuView = (BottomNavigationMenuView) view.getChildAt(0);
Field mShiftingModeField = BottomNavigationMenuView.class.getDeclaredField("mShiftingMode");
mShiftingModeField.setAccessible(true);
mShiftingModeField.set(mMenuView, false);
for (int i = 0; i < mMenuView.getChildCount(); i++) {
BottomNavigationItemView itemView = (BottomNavigationItemView) mMenuView.getChildAt(i);
itemView.setShiftingMode(false);
itemView.setChecked(itemView.getItemData().isChecked());
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
2.禁用item 缩放动画(选中放大图标/文字)
@SuppressLint("RestrictedApi")
public static void disableItemScale(BottomNavigationView view) {
try {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
Field mLargeLabelField = BottomNavigationItemView.class.getDeclaredField("mLargeLabel");
Field mSmallLabelField = BottomNavigationItemView.class.getDeclaredField("mSmallLabel");
Field mShiftAmountField = BottomNavigationItemView.class.getDeclaredField("mShiftAmount");
Field mScaleUpFactorField = BottomNavigationItemView.class.getDeclaredField("mScaleUpFactor");
Field mScaleDownFactorField = BottomNavigationItemView.class.getDeclaredField("mScaleDownFactor");
mSmallLabelField.setAccessible(true);
mLargeLabelField.setAccessible(true);
mShiftAmountField.setAccessible(true);
mScaleUpFactorField.setAccessible(true);
mScaleDownFactorField.setAccessible(true);
final float fontScale = view.getResources().getDisplayMetrics().scaledDensity;
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView itemView = (BottomNavigationItemView) menuView.getChildAt(i);
TextView lagerObj = (TextView) mLargeLabelField.get(itemView);
TextView smallObj = (TextView) mSmallLabelField.get(itemView);
lagerObj.setTextSize(smallObj.getTextSize() / fontScale + 0.5f);
mShiftAmountField.set(itemView, 0);
mScaleUpFactorField.set(itemView, 1f);
mScaleDownFactorField.set(itemView, 1f);
itemView.setChecked(itemView.getItemData().isChecked());
}
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
原理
源码:
public class BottomNavigationView extends FrameLayout {
//BottomNavigationView的显示效果由BottomNavigationMenuView控制
private final BottomNavigationMenuView mMenuView;
}
public class BottomNavigationMenuView extends ViewGroup implements MenuView {
//就是这个属性
private boolean mShiftingMode = true;
public void buildMenuView() {
//...
mButtons = new BottomNavigationItemView[mMenu.size()];
//为什么item大于3的时候,会有缩放
mShiftingMode = mMenu.size() > 3;
for (int i = 0; i < mMenu.size(); i++) {
BottomNavigationItemView child = getNewItem();
child.setShiftingMode(mShiftingMode);
//...
}
}
}
public class BottomNavigationItemView extends FrameLayout implements MenuView.ItemView {
private final int mShiftAmount;
private final float mScaleUpFactor;
private final float mScaleDownFactor;
private boolean mShiftingMode;
public BottomNavigationItemView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
final Resources res = getResources();
int inactiveLabelSize =
res.getDimensionPixelSize(R.dimen.design_bottom_navigation_text_size);
int activeLabelSize = res.getDimensionPixelSize(
R.dimen.design_bottom_navigation_active_text_size);
mDefaultMargin = res.getDimensionPixelSize(R.dimen.design_bottom_navigation_margin);
mShiftAmount = inactiveLabelSize - activeLabelSize;
mScaleUpFactor = 1f * activeLabelSize / inactiveLabelSize;
mScaleDownFactor = 1f * inactiveLabelSize / activeLabelSize;
LayoutInflater.from(context).inflate(R.layout.design_bottom_navigation_item, this, true);
setBackgroundResource(R.drawable.design_bottom_navigation_item_background);
mIcon = findViewById(R.id.icon);
mSmallLabel = findViewById(R.id.smallLabel);
mLargeLabel = findViewById(R.id.largeLabel);
}
@Override
public void setChecked(boolean checked) {
if (mShiftingMode) {
if (checked) {
LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
iconParams.topMargin = mDefaultMargin;
mIcon.setLayoutParams(iconParams);
mLargeLabel.setVisibility(VISIBLE);
mLargeLabel.setScaleX(1f);
mLargeLabel.setScaleY(1f);
} else {
LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
iconParams.gravity = Gravity.CENTER;
iconParams.topMargin = mDefaultMargin;
mIcon.setLayoutParams(iconParams);
//ShiftingMode模式下,不选中文字隐藏
mLargeLabel.setVisibility(INVISIBLE);
mLargeLabel.setScaleX(0.5f);
mLargeLabel.setScaleY(0.5f);
}
mSmallLabel.setVisibility(INVISIBLE);
} else {
if (checked) {
LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
//通过设置mShiftAmount 的大小 控制图片margin,进而控制图片大小
iconParams.topMargin = mDefaultMargin + mShiftAmount;
mIcon.setLayoutParams(iconParams);
//通过设置mLargeLabel和mSmallLabel的显示与隐藏控制文本大小
//如果把他俩TextSize设置为一样。则就不会变化
mLargeLabel.setVisibility(VISIBLE);
mSmallLabel.setVisibility(INVISIBLE);
mLargeLabel.setScaleX(1f);
mLargeLabel.setScaleY(1f);
mSmallLabel.setScaleX(mScaleUpFactor);
mSmallLabel.setScaleY(mScaleUpFactor);
} else {
LayoutParams iconParams = (LayoutParams) mIcon.getLayoutParams();
iconParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP;
iconParams.topMargin = mDefaultMargin;
mIcon.setLayoutParams(iconParams);
mLargeLabel.setVisibility(INVISIBLE);
mSmallLabel.setVisibility(VISIBLE);
mLargeLabel.setScaleX(mScaleDownFactor);
mLargeLabel.setScaleY(mScaleDownFactor);
mSmallLabel.setScaleX(1f);
mSmallLabel.setScaleY(1f);
}
}
refreshDrawableState();
}
}
<!--大文本和小文本大小-->
<dimen name="design_bottom_navigation_text_size">12sp</dimen>
<dimen name="design_bottom_navigation_active_text_size">14sp</dimen>
所以
如果要去掉item数量大于4时的缩放和平移:
1.通过反射把BottomNavigationMenuView#mShiftingMode
修改为false。
2.通过反射把BottomNavigationMenuView
中的BottomNavigationItemView#mShiftingMode
修改为false.
如果去掉item中的图片缩放和文本大小改变:
1.mShiftAmount
设置为 0。
2.mScaleUpFactor
和mScaleDownFactor
设置为1.0f。
3.mLargeLabel
和mSmallLabel
的文本大小设置为一样