BottomNavigationView 使用
- 布局中设置
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
style="@style/Widget.Design.BottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:background="@color/viewBackground"
app:elevation="@dimen/dp_16"
app:itemIconTint="@drawable/nav_item_color_state"
app:itemTextColor="@drawable/nav_item_color_state"
app:menu="@menu/bottom_navigation_main" />
复制代码
- BottomNavigationView 是通过 menu 来设置 item
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_home"
android:enabled="true"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/home"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_knowledge_system"
android:enabled="true"
android:icon="@drawable/ic_apps_black_24dp"
android:title="@string/knowledge_system"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_wechat"
android:enabled="true"
android:icon="@drawable/ic_wechat_black_24dp"
android:title="@string/wechat"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_navigation"
android:enabled="true"
android:icon="@drawable/ic_navigation_black_24dp"
android:title="@string/navigation"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_project"
android:enabled="true"
android:icon="@drawable/ic_project_black_24dp"
android:title="@string/project"
app:showAsAction="ifRoom" />
</menu>
复制代码
- Activity 中使用
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bottom_navigation);
BottomNavigationView navigation = (BottomNavigationView)findViewById(R.id.bottom_navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.action_home:
return true;
case R.id.action_knowledge_system:
return true;
case R.id.action_wechat:
return true;
case R.id.action_navigation:
return true;
case R.id.action_project:
return true;
}
return false;
}
};
复制代码
使用时遇到的坑
坑一:使用时 item 个数大于 3 个时会有位移动画,那么如何设置底部图标和字体都显示并去掉点击动画?
- 使用下面的类通过反射可以修改
public class BottomNavigationViewHelper {
public static void disableShiftMode(BottomNavigationView view) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
try {
Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
shiftingMode.setAccessible(true);
shiftingMode.setBoolean(menuView, false);
shiftingMode.setAccessible(false);
for (int i = 0; i < menuView.getChildCount(); i++) {
BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
//noinspection RestrictedApi
item.setShiftingMode(false);
// set once again checked value, so view will be updated
//noinspection RestrictedApi
item.setChecked(item.getItemData().isChecked());
}
} catch (NoSuchFieldException e) {
Log.e("BNVHelper", "Unable to get shift mode field", e);
} catch (IllegalAccessException e) {
Log.e("BNVHelper", "Unable to change value of shift mode", e);
}
}
}
复制代码
BottomNavigationViewHelper.disableShiftMode(navigation);
复制代码
另:在support版本 28 以下(不包含)使用上面的方法完美解决,那么在support版本 28 以上怎么解决呢?
support 28
版本官方重构了BottomNavigationView
,通过查阅BottomNavigationView
与BottomNavigationMenuView
中的代码可以知道通过设置labelVisibilityMode
的显示模式来设置底部图标和字体都显示并去掉点击动画。
所以目前 support
版本 28 可以使用下面的方法可以完美解决:
java代码中
bottom_navigation.setLabelVisibilityMode(1);
复制代码
或者 xml
布局文件中
app:labelVisibilityMode="labeled"
复制代码
坑二:如何实现中间的 icon 的样式和其他的不一样?
- 把
app:menu="@menu/bottom_navigation_main"
指向的bottom_navigation_main
修改为
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_home"
android:enabled="true"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/home"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_knowledge_system"
android:enabled="true"
android:icon="@drawable/ic_apps_black_24dp"
android:title="@string/knowledge_system"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_wechat"
android:enabled="true"
android:icon="@null"
android:title=""
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_navigation"
android:enabled="true"
android:icon="@drawable/ic_navigation_black_24dp"
android:title="@string/navigation"
app:showAsAction="ifRoom" />
<item
android:id="@+id/action_project"
android:enabled="true"
android:icon="@drawable/ic_project_black_24dp"
android:title="@string/project"
app:showAsAction="ifRoom" />
</menu>
复制代码
也就是中间第三个 item
不设置图标和文字。
- 然后在修改布局文件(用一个
LinearLayout
中间设个一个ImageView
覆盖在BottomNavigationView
上即可)
<FrameLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:clipToPadding="true">
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation"
style="@style/Widget.Design.BottomNavigationView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:background="@color/viewBackground"
app:elevation="@dimen/dp_16"
app:itemIconTint="@drawable/nav_item_color_state"
app:itemTextColor="@drawable/nav_item_color_state"
app:menu="@menu/bottom_navigation_main" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="16dp">
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
<ImageView
android:id="@+id/navigation_center_image"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:padding="5dp"
android:src="@mipmap/ic_launcher" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="2" />
</LinearLayout>
</FrameLayout>
复制代码
坑三:选中 item 时,item 的文本会有一个动画,icon 也会上移一点,那么如何取消动画呢?
- 下面的参数是
item
选中和没有选中的文本大小,把它们设置成一样的就没有动画了。
design_bottom_navigation_active_text_size
design_bottom_navigation_text_size
复制代码
- 下面的参数是
icon
的margin_bottom
值,可以调整它让icon
垂直居中。
design_bottom_navigation_margin
复制代码
- 把下面的根据需要复制到项目的
dimen.xml
文件中即可。
<!--BottomNavigationView 的选中没有选中的字体大小-->
<dimen name="design_bottom_navigation_active_text_size">10sp</dimen>
<dimen name="design_bottom_navigation_text_size">10sp</dimen>
<!--BottomNavigationView 只放图标时的设置-->
<dimen name="design_bottom_navigation_active_text_size">0sp</dimen>
<dimen name="design_bottom_navigation_text_size">0sp</dimen>
<dimen name="design_bottom_navigation_margin">16dp</dimen>
复制代码