在上一篇中,我們將了使用ViewPager實現Tab效果。如果沒有閱讀過,可以點擊下面的地址:
http://www.cnblogs.com/fuly550871915/p/4849893.html
在這一篇中我們講一下使用Fragment實現Tab效果,而這種實現方式也是推薦的方式。與用ViewPager實現的效果有一點不同。
一、效果展示
如下圖:

使用Fragment不支持手指左右滑動,只支持底部按鈕的點擊來切換。它的中間不再是一個ViewPager布局了,而是一個用來存放Fragment的FrameLayout的布局。其頂部布局和底部布局沒有什么變化。下面我們來看具體的代碼吧。
二、資源准備
圖片資源仍然是我們在上一篇文章中准備好的。直接復制到res下的drawable文件夾下就好。
三、具體代碼
(1)布局搭建
頂部布局和底部布局以及幾個Tab布局都沒有變化,我們直接復制即可。只是把主布局中間的換成FrameLayout而已。主布局代碼如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 > 7 8 <include layout="@layout/top"/> 9 10 <FrameLayout 11 android:id="@+id/lay_frame" 12 android:layout_width="match_parent" 13 android:layout_height="0dp" 14 android:layout_weight="1"></FrameLayout> 15 16 <include layout="@layout/bottum"/>" 17 18 19 20 </LinearLayout>
(2)構建每一個fragment類
下面我們就要把每一個Tab變成一個Fragment。新建類Hfragment繼承自Fragment。如下:
1 import android.os.Bundle; 2 import android.support.v4.app.Fragment; 3 import android.view.LayoutInflater; 4 import android.view.View; 5 import android.view.ViewGroup; 6 7 public class HFragment extends Fragment{ 8 9 10 public View onCreateView(LayoutInflater inflater, ViewGroup container, 11 Bundle savedInstanceState) { 12 13 return inflater.inflate(R.layout.tab01,container,false); 14 } 15 }
同理我們還要新建類Sfragment,Ufragment,Yfragment。它們都是繼承自Fragment。只不過中間渲染的布局分別為Tab02,Tab03,Tab04.這樣我們的fagment就完成了。
注意:繼承的類Fragment一定導入android.support.v4.app.Fragment;這個包,而不能是其他包下的。
(3)在MainActivity里就可以實現Tab了。
在MainActivty中,實現Tab主要的技術就是利用FragmentTransaction,開啟一個事務。在這個事務中,將我們的fragment加入進來,並嵌套在中間的布局FrameLayout上。然后通過事務控制隱藏和顯示每一個fragment來達到切換的目的。具體代碼如下:
1 import android.os.Bundle; 2 import android.app.Activity; 3 import android.support.v4.app.Fragment; 4 import android.support.v4.app.FragmentActivity; 5 import android.support.v4.app.FragmentManager; 6 import android.support.v4.app.FragmentTransaction; 7 import android.view.Menu; 8 import android.view.View; 9 import android.view.View.OnClickListener; 10 import android.widget.ImageButton; 11 import android.widget.LinearLayout; 12 13 public class MainActivity extends FragmentActivity implements OnClickListener{ 14 15 16 private Fragment hfrag; 17 private Fragment sfrag; 18 private Fragment ufrag; 19 private Fragment yfrag; 20 21 private ImageButton himg; 22 private ImageButton simg; 23 private ImageButton uimg; 24 private ImageButton yimg; 25 26 private LinearLayout hlay; 27 private LinearLayout slay; 28 private LinearLayout ulay; 29 private LinearLayout ylay; 30 31 private FragmentTransaction ftr;//事務 32 33 34 35 36 protected void onCreate(Bundle savedInstanceState) { 37 super.onCreate(savedInstanceState); 38 setContentView(R.layout.activity_main); 39 40 initView();//用來初始化數據控件 41 42 initEvent();//初始化事件 43 44 setSelected(0);//進入界面,先讓其顯示 第一個 45 } 46 47 48 private void initEvent() { 49 50 //設定點擊事件 51 52 hlay.setOnClickListener(this); 53 slay.setOnClickListener(this); 54 ulay.setOnClickListener(this); 55 ylay.setOnClickListener(this); 56 57 } 58 59 60 //用來初始化的方法 61 private void initView() { 62 63 //獲得按鈕 64 himg = (ImageButton) findViewById(R.id.ibtn_hudie); 65 simg = (ImageButton) findViewById(R.id.ibtn_set); 66 uimg = (ImageButton) findViewById(R.id.ibtn_user); 67 yimg = (ImageButton) findViewById(R.id.ibtn_yang); 68 69 //獲得底部的線性布局 70 hlay = (LinearLayout) findViewById(R.id.lay_hudie); 71 slay = (LinearLayout) findViewById(R.id.lay_set); 72 ulay = (LinearLayout) findViewById(R.id.lay_user); 73 ylay = (LinearLayout) findViewById(R.id.lay_yang); 74 75 76 } 77 78 79 //監聽點擊事件 80 public void onClick(View v) { 81 82 resetImg();//將按鈕復位 83 84 switch(v.getId()){ 85 86 case R.id.lay_hudie: 87 setSelected(0); 88 break; 89 case R.id.lay_set: 90 setSelected(1); 91 break; 92 case R.id.lay_user: 93 setSelected(2); 94 break; 95 case R.id.lay_yang: 96 setSelected(3); 97 break; 98 99 } 100 101 } 102 103 104 105 106 //自定義一個方法,設定布局中間的FrameLayout的選擇狀態 107 private void setSelected(int i) { 108 109 //需要將按鈕變亮,且需要切換fragment的狀體 110 //獲取事務 111 FragmentManager fm = getSupportFragmentManager(); 112 ftr = fm.beginTransaction();//開啟一個事務 113 hideTransaction(ftr);//自定義一個方法,來隱藏所有的fragment 114 115 switch(i){ 116 case 0: 117 if(hfrag == null){ 118 //實例化每一個fragment 119 hfrag = new HFragment(); 120 //千萬別忘記將該fragment加入到ftr中 121 ftr.add(R.id.lay_frame, hfrag); 122 } 123 ftr.show(hfrag); 124 himg.setImageResource(R.drawable.hudie2); 125 break; 126 case 1: 127 if(sfrag == null){ 128 sfrag = new SFragment(); 129 ftr.add(R.id.lay_frame, sfrag); 130 } 131 ftr.show(sfrag); 132 simg.setImageResource(R.drawable.set2); 133 break; 134 case 2: 135 if(ufrag == null){ 136 137 ufrag = new UFragment(); 138 ftr.add(R.id.lay_frame, ufrag); 139 } 140 ftr.show(ufrag); 141 uimg.setImageResource(R.drawable.user2); 142 break; 143 case 3: 144 if(yfrag == null){ 145 yfrag = new YFragment(); 146 ftr.add(R.id.lay_frame, yfrag); 147 } 148 ftr.show(yfrag); 149 yimg.setImageResource(R.drawable.yang2); 150 break; 151 } 152 ftr.commit();//最后千萬別忘記提交事務 153 } 154 155 //隱藏fragment 156 private void hideTransaction(FragmentTransaction ftr) { 157 158 if(hfrag != null){ 159 ftr.hide(hfrag);//隱藏該fragment 160 } 161 if(sfrag != null){ 162 ftr.hide(sfrag); 163 } 164 if(ufrag != null){ 165 ftr.hide(ufrag); 166 } 167 if(yfrag != null){ 168 ftr.hide(yfrag); 169 } 170 } 171 172 //復位按鈕,即設置按鈕為暗色 173 private void resetImg() { 174 175 himg.setImageResource(R.drawable.hudie); 176 simg.setImageResource(R.drawable.set); 177 uimg.setImageResource(R.drawable.user); 178 yimg.setImageResource(R.drawable.yang); 179 180 } 181 }
注意:在這里繼承的是FragmentActivity,導入包仍舊是android.support.v4.app.Fragment;
好了,這樣我們就實現了Tab效果,運行一下程序可以看看。
四、總結
(1)為什么推薦Fragment來實現Tab效果?
因為使用Fragment可以將每一個Tab跟我們的MainActivity分開。這樣有利於在每一個Fragment中實現較為復雜的效果,而MainnActivity只起到一個組合的作用。如果使用ViewPager方式 實現Tab,我們在每一個Tab上編寫較為復雜的效果時會發現所有的代碼都幾乎在MainActivity上完成,這樣會導入MainActivty冗長,不利於閱讀和維護。
(2)在實現過程中,一律使用包android.support.v4.app.Fragment; 這一點千萬別導入錯誤的包。
