Android中的多標籤切換的實現
類似於京東主頁幾個按鈕對應的幾個模組,微信主頁的四個按鈕對應的四個介面的實現
我們這樣做,主要是為了實現資訊的分類管理,將功能模組化,可以使我們的頁面邏輯更加的清晰
利用TableHost、TableWidget、FrameLayout實現
利用此種方式來實現,首先我們的activity必須要繼承TabActivity ,其次,我們的activity的佈局基本是固定的為下面的這種方式:
<?xml version="1.0" encoding="utf-8"?>
<TableHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--這裡的東西都是固定的,包括id都是,只能這樣寫-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation ="vertical"
>
<TabWidget
android:layout_width="match_parent"
android:id="@android:id/tabs"
android:layout_height="wrap_content"/>
<FrameLayout
android:layout_width="match_parent"
android:id="@android:id/tabcontent"
android:layout_height="match_parent"/>
</LinearLayout>
</TableHost>
我們的activity中寫法也差不多是固定的格式
public class TabHostActivity extends TabActivity {
private TabHost mTabHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 這裡不能使用下面這句。否則會報錯,應該直接getTabHost();
// setContentView(R.layout.activity_tabhost);
initViews();
}
private void initViews() {
// mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost = this.getTabHost();
mTabHost.setup();//初始化TableHost元件
//宣告並例項化一個LayoutInflater物件
LayoutInflater inflater = LayoutInflater.from(this);
//解析三個tab頁面
inflater.inflate(R.layout.tab1, mTabHost.getTabContentView());
inflater.inflate(R.layout.tab2, mTabHost.getTabContentView());
inflater.inflate(R.layout.tab3, mTabHost.getTabContentView());
//將三個頁面加入tabhost中
mTabHost.addTab(mTabHost.newTabSpec("tab1").setIndicator("聯絡人").setContent(R.id.tablayout1));
mTabHost.addTab(mTabHost.newTabSpec("tab2").setIndicator("通訊錄").setContent(R.id.tablayout2));
mTabHost.addTab(mTabHost.newTabSpec("tab3").setIndicator("收藏夾").setContent(R.id.tablayout3));
//添加當tab頁面改變時候的監聽。
mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String s) {
Toast.makeText(TabHostActivity.this, "" + s, Toast.LENGTH_SHORT).show();
}
});
}
}
對應的,我們的三個Tab頁的xml如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="@+id/tablayout1"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="第一個tab頁" />
</LinearLayout>
只是區分一下id就行,然後我們自己寫上兩三個tab的xml去看看實現後的效果
利用ViewPager、RaidoGroup、Fragment實現
我們用此種方式可以讓我們的頁面左右滑動,同時和我們的RadioButton進行聯動起來。這種方式也在許多app上都能見得到。
首先,我們要將我們的三個Fragment 和viewpager通過介面卡繫結,使得我們的頁面首先可以滑動起來了,然後,我們對我們的RadioGroup和ViewPager進行監聽,當一個的狀態改變了之後,我們控制另一個也相應的進行改變。
我們的佈局程式碼為:
<?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">
<RadioGroup
android:id="@+id/radioGroup"
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<RadioButton
android:id="@+id/rbtn1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:checked="true"
android:gravity="center"
android:button="@null"
android:background="@drawable/tab_selector"
android:text="tab1" />
<RadioButton
android:id="@+id/rbtn2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:button="@null"
android:background="@drawable/tab_selector"
android:text="tab2" />
<RadioButton
android:id="@+id/rbtn3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:button="@null"
android:background="@drawable/tab_selector"
android:text="tab3" />
</RadioGroup>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
activity的程式碼為:
public class ViewPagerActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, ViewPager.OnPageChangeListener {
private ArrayList<Fragment> mList = new ArrayList<>();
ViewPager mViewPager;
RadioGroup mRadioGroup;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewpager);
initFragment();
initViews();
}
/**
* 初始化我們的三個fragment
* */
private void initFragment() {
mList.add(new TabFragment1());
mList.add(new TabFragment2());
mList.add(new TabFragment3());
}
private void initViews() {
mRadioGroup = (RadioGroup) findViewById(R.id.radioGroup);
mViewPager = (ViewPager) findViewById(R.id.viewpager);
//將viewpager和fragment繫結
FragmentAdapter mAdapter = new FragmentAdapter(getSupportFragmentManager(), mList);
mViewPager.setAdapter(mAdapter);
mRadioGroup.setOnCheckedChangeListener(this);
mViewPager.setOnPageChangeListener(this);
}
//當radiobutton改變時候讓viewpager跟著改變
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {
switch (i) {
case R.id.rbtn1:
mViewPager.setCurrentItem(0);
break;
case R.id.rbtn2:
mViewPager.setCurrentItem(1);
break;
case R.id.rbtn3:
mViewPager.setCurrentItem(2);
break;
}
}
//當viewpager滑動改變後,讓RadioButton的選中狀態也改變
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
switch (position) {
case 0:
mRadioGroup.check(R.id.rbtn1);
break;
case 1:
mRadioGroup.check(R.id.rbtn2);
break;
case 2:
mRadioGroup.check(R.id.rbtn3);
break;
}
}
@Override
public void onPageScrollStateChanged(int state) {
}
}
介面卡的程式碼為:
public class FragmentAdapter extends FragmentPagerAdapter{
private ArrayList<Fragment> mFragmentList;
public FragmentAdapter(FragmentManager fm,ArrayList<Fragment> list) {
super(fm);
mFragmentList = list;
}
@Override
public Fragment getItem(int arg0) {
if(mFragmentList != null){
return mFragmentList.get(arg0);
}
return null;
}
@Override
public int getCount() {
if(mFragmentList != null){
return mFragmentList.size();
}
return 0;
}
@Override
public void destroyItem(View container, int position, Object object) {
// TODO Auto-generated method stub
// super.destroyItem(container, position, object);
}
}
而我們的三個Fragment中啥都沒有放,就載入了我們的一個xml佈局,就不再放程式碼了。這樣就實現了一個簡單的這種tab頁模式的框架。
利用TabLayout、Fragment實現
在android5.0之後,系統為我們提供了這種方式來實現這種功能。要使用TabLayout必須要引用官方的 compile ‘com.android.support:design:24.2.0’才行,當然不一定要是24.2.0的版本,只是必須要引入design的這個支援包,
我們的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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="50dp"
app:tabIndicatorColor="@android:color/holo_blue_bright"
app:tabSelectedTextColor="@android:color/holo_blue_bright"
app:tabTextColor="@android:color/black" />
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="50dp"
/>
</LinearLayout>
java程式碼為:
public class TabLayoutActivity extends AppCompatActivity {
//這種實現方式須要引入 compile 'com.android.support:design:24.2.0'才行
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tabbar);
initTab();
}
/**
* 初始化TAB標籤
*/
private void initTab() {
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
List<String> tabList = new ArrayList<>();
tabList.add("tab1");
tabList.add("tab2");
tabList.add("tab3");
tabLayout.setTabMode(TabLayout.MODE_FIXED);//設定tab模式,當前為系統預設模式
tabLayout.addTab(tabLayout.newTab().setText(tabList.get(0)));//新增tab選項卡
tabLayout.addTab(tabLayout.newTab().setText(tabList.get(1)));
tabLayout.addTab(tabLayout.newTab().setText(tabList.get(2)));
List<Fragment> fragmentList = new ArrayList<>();
fragmentList.add(new TabFragment1());
fragmentList.add(new TabFragment2());
fragmentList.add(new TabFragment3());
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
TabFragmentAdapter fragmentAdapter = new TabFragmentAdapter(getSupportFragmentManager(), fragmentList, tabList);
viewPager.setAdapter(fragmentAdapter);//給ViewPager設定介面卡
tabLayout.setupWithViewPager(viewPager);//將TabLayout和ViewPager關聯起來。
tabLayout.setTabsFromPagerAdapter(fragmentAdapter);//給Tabs設定介面卡
}
}
Fragment的適配為:
public class TabFragmentAdapter extends FragmentStatePagerAdapter {
private List<Fragment> mFragments;
private List<String> mTitles;
public TabFragmentAdapter(FragmentManager fm, List<Fragment> fragments, List<String> titles) {
super(fm);
mFragments = fragments;
mTitles = titles;
}
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
@Override
public int getCount() {
return mFragments.size();
}
@Override
public CharSequence getPageTitle(int position) {
return mTitles.get(position);
}
}
三種實現方式,其實也是android版本不斷升級的一個實現方式上的改變,我們開發中,儘可能的選擇官方支援的最新的方式來實現同樣的功能,