drawable文件夹下建立nav_change.xml ,并在布局中引用
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:color="@color/color_checked">item>
<item android:color="@color/color_unchecked">item>
selector>
布局中设置
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent"
tools:context="com.example.yanruifeng.myapplication.TestBottonNavigationActivity">
<android.support.design.widget.BottomNavigationView
android:id="@+id/bnv_nav"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
app:menu="@menu/navigation"
app:itemTextColor="@drawable/nav_change"
app:itemIconTint="@drawable/nav_change"
app:itemBackground="@color/color_bg"
android:layout_height="96px">android.support.design.widget.BottomNavigationView>
RelativeLayout>
在Activity中的使用
public class TestBottonNavigationActivity extends AppCompatActivity {
@BindView(R.id.bnv_nav)
BottomNavigationView bottomNavigationView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_botton_navigation);
ButterKnife.bind(this);
bottomNavigationView.getMenu().findItem(R.id.ic_home).setIcon(R.drawable.home_selected);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
resetIconColor();
switch (item.getItemId()){
case R.id.msg:
item.setIcon(R.drawable.msg_selected);
break;
case R.id.me:
item.setIcon(R.drawable.my_selected);
break;
case R.id.ic_home:
item.setIcon(R.drawable.home_selected);
break;
}
return true;
}
});
}
public void resetIconColor(){
bottomNavigationView.getMenu().findItem(R.id.ic_home).setIcon(R.drawable.home);
bottomNavigationView.getMenu().findItem(R.id.msg).setIcon(R.drawable.msg);
bottomNavigationView.getMenu().findItem(R.id.me).setIcon(R.drawable.my);
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
实际上不在Activity中动态更改图标也可以,在res/menu/navigation.xml中让icon引入drawable下的xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/ic_home"
android:icon="@drawable/nav_homeicon_change"
android:title="首页" />
<item
android:id="@+id/msg"
android:icon="@drawable/nav_msgicon_change"
android:title="消息" />
<item
android:id="@+id/me"
android:icon="@drawable/nav_myicon_change"
android:title="我的"/>
menu>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/home_selected">item>
<item android:state_checked="false" android:drawable="@drawable/home">item>
selector>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/msg_selected">item>
<item android:state_checked="false" android:drawable="@drawable/msg">item>
selector>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true" android:drawable="@drawable/my_selected">item>
<item android:state_checked="false" android:drawable="@drawable/my">item>
selector>
问题一:使用的时候 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);
}
}
}
使用:
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
BottomNavigationViewHelper.disableShiftMode(navigation);
问题二:
要实现上面的这样的效果:
我们把 app:menu=”@menu/navigation” 指向的 navigation 修改为
xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
<item
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
<item
android:id="@+id/navigation_center"
android:icon="@null"
android:title="" />
<item
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
<item
android:id="@+id/navigation_person"
android:icon="@drawable/ic_person_black_24dp"
android:title="@string/title_person" />
menu>
即中间第三个 menu 不给设置图片和文字
然后我们修改布局文件(即用一个LinearLayout (只是正中间有一个Image), 覆盖在 BottomNavigation 之上)
如果中间的按钮需要的是替换当前页面的fragment的话我们那么我们的 image 只用作显示使用,如果需要按钮的功能是打开一个新页面,那么我们需要给这个 imageVIew 设置一个点击事件,这样 BottomNavigation 就不会拿到点击事件,把中间的 item 标记为选中
<FrameLayout
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:clipToPadding="true">
<android.support.design.widget.BottomNavigationView
android:id="@+id/navigation"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_gravity="bottom"
android:background="?android:attr/windowBackground"
app:menu="@menu/navigation" />
<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 也会上移一点。
原回答
design_bottom_navigation_active_text_size
design_bottom_navigation_text_size
上面的参数是item选中没有选中的文本大小,我们把它设置成一样的话就没有动画了
design_bottom_navigation_margin
是图标的 margin bottom 的值我们可以调整他让 icon 垂直居中
<dimen name="design_bottom_navigation_active_text_size">10spdimen>
<dimen name="design_bottom_navigation_text_size">10spdimen>
<dimen name="design_bottom_navigation_active_text_size">0spdimen>
<dimen name="design_bottom_navigation_text_size">0spdimen>
<dimen name="design_bottom_navigation_margin">16dpdimen>
把上面的 根据需要 copy 到 res/values/dimens 中就行