Android原生底部標簽 BottomNavigationView+Fragment 解決當item大於三出現布局不平均的問題


        項目目錄結構,文章末尾有解決當item大於三出現布局不平均的問題

 

 

 

在開始之前導入這個包

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

將這幾個圖片添加進去

 

  二、在res新建一個menu文件,在這文件夾下新建一個main_bottom_navigation.xml

插入如下代碼,這是BottomNavigationView的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/menu_message"
        android:enabled="true"
        android:icon="@drawable/message"
        app:showAsAction="ifRoom"
        android:title="消息" />
    <item
        android:id="@+id/menu_contacts"
        android:enabled="true"
        android:icon="@drawable/icon_contacts"
        app:showAsAction="ifRoom"
        android:title="聯系人" />
    <item
        android:id="@+id/menu_discover"
        android:enabled="true"
        android:icon="@drawable/icon_discover"
        app:showAsAction="ifRoom"
        android:title="發現" />
    <item
        android:id="@+id/menu_me"
        android:enabled="true"
        app:showAsAction="ifRoom"
        android:icon="@drawable/me"
        android:title="我" />
</menu>

然后在drawable文件夾下新建bottom_navigation_item_selector.xml文件,插入如下代碼,這段代碼的作用是當你選定某個item,就將它的顏色變成藍色,未選中則是灰色。

<?xml version="1.0" encoding="utf-8"?>
<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>

activity_main.xml代碼如下

<?xml version="1.0" encoding="utf-8"?>
<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:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@color/black_2c"
        app:titleTextColor="@color/write" />

    <FrameLayout
        android:id="@+id/ll_frameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/bv_bottomNavigation"
        android:layout_below="@id/toolbar" />


    <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:labelVisibilityMode="labeled"
        app:itemIconTint="@drawable/bottom_navigation_item_selector"
        app:itemTextColor="@drawable/bottom_navigation_item_selector"
        app:menu="@menu/main_bottom_navigation" />
</RelativeLayout>

fragment_account.xml代碼如下

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="我"
        android:textColor="@color/theme"
        android:textSize="23sp" />

</android.support.constraint.ConstraintLayout>

其他的fragment_contacts.xml、fragment_discover.xml、fragment_message.xml分別對應

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="聯系人"
        android:textColor="@color/theme"
        android:textSize="23sp" />
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="發現"
        android:textColor="@color/theme"
        android:textSize="23sp" />
</android.support.constraint.ConstraintLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="消息"
        android:textColor="@color/theme"
        android:textSize="23sp" />
</android.support.constraint.ConstraintLayout>
AccountFragment、ContactsFragment、DiscoverFragment、MessageFragment這幾個Fragment分別對應如下代碼,其實都是一樣的,只是對應不一樣的布局文件。
public class AccountFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_account, container, false);
    }
}
public class ContactsFragment extends Fragment {

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return  inflater.inflate(R.layout.fragment_contacts, container, false);
    }
}
public class DiscoverFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_discover, container, false);
    }
}
public class MessageFragment extends Fragment {

    public MessageFragment(){

    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_message, container, false);
    }
}

接下來就是MainActivity代碼了

public class MainActivity extends AppCompatActivity {

    private Toolbar mToolbar;
    private BottomNavigationView mBottomNavigationView;

    private int lastIndex;
    List<Fragment> mFragments;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initBottomNavigation();
        initData();

    }

    public void initView() {
        mToolbar = findViewById(R.id.toolbar);

    }

    public void initData() {
        setSupportActionBar(mToolbar);
        mFragments = new ArrayList<>();
        mFragments.add(new MessageFragment());
        mFragments.add(new ContactsFragment());
        mFragments.add(new DiscoverFragment());
        mFragments.add(new AccountFragment());
        // 初始化展示MessageFragment
        setFragmentPosition(0);
    }

    public void initBottomNavigation() {
        mBottomNavigationView = findViewById(R.id.bv_bottomNavigation);
//           解決當item大於三個時,非平均布局問題

// BottomNavigationViewHelper.disableShiftMode(mBottomNavigationView); 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; } }); } private void setFragmentPosition(int position) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); Fragment currentFragment = mFragments.get(position); Fragment lastFragment = mFragments.get(lastIndex); lastIndex = position; ft.hide(lastFragment); if (!currentFragment.isAdded()) { getSupportFragmentManager().beginTransaction().remove(currentFragment).commit(); ft.add(R.id.ll_frameLayout, currentFragment); } ft.show(currentFragment); ft.commitAllowingStateLoss(); } }

好了所有代碼都已經完成,可以運行看效果了。

-----------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------

可以看到這里有段代碼被注釋了,這是句代碼本來是為了解決當item大於三個的時候布局不平均,(ps:懶得作圖,如有需要可以自行嘗試)

那既然要解決為什么要注釋呢,是因為我發現其實根本不需要了。

網上很多了都是寫這樣一個幫助類來解決問題然后在activity里用上面的代碼來調用 BottomNavigationViewHelper
public class BottomNavigationViewHelper {
    @SuppressLint("RestrictedApi")
    public static void disableShiftMode(BottomNavigationView view) {
        BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
        try {
            Field shiftingMode = menuView.getClass().getDeclaredField("labelVisibilityMode");
            shiftingMode.setAccessible(true);
            shiftingMode.setInt(menuView, 1);//labelVisibilityMode
//            shiftingMode.setBoolean(menuView, false);//mShiftingMode
            shiftingMode.setAccessible(false);
            for (int i = 0; i < menuView.getChildCount(); i++) {
                BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                //noinspection RestrictedApi
//                item.setShiftingMode(false);
                item.setShifting(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);
        }
    }
}

但是!現在只需要在activity_main.xml的

android.support.design.widget.BottomNavigationView下添加這一行代碼就可以解決當item大於三個出現布局不平均的問題了

app:labelVisibilityMode="labeled"

 Gitee鏈接:https://gitee.com/xg520/BottomDemo.git


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM