2018-10-30

Android 使用BottomNavigationView實(shí)現(xiàn)底部導(dǎo)航欄

今天我們來使用BottomNavigationView來實(shí)現(xiàn)android底部導(dǎo)航欄,在Android Support Library 25 中增加了 BottomNavigationView 控件,官方為我們提供了這樣這一個(gè)控件,就來試試吧!

1.效果圖如下:

2.導(dǎo)入以下support:design library,BottomNavigationView就在這個(gè)design庫(kù)中。

compile'com.android.support:design:25.0.1'

3.在res下新建一個(gè)menu,然后在menu下建一個(gè)navigation.xml(在四個(gè)item中,放置了四個(gè)icon)。

navigation.xml:

<?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/iv1_p"

? ? ? ? android:title="首頁" />

? ? <item

? ? ? ? android:id="@+id/navigation_dashboard"

? ? ? ? android:icon="@drawable/iv2_p"

? ? ? ? android:title="錢包" />

? ? <item

? ? ? ? android:id="@+id/navigation_notifications"

? ? ? ? android:icon="@drawable/iv3_p"

? ? ? ? android:title="卡片" />

? ? <item

? ? ? ? android:id="@+id/navigation_person"

? ? ? ? android:icon="@drawable/iv4_p"

? ? ? ? android:title="個(gè)人" />

</menu>

4.在布局文件中使用BottomNavigationView:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout 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"

? ? android:orientation="vertical"

? ? tools:context="com.afanbaby.bottomnavigationdemo.MainActivity">

? ? <android.support.v4.view.ViewPager

? ? ? ? android:id="@+id/vp"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="0dp"

? ? ? ? android:layout_weight="1" />

? ? <android.support.design.widget.BottomNavigationView

? ? ? ? android:id="@+id/bottomNavigationView"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="50dp"

? ? ? ? android:layout_alignParentBottom="true"

? ? ? ? android:background="?android:attr/windowBackground"

? ? ? ? app:itemBackground="@null"

? ? ? ? app:itemIconTint="@drawable/bottom_navigation_selector"

? ? ? ? app:itemTextColor="@drawable/bottom_navigation_selector"

? ? ? ? app:menu="@menu/navigation" />

</LinearLayout>

5.在drawable中新建bottom_navigation_selector.xml(設(shè)置文字和icon選中和未選中的顏色):

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

? ? <item android:color="@color/tab_checked" android:state_checked="true" />

? ? <item android:color="@color/tab_unchecked" android:state_checked="false" />

</selector>

6.color中增加兩個(gè)顏色值:

<?xml version="1.0" encoding="utf-8"?>

<resources>

<color name="tab_checked">#ED6A2C</color>

? ? ? ? <color name="tab_unchecked">#757575</color>

</resources>

7.就可以在MainActivity中使用了:

public class MainActivity extends AppCompatActivity {

? ? private BottomNavigationView bottomNavigationView;

? ? private ViewPagerAdapter viewPagerAdapter;

? ? private ViewPager viewPager;

? ? private MenuItem menuItem;

? ? @Override

? ? protected void onCreate(Bundle savedInstanceState) {

? ? ? ? super.onCreate(savedInstanceState);

? ? ? ? setContentView(R.layout.activity_main);

? ? ? ? bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationView);

? ? ? ? bottomNavigationView.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

? ? ? ? BottomNavigationViewHelper.disableShiftMode(bottomNavigationView);

? ? ? ? viewPager = (ViewPager) findViewById(R.id.vp);

? ? ? ? viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onPageSelected(int position) {

? ? ? ? ? ? ? ? if (menuItem != null) {

? ? ? ? ? ? ? ? ? ? menuItem.setChecked(false);

? ? ? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? ? ? bottomNavigationView.getMenu().getItem(0).setChecked(false);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? menuItem = bottomNavigationView.getMenu().getItem(position);

? ? ? ? ? ? ? ? menuItem.setChecked(true);

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void onPageScrollStateChanged(int state) {

? ? ? ? ? ? }

? ? ? ? });

? ? ? ? viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

? ? ? ? viewPager.setAdapter(viewPagerAdapter);

? ? ? ? List<Fragment> list = new ArrayList<>();

? ? ? ? list.add(TestFragment.newInstance("首頁"));

? ? ? ? list.add(TestFragment.newInstance("錢包"));

? ? ? ? list.add(TestFragment.newInstance("卡片"));

? ? ? ? list.add(TestFragment.newInstance("個(gè)人"));

? ? ? ? viewPagerAdapter.setList(list);

? ? }

? ? private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {

? ? ? ? @Override

? ? ? ? public boolean onNavigationItemSelected(@NonNull MenuItem item) {

? ? ? ? ? ? menuItem = item;

? ? ? ? ? ? switch (item.getItemId()) {

? ? ? ? ? ? ? ? case R.id.navigation_home:

? ? ? ? ? ? ? ? ? ? viewPager.setCurrentItem(0);

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? case R.id.navigation_dashboard:

? ? ? ? ? ? ? ? ? ? viewPager.setCurrentItem(1);

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? case R.id.navigation_notifications:

? ? ? ? ? ? ? ? ? ? viewPager.setCurrentItem(2);

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? ? ? case R.id.navigation_person:

? ? ? ? ? ? ? ? ? ? viewPager.setCurrentItem(3);

? ? ? ? ? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? return false;

? ? ? ? }

? ? };

}

8.ViewPagerAdapter:

public class ViewPagerAdapter extends FragmentPagerAdapter {

? ? private List<Fragment> list;

? ? public void setList(List<Fragment> list) {

? ? ? ? this.list = list;

? ? ? ? notifyDataSetChanged();

? ? }

? ? public ViewPagerAdapter(FragmentManager fm) {

? ? ? ? super(fm);

? ? }

? ? @Override

? ? public Fragment getItem(int position) {

? ? ? ? return list.get(position);

? ? }

? ? @Override

? ? public int getCount() {

? ? ? ? return list != null ? list.size() : 0;

? ? }

}

9.測(cè)試的TestFragment:

public class TestFragment extends Fragment {

? ? private TextView tv;

? ? public static TestFragment newInstance(String name) {

? ? ? ? Bundle args = new Bundle();

? ? ? ? args.putString("name", name);

? ? ? ? TestFragment fragment = new TestFragment();

? ? ? ? fragment.setArguments(args);

? ? ? ? return fragment;

? ? }

? ? @Nullable

? ? @Override

? ? public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {

? ? ? ? View view = inflater.inflate(R.layout.fragment_test, container, false);

? ? ? ? return view;

? ? }

? ? @Override

? ? public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {

? ? ? ? super.onViewCreated(view, savedInstanceState);

? ? ? ? tv = (TextView) view.findViewById(R.id.fragment_test_tv);

? ? ? ? Bundle bundle = getArguments();

? ? ? ? if (bundle != null) {

? ? ? ? ? ? String name = bundle.get("name").toString();

? ? ? ? ? ? tv.setText(name);

? ? ? ? }

? ? }

}

10.測(cè)試的TestFragment的布局文件:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

? ? android:layout_width="match_parent"

? ? android:layout_height="match_parent"

? ? android:orientation="vertical">

? ? <TextView

? ? ? ? android:id="@+id/fragment_test_tv"

? ? ? ? android:layout_width="match_parent"

? ? ? ? android:layout_height="match_parent"

? ? ? ? android:textSize="28dp"

? ? ? ? android:gravity="center"

? ? ? ? android:text="ceshi"/>

</LinearLayout>

這樣就完成了,是不是很簡(jiǎn)單,快去試下吧!

11.需要注意的地方:

(1)取消位移動(dòng)畫,如果你的菜單數(shù)大于3個(gè),則界面是這樣的(引用網(wǎng)絡(luò))。

這個(gè)效果可定不是我們想要的效果,可以通過反射解決。

新建一個(gè)BottomNavigationViewHelper.class:

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);

? ? ? ? }

? ? }

}

(2)取消導(dǎo)航欄的點(diǎn)擊效果(類似水波紋的效果)

我們只需在BottomNavigationView的布局文件中添加一個(gè)屬性:

app:itemBackground="@null"

1

(3)取消導(dǎo)航欄的每項(xiàng)點(diǎn)擊文字和圖片放大的效果

我們需要在values中的demens.xml中設(shè)置:

<?xml version="1.0" encoding="utf-8"?>

<resources>

? ? <!--BottomNavigationView 的選中沒有選中的字體大小-->

? ? <dimen name="design_bottom_navigation_active_text_size">10dp</dimen>

? ? <dimen name="design_bottom_navigation_text_size">10dp</dimen>

? ? <!--BottomNavigationView 只放圖標(biāo)時(shí)的設(shè)置-->

? ? <!--<dimen name="design_bottom_navigation_active_text_size">0dp</dimen>-->

? ? <!--<dimen name="design_bottom_navigation_text_size">0dp</dimen>-->

? ? <!--<dimen name="design_bottom_navigation_margin">16dp</dimen>-->

</resources>

12.demo的地址:

http://download.csdn.net/download/afanbaby/10237265

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

作者:Afanbaby

來源:CSDN

原文:https://blog.csdn.net/afanbaby/article/details/79240620

版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android使用底部導(dǎo)航 Android底部導(dǎo)航停留在屏幕底部,提供應(yīng)用中頂級(jí)視圖之間的導(dǎo)航。這是在具有向后兼容...
    ListenToCode閱讀 2,536評(píng)論 1 15
  • 用兩張圖告訴你,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 13,971評(píng)論 2 59
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,001評(píng)論 25 709
  • 長(zhǎng)靈河已經(jīng)進(jìn)入了深秋時(shí)分,河兩岸層林盡染,紅的黃的綠的交相輝映。河上方的天空藍(lán)得媲美大海,藍(lán)得讓人沒來由地心生喜歡...
    一生愨閱讀 238評(píng)論 0 0
  • 1.先把論文寫好 2.學(xué)習(xí)技術(shù),操作系統(tǒng)原理,網(wǎng)絡(luò)通信原理,熟悉C語言,掌握數(shù)據(jù)結(jié)構(gòu) 3.要看得懂源碼,會(huì)寫技術(shù)博...
    cherish_1609閱讀 145評(píng)論 0 0

友情鏈接更多精彩內(nèi)容