BottomNavigationView結合ViewPager


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

 


免責聲明!

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



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