ViewPager+RadioButton輕鬆實現底部Tab導航
一、概述
實現類似微信哪種底部tab導航的方式有很多種,這篇文章先介紹實現這種底部導航的一種簡單的方式,即ViewPager+RedioButton實現底部tab導航。
實現之前,我們先看一下即將要實現的導航效果圖:
OK,下面我們通過程式碼一步一步實現上圖的底部導航效果。
二、編寫程式碼
第一步:編寫主介面的佈局,activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight ="1" >
</android.support.v4.view.ViewPager>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/devider_line" >
</View>
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width ="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp" >
<RadioButton
android:id="@+id/btn_home"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:button="@null"
android:drawablePadding="3dp"
android:drawableTop="@drawable/ic_tab_home_yellow"
android:gravity="center_horizontal"
android:text="@string/tab_home"
android:textColor="@color/yellow" />
<RadioButton
android:id="@+id/btn_classify"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:button="@null"
android:drawablePadding="3dp"
android:drawableTop="@drawable/ic_tab_classify_yellow"
android:gravity="center_horizontal"
android:text="@string/tab_classify"
android:textColor="@color/yellow" />
<RadioButton
android:id="@+id/btn_discover"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:button="@null"
android:drawablePadding="3dp"
android:drawableTop="@drawable/ic_tab_discover_yellow"
android:gravity="center_horizontal"
android:text="@string/tab_discover"
android:textColor="@color/yellow" />
<RadioButton
android:id="@+id/btn_me"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@null"
android:button="@null"
android:drawablePadding="3dp"
android:drawableTop="@drawable/ic_tab_me_yellow"
android:gravity="center_horizontal"
android:text="@string/tab_me"
android:textColor="@color/yellow" />
</RadioGroup>
</LinearLayout>
注意:
- RadioButton預設是前面帶有圓點的,去掉前面圓點的方法:
將button屬性設為null,即:
android:button="@null"
- 讓RadioButton的文字水平居中,即:
android:gravity="center_horizontal"
可以新增一個寬度為螢幕填充父容器,高度為0.1dp的View,設定顏色背景實現分割線的效果
當設定了view的weight屬性後,可以將寬度或者高度設為0dp,這樣可以提高效率
第二步:MainActivity處理邏輯
1、初始化Fragment
protected void init() {
Fragment homeFragment = new HomeFragment();
Fragment classifyFragment = new ClassifyFragment();
Fragment discoverFragment = new DiscoverFragment();
Fragment meFragment = new MeFragment();
fragments.add(homeFragment);
fragments.add(classifyFragment);
fragments.add(discoverFragment);
fragments.add(meFragment);
}
- fragments為一個盛放Fragment的List集合
- 其中的一個Fragment的程式碼(其他的一樣,只是顯示的文字不同):
package com.lt.bottomtabdemo.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.TextView;
/**
* Created by lt on 2015/12/1.
*/
public class HomeFragment extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
textView.setGravity(Gravity.CENTER);
textView.setLayoutParams(params);
textView.setText("首頁");
return textView;
}
}
2、初始化View併為ViewPager設定Adapter
mRadioGroup = (RadioGroup) findViewById(R.id.radioGroup);
mViewPager = (ViewPager) findViewById(R.id.viewPager);
TabPageAdapter tabPageAdapter = new TabPageAdapter(
getSupportFragmentManager(), fragments);
mViewPager.setAdapter(tabPageAdapter);
mViewPager.setOnPageChangeListener(this);
其中 TagPagerAdapter.java:
package com.lt.bottomtabdemo.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.view.ViewGroup;
import java.util.List;
/**
* Created by lt on 2015/12/1.
* app導航內容區域介面卡
*/
public class TabPageAdapter extends FragmentPagerAdapter{
private List<Fragment> fragments;
public TabPageAdapter(FragmentManager fm,List<Fragment> fragments) {
super(fm);
this.fragments = fragments;
}
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}
@Override
public int getCount() {
return fragments.size();
}
/**
* 重寫,不讓Fragment銷燬
*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
}
這裡重寫destroyItem什麼都不做,這裡只有四個頁面沒必要讓系統銷燬Fragment。
3、寫一個切換頁面的方法:
/**
* 選擇某頁
* @param position 頁面的位置
*/
private void selectPage(int position) {
// 將所有的tab的icon變成灰色的
for (int i = 0; i < mRadioGroup.getChildCount(); i++) {
Drawable gray = getResources().getDrawable(unselectedIconIds[i]);
// 不能少,少了不會顯示圖片
gray.setBounds(0, 0, gray.getMinimumWidth(),
gray.getMinimumHeight());
RadioButton child = (RadioButton) mRadioGroup.getChildAt(i);
child.setCompoundDrawables(null, gray, null, null);
child.setTextColor(getResources().getColor(
R.color.dark_gray));
}
// 切換頁面
mViewPager.setCurrentItem(position, false);
// 改變圖示
Drawable yellow = getResources().getDrawable(selectedIconIds[position]);
yellow.setBounds(0, 0, yellow.getMinimumWidth(),
yellow.getMinimumHeight());
RadioButton select = (RadioButton) mRadioGroup.getChildAt(position);
select.setCompoundDrawables(null, yellow, null, null);
select.setTextColor(getResources().getColor(
R.color.yellow));
}
用到的陣列資源,分別是按鈕選中與沒有選中狀態顯示的圖片資源:
/**
* 按鈕的沒選中顯示的圖示
*/
private int[] unselectedIconIds = { R.drawable.ic_tab_home_gray,
R.drawable.ic_tab_classify_gray, R.drawable.ic_tab_discover_gray,
R.drawable.ic_tab_me_gray };
/**
* 按鈕的選中顯示的圖示
*/
private int[] selectedIconIds = { R.drawable.ic_tab_home_yellow,
R.drawable.ic_tab_classify_yellow, R.drawable.ic_tab_discover_yellow,
R.drawable.ic_tab_me_yellow };
selectPage(int postion)方法說明:
遍歷RadioGroup將所有的RadioButton的上面的圖片和文字顏色設為沒有選中的狀態:
- 通過RadioButton.setCompoundDrawables(left, top, right, bottom);變換RadioButton的四個方向的圖片,這裡我們要換掉上面的圖片,所以先得到上面的圖片Drawable物件(注意要設定圖片顯示的大小):
Drawable gray = getResources().getDrawable(unselectedIconIds[i]);
// 不能少,少了不會顯示圖片,設定顯示的範圍,為一個矩形
gray.setBounds(0, 0, gray.getMinimumWidth(),
gray.getMinimumHeight());
- 然後在設定選中的那個RadioButton上面的圖片和文字顏色
這裡的position是指當前頁面對應的tab按鈕RadioButton在RadioGroup中的排序。
4、為了底部RadioButton點選後可以切換到相應的頁面,為RadioGroup設定按鈕選中改變的監聽:
mRadioGroup.setOnCheckedChangeListener(this);
實現onCheckedChanged方法
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.btn_home: // 首頁選中
selectPage(0);
break;
case R.id.btn_classify: // 分類選中
selectPage(1);
break;
case R.id.btn_discover: // 發現選中
selectPage(2);
break;
case R.id.btn_me: // 個人中心選中
selectPage(3);
break;
}
}
5、為了讓ViewPager滑動的同時改變底部按鈕選擇狀態,為ViewPager設定頁面改變監聽:
mViewPager.setOnPageChangeListener(this);
實現介面的三個方法(只實現其中的onPageSelected,其它的給空實現):
@Override
public void onPageSelected(int position) {
selectPage(position);
}
OK,到這裡我們 ViewPager+RadioButton 實現底部導航的例子完成了。