BottomNavigationView結合ViewPager搭建流行UI框架


BottomNavigationView是Google推出的底部導航欄組件,在沒有這些底部導航組件之前,Android開發者多使用的是RadioGroup,在上一個項目開發中我們使用了Google的BottomNaviationView與ViewPager相結合搭建了UI框架,現項目已經完成,總結如下:

使用BottomNaviationView需要添加依賴庫:

在app moudle 裏面的build.gradle文件中,dependencies節點下面添加如下依賴:

compile 'com.android.support:design:25.3.0'
添加完依賴我們便可以在佈局文件中使用了,activity_main.xml文件如下:
<?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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.qj.simpleuiframe.MainActivity">

    <!--狀態欄-->
    <View
        android:layout_width="match_parent"
        android:layout_height="24dp"
        android:background="@color/color661BB5D7"/>

    <!--標題欄-->
    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/color1BB5D7"
        android:gravity="center"
        android:textColor="@color/colorFFFFFF"
        android:textSize="20sp"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

    <!--底部導航欄-->
    <android.support.design.widget.BottomNavigationView
        android:id="@+id/bnv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?android:attr/windowBackground"
        app:itemIconTint="@drawable/tab_text_color_selector"
        app:itemTextColor="@drawable/tab_text_color_selector"
        app:menu="@menu/navigation"/>
</LinearLayout>
先說說底部導航欄BottomNaviationView:
app:menu="@menu/navigation" 這句說明:在我們的res文件夾下面有一個menu文件夾,menu文件夾裏面有一個navigation文件,裏面是關於我們底部導航欄的信息

我們來看看這個navigation.xml文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/tab_one"
        android:icon="@drawable/tab_one_selector"
        android:title="@string/tab_one"/>

    <item
        android:id="@+id/tab_two"
        android:icon="@drawable/tab_two_selector"
        android:title="@string/tab_two"/>

    <item
        android:id="@+id/tab_three"
        android:icon="@drawable/tab_three_selector"
        android:title="@string/tab_three"/>
</menu>
我們看到裏面總共有三個導航按鈕,我們以第一個爲例做一下簡單的說明:
id和title屬性很簡單,我們看一下icon屬性,我們平時的底部導航按鈕都是上圖下文形式的(大多情況是這樣),下面的文字是由我們的title屬性指定的,上面的圖片則是由我們這裏的icon屬性所決定的,我們看一看這個很簡單的tab_one_selector選擇器:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/commend_select" android:state_pressed="true"/>
    <item android:drawable="@mipmap/commend_select" android:state_selected="true"/>
    <item android:drawable="@mipmap/commend"/>
</selector>
到這app:menu="@menu/navigation" 就說完了
下面說一下

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

app:itemIconTint是設置底部導航按鈕圖標顏色的屬性

app:itemTextColor是設置底部導航按鈕文字顏色的屬性

由於大多情況下圖標和文件顏色都是相同的(爲了統一風格樣式),所以它們兩個我用的是同一個顏色選擇器

說到這BottomNaviationView這個控件就說完了,下面解釋一下activity_main.xml文件中的狀態欄控件,在佈局中寫狀態欄的原因是因爲我們的應用主題是沒有ActionBar並且狀態欄是透明的,所以狀態欄和標題欄需要我們自己來寫(也是爲了滿足用戶定義不同樣式的狀態欄和標題欄的要求)

下面看一下appTheme這一主題:

<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- 全屏、無標題欄、狀態欄透明 -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowTranslucentStatus">true</item>
    </style>
可以看到AppTheme的父主題是沒有ActionBar的,而且我們還設置了它的的windowTranslucentStatus爲true,即狀態欄透明
這樣我們的Activity就完全全屏了,沒了狀態欄和標題欄,我們就可以自己定義狀態欄和標題欄了!

到這裏activity_main.xml文件就說完了,下面看一下MainActivity.java中的代碼

public class MainActivity extends FragmentActivity implements BottomNavigationView.OnNavigationItemSelectedListener, ViewPager.OnPageChangeListener {

    private ViewPager mViewPager;
    private BottomNavigationView mBottomNavigationView;
    private TextView mTitle;

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

    private void initView() {
        mTitle = (TextView) findViewById(R.id.title);
        mBottomNavigationView = (BottomNavigationView) findViewById(R.id.bnv);
        mViewPager = (ViewPager) findViewById(R.id.viewpager);
    }

    private void initData() {
    }

    private void initListener() {
        mBottomNavigationView.setOnNavigationItemSelectedListener(this);
        //系統默認選中第一個,但是系統選中第一個不執行onNavigationItemSelected(MenuItem)方法,如果要求剛進入頁面就執行clickTabOne()方法,則手動調用選中第一個
        mBottomNavigationView.setSelectedItemId(R.id.tab_one);//根據具體情況調用
        mViewPager.addOnPageChangeListener(this);
        //爲viewpager設置adapter
        mViewPager.setAdapter(new ViewPagerAdapter(getSupportFragmentManager()));
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        //BottomNaviationView和ViewPager聯動,當BottomNaviationView的某個tab按鈕被選中了,同時設置ViewPager對應的頁面被選中
        int itemId = item.getItemId();
        switch (itemId) {
            case R.id.tab_one:
                clickTabOne();
                return true;//返回true,否則tab按鈕不變色,未被選中
            case R.id.tab_two:
                clickTabTwo();
                return true;
            case R.id.tab_three:
                clickTabThree();
                return true;

            default:
                break;
        }
        return false;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        //ViewPager和BottomNaviationView聯動,當ViewPager的某個頁面被選中了,同時設置BottomNaviationView對應的tab按鈕被選中
        switch (position) {
            case 0:
                mBottomNavigationView.setSelectedItemId(R.id.tab_one);
                break;
            case 1:
                mBottomNavigationView.setSelectedItemId(R.id.tab_two);
                break;
            case 2:
                mBottomNavigationView.setSelectedItemId(R.id.tab_three);
                break;

            default:
                break;
        }
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    private void clickTabOne() {
        //爲防止隔頁切換時,滑過中間頁面的問題,去除頁面切換緩慢滑動的動畫效果
        mViewPager.setCurrentItem(0, false);
        mTitle.setText("One");
    }

    private void clickTabTwo() {
        mViewPager.setCurrentItem(1, false);
        mTitle.setText("Two");
    }

    private void clickTabThree() {
        mViewPager.setCurrentItem(2, false);
        mTitle.setText("Three");
    }
}
代碼中都有詳細的註釋,這裏就不多說了,這裏說一下ViewPager設置適配器,代碼中創建了ViewPagerAdapter對象
public class ViewPagerAdapter extends FragmentPagerAdapter {
    //由於頁面已經固定,故這裏把Adapter需要的fragment提前創建
    private Fragment[] mFragments = new Fragment[]{new OneFragment(), new TwoFragment(), new ThreeFragment()};

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments[position];
    }

    @Override
    public int getCount() {
        return 3;
    }
}
ViewPagerAdapter對象中創建了它所需要的所有fragment對象,這裏由於是演示說明,所以Fragment頁面也很簡單,代碼就不貼了(最後會提供下載地址)
到這我們的BottomNaviationView與ViewPager相結合搭建的流行UI框架已經完成了!


項目下載鏈接

.apk文件下載


如果系統自帶的BottomNaviationView不能滿足您的項目需求,建議您看看github一位大神封裝的一個BottomNaviationView的增強庫:

BottomNaviationViewEx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章