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框架已經完成了!
如果系統自帶的BottomNaviationView不能滿足您的項目需求,建議您看看github一位大神封裝的一個BottomNaviationView的增強庫: