在上一篇中,我们将了使用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; 这一点千万别导入错误的包。