BottomNavigationView + Fragment

作者: EvanZch | 来源:发表于2018-08-27 21:23 被阅读148次

    本篇是自己在学习 BottomNavigationView 时整理的笔记。

    效果图:


    效果图.gif

    目录结构:


    目录结构.png

    https://github.com/Evan-zch/BottomNavigationViewDemo

    正文

    ​前面呈现的效果图是现在很多主流App都在使用底部导航栏模式,比如常用的微信、QQ这些基本的社交软件,其实要实现上面的效果也很简单。

    1、布局文件
    <android.support.design.widget.BottomNavigationView
            android:id="@+id/bv_bottomNavigation"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:background="@color/write"
            app:itemIconTint="@drawable/bottom_navigation_item_selector"
            app:itemTextColor="@drawable/bottom_navigation_item_selector"
            app:menu="@menu/main_bottom_navigation" />
    

    要使用 BottomNavigationView 需要在build.gradle中添加design

    implementation 'com.android.support:design:27.1.1'
    

    app:itemBackground:设置item的背景

    app:itemIconTint:设置icon的颜色

    app:itemTextColor:设置文字的颜色

    app:menu :设置底部导航栏icon和文字

    2、bottom_navigation_item_selector.xml

    app:itemIconTint="@drawable/bottom_navigation_item_selector"
    app:itemTextColor="@drawable/bottom_navigation_item_selector"

    drawable下新建xml文件,通过为 itemIconTintitemTextColor 设置 selector,可实现在点击时icontitle颜色的变换。

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="@color/theme" android:state_checked="true" />
        <item android:color="@color/bottom_navigation_normal" android:state_checked="false" />
    </selector>
    
    3、main_bottom_navigation.xml

    app:menu="@menu/main_bottom_navigation"

    menu目录下新建xml文件,自定义底部导航栏icontitle,代码如下:

    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
        <item
            android:id="@+id/menu_message"
            android:enabled="true"
            android:icon="@mipmap/message"
            app:showAsAction="ifRoom"
            android:title="消息" />
        <item
            android:id="@+id/menu_contacts"
            android:enabled="true"
            android:icon="@mipmap/icon_contacts"
            app:showAsAction="ifRoom"
            android:title="联系人" />
        <item
            android:id="@+id/menu_discover"
            android:enabled="true"
            android:icon="@mipmap/icon_discover"
            app:showAsAction="ifRoom"
            android:title="发现" />
        <item
            android:id="@+id/menu_me"
            android:enabled="true"
            app:showAsAction="ifRoom"
            android:icon="@mipmap/me"
            android:title="我" />
    </menu>
    
    4、在Activity中进行初始化:
    public void initBottomNavigation() {
            mBottomNavigationView = findViewById(R.id.bv_bottomNavigation);
            // 添加监听
            mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
                @Override
                public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                    switch (item.getItemId()) {
                        case R.id.menu_message:
                            setFragmentPosition(0);
                            break;
                        case R.id.menu_contacts:
                            setFragmentPosition(1);
                            break;
                        case R.id.menu_discover:
                            setFragmentPosition(2);
                            break;
                        case R.id.menu_me:
                            setFragmentPosition(3);
                            break;
                        default:
                            break;
                    }
                    // 这里注意返回true,否则点击失效
                    return true;
                }
            });
        }
    

    特别说明

    当底部导航栏item数目大于三个时,展示效果如下:

    item大于三个时效果图.gif

    item数目大于三个时,底部导航栏展示的效果采取动画的方式,很多时候非我们想要的效果, 通过反射来进行处理原文

    代码如下:

    public class BottomNavigationViewHelper {
        @SuppressLint("RestrictedApi")
        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);
            }
        }
    }
    

    可以在初始化的时候多添加一行代码就能避免这个问题

    
    mBottomNavigationView = findViewById(R.id.bv_bottomNavigation);
    // 解决当item大于三个时,非平均布局问题
    BottomNavigationViewHelper.disableShiftMode(mBottomNavigationView);
    

    相关文章

      网友评论

      • 有点健忘:试了下,咋感觉那几行反射的代码没有用到。循环child改成false就可以了。
        EvanZch:@有点健忘 我也试了,发现不行啊,下午有空研究一下看看
        有点健忘:@Evan_zch 对啊,我把反射代码删了,感觉也是正常的,我有4个item,图片文字都显示的
        EvanZch:你是说注释掉上面的反射方法也可以吗?

      本文标题:BottomNavigationView + Fragment

      本文链接:https://www.haomeiwen.com/subject/qxfxwftx.html