Fragment、ViewPager、ActionBar實現TAB導航條效果
前言:
製作Tab書籤導航條(書籤選項卡)有多種方法:
【特別提示:】注意幾種建立Tab書籤導航中Fragment生命週期的變化。
1、TabActivity+TabHost(已經過期)
2、Fragment + FragmentTabHost(取代TabActivity,不建議使用)
3、Fragment + ActionBar 【不建議使用
4、Fragment + ActionBar + ViewPager 固定導航條【不建議使用】
5、Fragment + RadioGroup 【必要時首選】
6、Fragment + ViewPager + RadioGroup自定義固定導航條 【推薦使用】
7、Fragment + ViewPager 帶滑動導航條 【推薦使用
8、Fragment + ViewPager + HorizontalScrollView自定義滑動導航條 【推薦使用】
一、TabActivity 實現選項卡效果:
TabActivity(已經過期,使用FragmentActivity來實現相同的效果)
(一)、相關類介紹:
1、TabHost:提供選項卡(Tab頁)的視窗檢視容器。
2、TabSpec:每個選項卡都包含選項卡指示符、內容和用於識別選項卡的標籤。
TabSpec與TabHost的關係:
TabHost相當於瀏覽器中瀏覽器分佈的集合,而TabSpec則相當於瀏覽器中的 每一個分頁面。在Android中,每一個TabSpec可以是一個元件,也可以是一個佈局,TabHost將每一個分頁集中在一起,隨著選項卡的切換來分別顯示相應的介面。
(二)、TabActivity實現選項卡效果的步驟:【瞭解】
1、寫選型卡頁面特殊的佈局檔案:
- 根節點必須是TabHost,屬性android:id="@android:id/tabhost" 是固定值;
- 必須有子節點TabWidget,必須有屬性android:id="@android:id/tabs";
- 必須有一個FrameLayout佈局節點,屬性必須是android:id="@android:id/tabcontent"。
2、繼承TabActivity:(以前學習的過程中都是繼承android.app.Activity類,但是這裡需要繼承android.app.TabActivity)
3、建立TabHost物件:通過getTabHost()方法來實現。
4、分別建立TabSpec物件:
- 通過TabHost物件的newTabSpec()方法建立TabSpec物件;
- 通過setIndicator()設定標籤和圖示;
- 通過setContent()設定內容。
5、TabHost物件新增TabSpec物件。通過TabHost物件的addTab()方法實現新增選項卡。
(三)、示例程式碼:
1、佈局檔案的程式碼:
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp"/>
</LinearLayout>
</TabHost>
2、MainActivity中核心程式碼:
publicclass MainActivity extends TabActivity {
@Override
protectedvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Resources res = getResources();
TabHost tabHost = getTabHost();
TabSpec tabSpec1 = tabHost.newTabSpec("records")
.setIndicator("記錄", res.getDrawable(R.drawable.ic_launcher))
.setContent(new Intent(this, NextActivity.class));
tabHost.addTab(tabSpec1);
TabSpec tabSpec2 = tabHost.newTabSpec("records")
.setIndicator("聯絡人", res.getDrawable(R.drawable.contacts))
.setContent(new Intent(this, NextActivity.class));
tabHost.addTab(tabSpec2);
TabSpec tabSpec3 = tabHost.newTabSpec("collections")
.setIndicator("收藏夾", res.getDrawable(R.drawable.collections))
.setContent(new Intent(this, NextActivity.class));
tabHost.addTab(tabSpec3);
}
}
二、FragmentTabHost中實現選項卡效果:
(一)、與TabActivity中實現選項卡的不同之處:
1、TabHost物件的建立方式不同;
2、TabSpec物件的建立方式不同;
3、佈局檔案不同。
(二)、FragmentActivity 實現選項卡效果的步驟:【掌握】
1、寫選型卡頁面特殊的佈局檔案:
- 根節點必須是<android.support.v4.app.FragmentTabHost>;
- 必須有一個佈局節點,用來放置選項卡內容。
2、繼承FragmentActivity:(以前學習的過程中都是繼承android.app.Activity類,但是這裡需要繼承android.support.v4.app.FragmentActivity)
3、建立TabHost物件:通過(FragmentTabHost) findViewById(R.id.tabhost)方法來實現。
4、TabHost執行setup()方法:
【備註:】如果使用 findViewById() 載入 TabHost,那麼在新增一個選項卡之前, 需要呼叫 setup()方法。而在 TabActivity 中呼叫了 getTabHost() 方法後,你就不再需要呼叫setup()了。
例如:tabHost.setup(this, getSupportFragmentManager(), R.id.layout_container_tabcontent);
5、分別建立TabSpec物件:
- 通過TabHost物件的newTabSpec()方法建立TabSpec物件;
- 通過setIndicator()設定標籤和圖示;
6、TabHost物件新增TabSpec物件。通過TabHost物件的addTab()方法實現新增選項卡。
- 呼叫TabHost物件的有三個引數的addTab()方法。第一個引數是TabSpec物件,第二個引數是Fragment類的class檔案,第三個引數的往Fragment物件中傳遞的Bundle資料。
(三)、示例程式碼:
1、佈局檔案的程式碼:
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"> <TabWidget android:id="@+id/tabwidget_tabs" android:layout_width="match_parent" android:layout_height="wrap_content"/> <FrameLayout android:id="@+id/layout_container_tabcontent" android:layout_width="match_parent" android:layout_height="match_parent"/> </android.support.v4.app.FragmentTabHost>
2、MainActivity中核心程式碼:
publicclass MainActivity extends FragmentActivity { private FragmentTabHost tabHost; private Bundle bundle1, bundle2, bundle3; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tabHost = (FragmentTabHost) findViewById(R.id.tabhost); tabHost.setup(this, getSupportFragmentManager(), R.id.layout_container_tabcontent); bundle1 = new Bundle(); bundle1.putInt("tabIndex", 1); bundle2 = new Bundle(); bundle2.putInt("tabIndex", 2); bundle3 = new Bundle(); bundle3.putInt("tabIndex", 3); Resources res = getResources(); tabHost.addTab( tabHost.newTabSpec("records").setIndicator("記錄", res.getDrawable(R.drawable.records)), ContentFragment.class, bundle1); tabHost.addTab( tabHost.newTabSpec("contacts").setIndicator("聯絡人", res.getDrawable(R.drawable.contacts)), ContentFragment.class, bundle2); tabHost.addTab( tabHost.newTabSpec("collection").setIndicator("收藏夾", res.getDrawable(R.drawable.collections)), ContentFragment.class, bundle3); } }
3、ContentFragment類中的核心程式碼:
publicclass ContentFragment extends Fragment { private TextView text_fragment_info; private ListView listView_fragment; privateinttabIndex = 0; private String defaultData = "未知"; private List<String> list1, list2, list3; private ArrayAdapter<String> adapter = null; @Override publicvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle bundle = getArguments(); if (bundle != null) { tabIndex = bundle.getInt("tabIndex"); defaultData = "您訪問的是第" + tabIndex + "個欄目"; switch (tabIndex) { case 1: list1 = new ArrayList<String>(); for (int i = 0; i < 10; i++) { list1.add("記錄:" + i); } break; case 2: list2 = new ArrayList<String>(); for (int i = 0; i < 10; i++) { list2.add("聯絡人:" + i); } break; case 3: list3 = new ArrayList<String>(); for (int i = 0; i < 10; i++) { list3.add("收藏夾:" + i); } break; default: break; } } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_content, container, false); text_fragment_info = (TextView) view .findViewById(R.id.text_fragment_info); listView_fragment = (ListView) view .findViewById(R.id.listView_fragment); switch (tabIndex) { case 1: adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, list1); break; case 2: adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, list2); break; case 3: adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, list3); break; default: break; } text_fragment_info.setText(defaultData); listView_fragment.setAdapter(adapter); return view; } }
三、ViewPager實現Tab效果:(ViewPager預設滑動導航條效果)【掌握】
(一)、ViewPager Tab效果說明:
- 導航條利用<android.support.v4.view.PagerTabStrip>標籤生成;
- 導航條會隨著ViewPager內容物的滑動而發生左右側滑。
(二)、ViewPager 實現帶滑動導航條選項卡的步驟:
1、特殊的佈局檔案;
- 必須有<android.support.v4.view.ViewPager>節點;
- 在ViewPager節點中<android.support.v4.view.PagerTabStrip>子節點或者<android.support.v4.view.PagerTitleStrip>子節點,用來顯示選項卡導航條。
2、建立ViewPager物件:通過findViewById()方法來實現即可;
3、建立PagerTabStrip物件:通過findViewById()方法來實現即可,設定PagerTabStrip;
- 通過PagerTabStrip 物件的setTextColor()方法設定導航條文字顏色;
- 通過PagerTabStrip 物件的setBackgroundColor ()方法設定導航條背景顏色;
- 通過PagerTabStrip 物件的setDrawFullUnderline()方法設定導航條下方是否有完整下劃線顏色;
- 通過PagerTabStrip 物件的setTabIndicatorColor()方法設定導航條文字下方的指示顏色;
- 通過PagerTabStrip 物件的setTextSpacing()方法設定導航條文字的間隔。
4、定義ViewPager中的資料來源List<View>,自定義PagerAdapter介面卡;
5、為ViewPager物件設定介面卡。
(三)、示例程式碼:
1、佈局檔案的程式碼:
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <android.support.v4.view.ViewPager android:id="@+id/viewpager_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center"> <android.support.v4.view.PagerTabStrip android:id="@+id/pagerTabStrip_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="2dp" android:layout_gravity="top"> </android.support.v4.view.PagerTabStrip> </android.support.v4.view.ViewPager> </LinearLayout>
【注意事項】
1.這裡ViewPager和 PagerTabStrip都要把包名寫全了,不然會ClassNotFount
2.API中說:在佈局xml把PagerTabStrip當做ViewPager的一個子標籤來用,不能拿出來,不然還是會報錯
3.在PagerTabStrip標籤中可以用屬性android:layout_gravity=TOP|BOTTOM來指定title的位置
4.如果要顯示出PagerTabStrip某一頁的title,需要在ViewPager的adapter中實現getPageTitle(int)。
2、MainActivity核心程式碼
publicclass MainActivity extends Activity { private List<View> list_views; private List<String> list_titles; private ViewPager viewPager_main; private PagerTabStrip pagerTabStrip_main; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); viewPager_main = (ViewPager) findViewById(R.id.viewpager_main); pagerTabStrip_main = (PagerTabStrip) findViewById(R.id.pagerTabStrip_main); pagerTabStrip_main.setTextColor(Color.WHITE); pagerTabStrip_main.setBackgroundColor(Color.BLACK); pagerTabStrip_main.setDrawFullUnderline(true); pagerTabStrip_main.setTabIndicatorColor(Color.CYAN); pagerTabStrip_main.setTextSpacing(50); list_views = new ArrayList<View>(); list_titles = new ArrayList<String>(); LayoutInflater inflater = LayoutInflater.from(this); View view1 = inflater.inflate(R.layout.view1_viewpager, null); View view2 = inflater.inflate(R.layout.view2_viewpager, null); View view3 = inflater.inflate(R.layout.view3_viewpager, null); View view4 = inflater.inflate(R.layout.view4_viewpager, null); list_views.add(view1); list_views.add(view2); list_views.add(view3); list_views.add(view4); list_titles.add("View1"); list_titles.add("View2"); list_titles.add("View3"); list_titles.add("View4"); viewPager_main.setAdapter(new MyAdapter(list_views, list_titles)); } class MyAdapter extends PagerAdapter { private List<View> list = null; private List<String> list_titles = null; public MyAdapter(List<View> list, List<String> list_titles) { this.list = list; this.list_titles = list_titles; } @Override publicint getCount() { if (list != null) { returnlist.size(); } return 0; } @Override publicboolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(list.get(position)); returnlist.get(position); } @Override publicvoid destroyItem(ViewGroup container, int position, Object object) { container.removeView(list.get(position)); } @Override public CharSequence getPageTitle(int position) { returnlist_titles.get(position); } } }
四、ViewPager Tab效果二:(ViewPager自定義導航條效果)
(一)、效果說明:
- 自定義導航條;
- 導航條固定位置,不發生左右側滑。
(二)、ViewPager 實現自定義導航條選項卡的步驟:
1、特殊的佈局檔案;
- 必須有<android.support.v4.view.ViewPager>節點;
- 在ViewPager節點上方可自定義佈局,佈局內可放置TextView及ImageView等控制元件來自定義導航條效果。
2、初始化自定義選項卡導航條,併為選項卡設定單擊監聽事件OnClickListener;
3、初始化ViewPager;
- 建立ViewPager物件:通過findViewById()方法來實現即可;
- 定義ViewPager中的資料來源List<View>;
- 自定義PagerAdapter介面卡;
- 為ViewPager物件設定介面卡;
- 給ViewPager設定監聽器(OnPageChangeListener)。
(三)、示例程式碼:
1、佈局檔案的程式碼:
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/layout_main_tabtitle" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="24sp" android:background="#999" android:text="Tab1"/> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="24sp" android:background="#999" android:layout_marginLeft="1dp" android:text="Tab2"/> <TextView android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:textSize="24sp" android:background="#999" android:layout_marginLeft="1dp" android:text="Tab3"/> </LinearLayout> <TextView android:layout_width="match_parent" android:layout_height="3dp" android:background="#00f" android:text=""/> <android.support.v4.view.ViewPager android:id="@+id/viewPager_main" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout>
2、MainActivity核心程式碼:
publicclass MainActivity extends Activity { private ViewPager viewPager_main; private List<View> list = null; private TextView[] arr_titles = null; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initTabView(); initViewPager(); } privatevoid initTabView() { LinearLayout layout = (LinearLayout) findViewById(R.id.layout_main_tabtitle); arr_titles = new TextView[3]; for (int i = 0; i < 3; i++) { TextView textView = (TextView) layout.getChildAt(i); arr_titles[i] = textView; arr_titles[i].setEnabled(true); arr_titles[i].setBackgroundColor(Color.GRAY); arr_titles[i].setTag(i); arr_titles[i].setOnClickListener(new OnClickListener() { @Override publicvoid onClick(View v) { // 根據當前點選的position,設定ViewPager的當前item viewPager_main.setCurrentItem((Integer) v.getTag()); } }); } arr_titles[0].setEnabled(false); arr_titles[0].setBackgroundColor(Color.BLUE); } privatevoid initViewPager() { viewPager_main = (ViewPager) findViewById(R.id.viewPager_main); list = new ArrayList<View>(); LayoutInflater inflater = LayoutInflater.from(this); View view1 = inflater.inflate(R.layout.view1_viewpager, null); View view2 = inflater.inflate(R.layout.view2_viewpager, null); View view3 = inflater.inflate(R.layout.view3_viewpager, null); list.add(view1); list.add(view2); list.add(view3); viewPager_main.setAdapter(new MyAdapter(list)); viewPager_main.setOnPageChangeListener(new OnPageChangeListener() { @Override publicvoid onPageSelected(int position) { // 當頁面切換改變時,讓所有的“點”都變成可操作。 for (int j = 0; j < arr_titles.length; j++) { arr_titles[j].setEnabled(true); arr_titles[j].setBackgroundColor(Color.GRAY); } // 讓當前點選的“點”變成不可以操作。 arr_titles[position].setEnabled(false); arr_titles[position].setBackgroundColor(Color.BLUE); } @Override publicvoid onPageScrolled(int arg0, float arg1, int arg2) { } @Override publicvoid onPageScrollStateChanged(int arg0) { } }); } class MyAdapter extends PagerAdapter { private List<View> list = null; public MyAdapter(List<View> list) { this.list = list; } @Override publicint getCount() { returnlist.size(); } @Override publicboolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public Object instantiateItem(ViewGroup container, int position) { container.addView(list.get(position)); returnlist.get(position); } @Override publicvoid destroyItem(ViewGroup container, int position, Object object) { container.removeView(list.get(position)); } } }
五、Fragment + ActionBar實現Tab效果:
(一)、Fragment + ActionBar實現選項卡的步驟:
1、當前窗體Activity類要繼承於FragmentActivity,而不是Activity;
2、獲取ActionBar物件:通過當前上下文物件的getActionBar()方法來實現;
3、設定ActionBar物件的導航模式為Tab導航模式;
- actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
4、分別建立Tab物件:
- 通過ActionBar物件的newTab()方法建立Tab物件;
- 通過Tab物件的setText()設定選項卡文字;
- 通過Tab物件的setTabListener()設定選項卡監聽事件。
5、自定義ActionBar.TabListener的監聽器;
6、為ActionBar物件新增Tab物件。通過ActionBar物件的addTab()方法實現新增選項卡。
7、現場保護和恢復現場。
(二)、示例程式碼:
1、MainActivity的核心程式碼:
publicclass MainActivity extends Activity { @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initTabView(); } privatevoid initTabView() { ActionBar actionBar = getActionBar(); actionBar.setHomeButtonEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.addTab(actionBar.newTab().setText("動態") .setTabListener(new MyTabListener())); actionBar.addTab(actionBar.newTab().setText("群組") .setTabListener(new MyTabListener())); actionBar.addTab(actionBar.newTab().setText("好友") .setTabListener(new MyTabListener())); actionBar.addTab(actionBar.newTab().setText("會話") .setTabListener(new MyTabListener())); } @Override publicboolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); returntrue; } @Override publicboolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: break; case R.id.action_quip: finish(); break; default: break; } returnsuper.onOptionsItemSelected(item); } class MyTabListener implements ActionBar.TabListener { @Override publicvoid onTabSelected(Tab tab, FragmentTransaction ft) { Fragment fragment = new ContentFragment(); Bundle bundle = new Bundle(); bundle.putInt("tabIndex", tab.getPosition() + 1); fragment.setArguments(bundle); FragmentTransaction transaction = getFragmentManager() .beginTransaction(); transaction.replace(R.id.layout_fragment_container, fragment); transaction.addToBackStack(null); transaction.commit(); } @Override publicvoid onTabUnselected(Tab tab, FragmentTransaction ft) { } @Override publicvoid onTabReselected(Tab tab, FragmentTransaction ft) { } } }
六、Fragment + ViewPager實現Tab效果:
(一)、Fragment + ViewPager實現選項卡的步驟:
1、特殊的佈局檔案;
- 必須有<android.support.v4.view.ViewPager>節點;<android.support.v4.view.PagerTabStrip>
- 在ViewPager節點上方可自定義佈局,佈局內可放置TextView及ImageView等控制元件來自定義導航條效果。
2、當前窗體Activity類要繼承於FragmentActivity,而不是Activity;
3、初始化自定義選項卡導航條,併為選項卡設定單擊監聽事件OnClickListener;
4、初始化ViewPager;
- 建立ViewPager物件:通過findViewById()方法來實現即可;
- 定義ViewPager中的資料來源List<Fragment>;
- 自定義介面卡,要繼承於FragmentPagerAdapter,而不是PagerAdapter;
- 為ViewPager物件設定介面卡;
- 給ViewPager設定監聽器(OnPageChangeListener)。
【備註:】為什麼要使用FragmentPagerAdapter介面卡呢?
因為PagerAdapter的重寫方法中:
public Object instantiateItem(ViewGroup container, int position) {
container.addView(list.get(position));
return list.get(position);
}
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(list.get(position));
}
container.addView(list.get(position))和container.removeView(list.get(position))的引數都是一個View物件,而不能是Fragment物件。因為涉及到ViewPager的資料來源是Fragment的情況,一定要使用FragmentPagerAdapter介面卡。
因為繼承於FragmentPagerAdapter來自定義介面卡,自定義介面卡構造方法中的第一個引數FragmentManager只能在窗體中通過getSupportFragmentManager()來獲取,這就要求當前窗體必須繼承於FragmentActivity類。
【補充:】View、Fragment和Activity的類目錄結構:
java.lang.Object
↳ android.view.View
java.lang.Object
↳ android.app.Fragment
java.lang.Object
↳ android.support.v4.app.Fragment
java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.view.ContextThemeWrapper
↳ android.app.Activity
java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.view.ContextThemeWrapper
↳ android.app.Activity
↳ android.support.v4.app.FragmentActivity
(二)、示例程式碼:
1、佈局檔案示例程式碼:
<?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="98dp" android:background="@drawable/top_theme_blue" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="48dp"> <ImageView android:id="@+id/imageView1" android:layout_width="36dp" android:layout_height="36dp" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:src="@drawable/headimg"/> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:text="Android開發團隊" /> <ImageView android:id="@+id/imageView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:paddingLeft="10dp" android:src="@drawable/status_online"/> </LinearLayout> <LinearLayout android:id="@+id/layout_main_tabtitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingBottom="5dp" android:paddingTop="10dp"> <TextView android:id="@+id/text_tab_activity" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" android:gravity="center" android:text="動態" android:textColor="#fff" android:textSize="18sp"/> <TextView android:id="@+id/text_tab_groups" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" android:gravity="center" android:text="群組" android:textColor="#ddd" android:textSize="18sp"/> <TextView android:id="@+id/text_tab_friends" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" android:gravity="center" android:text="好友" android:textColor="#ddd" android:textSize="18sp"/> <TextView android:id="@+id/text_tab_chat" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1.0" android:gravity="center" android:text="會話" android:textColor="#ddd" android:textSize="18sp"/> </LinearLayout> <LinearLayout android:id="@+id/layout_indicateline" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:paddingBottom="2dp"> <TextView android:layout_width="0dp" android:layout_height="4dp" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:layout_weight="1"/> <TextView android:layout_width="0dp" android:layout_height="4dp" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:layout_weight="1"/> <TextView android:layout_width="0dp" android:layout_height="4dp" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:layout_weight="1"/> <TextView android:layout_width="0dp" android:layout_height="4dp" android:layout_marginLeft="15dp" android:layout_marginRight="15dp" android:layout_weight="1"/> </LinearLayout> </LinearLayout> <android.support.v4.view.ViewPager android:id="@+id/viewPager_main" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="#fff"/> </LinearLayout>
2、Fragment檔案中核心程式碼:同上
3、MainActivity中的核心程式碼:
publicclass MainActivity extends FragmentActivity { private ViewPager viewPager_main; private List<Fragment> fragmentsList; private TextView[] arr_titles; private TextView[] arr_lines; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initIndicateLine(); initTabView(); initViewPager(); } privatevoid initTabView() { LinearLayout layout = (LinearLayout) findViewById(R.id.layout_main_tabtitle); arr_titles = new TextView[4]; for (int i = 0; i < arr_titles.length; i++) { TextView textView = (TextView) layout.getChildAt(i); arr_titles[i] = textView; arr_titles[i].setEnabled(true); arr_titles[i].setTag(i); arr_titles[i].setOnClickListener(new OnClickListener() { @Override publicvoid onClick(View v) { viewPager_main.setCurrentItem((Integer) v.getTag()); } }); arr_titles[0].setEnabled(false); } } privatevoid initViewPager() { viewPager_main = (ViewPager) findViewById(R.id.viewPager_main); fragmentsList = new ArrayList<Fragment>(); Fragment fragment1 = new ContentFragment(); Bundle bundle1 = new Bundle(); bundle1.putInt("tabIndex", 1); fragment1.setArguments(bundle1); Fragment fragment2 = new ContentFragment(); Bundle bundle2 = new Bundle(); bundle2.putInt("tabIndex", 2); fragment2.setArguments(bundle2); Fragment fragment3 = new ContentFragment(); Bundle bundle3 = new Bundle(); bundle3.putInt("tabIndex", 3); fragment3.setArguments(bundle3); Fragment fragment4 = new ContentFragment(); Bundle bundle4 = new Bundle(); bundle4.putInt("tabIndex", 4); fragment4.setArguments(bundle4); fragmentsList.add(fragment1); fragmentsList.add(fragment2); fragmentsList.add(fragment3); fragmentsList.add(fragment4); viewPager_main.setAdapter(new MyAdapter(getSupportFragmentManager(), fragmentsList)); viewPager_main.setOnPageChangeListener(new OnPageChangeListener() { @Override publicvoid onPageScrollStateChanged(int position) { } @Override publicvoid onPageScrolled(int arg0, float arg1, int arg2) { } @Override publicvoid onPageSelected(int position) { for (int i = 0; i < arr_titles.length; i++) { arr_titles[i].setEnabled(true); arr_lines[i].setBackgroundColor(Color.TRANSPARENT); } arr_titles[position].setEnabled(false); arr_lines[position].setBackgroundColor(Color.WHITE); } }); viewPager_main.setCurrentItem(0); } privatevoid initIndicateLine() { LinearLayout layout = (LinearLayout) findViewById(R.id.layout_indicateline); arr_lines = new TextView[4]; for (int i = 0; i < arr_lines.length; i++) { TextView view = (TextView) layout.getChildAt(i); arr_lines[i] = view; arr_lines[i].setTag(i); arr_lines[i].setBackgroundColor(Color.TRANSPARENT); } arr_lines[0].setBackgroundColor(Color.WHITE); } class MyAdapter extends FragmentPagerAdapter { private List<Fragment> fragmentsList = null; public MyAdapter(FragmentManager fm) { super(fm); } public MyAdapter(FragmentManager fm, List<Fragment> fragmentsList) { super(fm); this.fragmentsList = fragmentsList; } @Override public Fragment getItem(int arg0) { returnfragmentsList.get(arg0); } @Override publicint getCount() { returnfragmentsList.size(); } } @Override publicboolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); returntrue; } }
七、Fragment + ActionBar + ViewPager 實現Tab書籤導航效果:
(一)、實現步驟:
- 窗體繼承FragmentActivity ,自定義Fragment;
- 初始化ActionBar,設定ActionBar導航模式,for迴圈設定AcitonBar的監聽器setTabListener , 自定義TabListener;
- 初始化ViewPager,for迴圈生成介面卡的資料來源LIst<Fragment> ,設定介面卡FragmentPagerAdapter,自定義介面卡;設定ViewPager監聽器setOnPageChangeListener。
(二)、核心程式碼:
publicclass MainActivity extends FragmentActivity implements ActionBar.TabListener { /** * The {@link android.support.v4.view.PagerAdapter} that will provide * fragments for each of the sections. We use a * {@link android.support.v4.app.FragmentPagerAdapter} derivative, which * will keep every loaded fragment in memory. If this becomes too memory * intensive, it may be best to switch to a * {@link android.support.v4.app.FragmentStatePagerAdapter}. */ SectionsPagerAdapter mSectionsPagerAdapter; /** * The {@link ViewPager} that will host the section contents. */ ViewPager mViewPager; @Override protectedvoid onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Set up the action bar. final ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // Create the adapter that will return a fragment for each of the three // primary sections of the app. mSectionsPagerAdapter = new SectionsPagerAdapter( getSupportFragmentManager()); // Set up the ViewPager with the sections adapter. mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager.setAdapter(mSectionsPagerAdapter); // When swiping between different sections, select the corresponding // tab. We can also use ActionBar.Tab#select() to do this if we have // a reference to the Tab. mViewPager .setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { @Override publicvoid onPageSelected(int position) { actionBar.setSelectedNavigationItem(position); } }); // For each of the sections in the app, add a tab to the action bar. for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) { // Create a tab with text corresponding to the page title defined by // the adapter. Also specify this Activity object, which implements // the TabListener interface, as the callback (listener) for when // this tab is selected. actionBar.addTab(actionBar.newTab() .setText(mSectionsPagerAdapter.getPageTitle(i)) .setTabListener(this)); } } @Override publicboolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); returntrue; } @Override publicvoid onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { // When the given tab is selected, switch to the corresponding page in // the ViewPager. mViewPager.setCurrentItem(tab.getPosition()); } @Override publicvoid onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } @Override publicvoid onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) { } /** * A {@link FragmentPagerAdapter} that returns a fragment corresponding to * one of the sections/tabs/pages. */ publicclass SectionsPagerAdapter extends FragmentPagerAdapter { public SectionsPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { // getItem is called to instantiate the fragment for the given page. // Return a DummySectionFragment (defined as a static inner class // below) with the page number as its lone argument. Fragment fragment = new DummySectionFragment(); Bundle args = new Bundle(); args.putInt(DummySectionFragment.ARG_SECTION_NUMBER, position + 1); fragment.setArguments(args); return fragment; } @Override publicint getCount() { // Show 3 total pages. return 3; } @Override public CharSequence getPageTitle(int position) { Locale l = Locale.getDefault(); switch (position) { case 0: return getString(R.string.title_section1).toUpperCase(l); case 1: return getString(R.string.title_section2).toUpperCase(l); case 2: return getString(R.string.title_section3).toUpperCase(l); } returnnull; } } /** * A dummy fragment representing a section of the app, but that simply * displays dummy text. */ publicstaticclass DummySectionFragment extends Fragment { /** * The fragment argument representing the section number for this * fragment. */ publicstaticfinal String ARG_SECTION_NUMBER = "section_number"; public DummySectionFragment() { } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main_dummy, container, false); TextView dummyTextView = (TextView) rootView .findViewById(R.id.section_label); dummyTextView.setText(Integer.toString(getArguments().getInt( ARG_SECTION_NUMBER))); return ro