您的位置:首页 > 移动开发 > Android开发

FragmentTabHost用法简介

2017-03-27 22:44 246 查看
      最近接到新的需求,要求把原本用TabActivity实现词库UI界面重新使用Fragment来实现。不得不吐槽当初开发的人,居然还用TabActivity开发。因为没有滑动切换界面的需求(如果有滑动需求,建议直接用ViewPager实现),为了尽量少的改动代码,所以采用了FragmentTabHost去实现。

FragmentTabHost 适用范围

      适用范围同TabActivity,用于有多个标签页,需要点击标签页进行切换的界面。市场上很多APP都是这样的界面,比如下厨房。



XML布局

如果在xml文件里只设置了FragmentTabHost,没有设置其他子元素,那么会采用默认的布局,Tab在上,页面在下的方式。需要注意的是虽然在Activity里我们传入了real_content id,但是xml文件里的FramentLayout实际上并不是最终加载Fragamnt的容器,他的作用仅仅是提供了一个view id。我们完全可以去掉这个FrameLayout,在初始化FragmentTabHost传入一个其他已经存在的view id。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<FrameLayout
android:id="@+id/real_content"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</FrameLayout>


Activity实现

FragmentTabHost是v4包里的类,而且需要传入v4包的FragmentManager对象,所以Activity需要继承FragmentActivity(或者AppCompatActivity)

public class FragmentTabHostActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//加载xml文件
setContentView(R.layout.activity_fragment_tab_host);
FragmentTabHost tabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);

//初始化FragmentTabHost
tabHost.setup(this,getSupportFragmentManager(),R.id.real_content);

//创建tab
//addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args)
// 第一个参数不能通过new的方式创建TabSpec对象,因为其构造函数是private属性。tabHost.newTabSpec("tab1") 创建一个TabSpec并将设置ID;setIndicator("tab1") 设置标签名
// 第二个参数是传入需要显示的Fragment类
// 第三个参数传入的参数,在Fragment里可以通过getArguments()获得
Bundle bundle = new Bundle();
bundle.putString("tag","1st fragment");
tabHost.addTab(tabHost.newTabSpec("tab1").setIndicator("tab1"),TabFragment.class,bundle);

bundle = new Bundle();
bundle.putString("tag","2nd fragment");
tabHost.addTab(tabHost.newTabSpec("tab2").setIndicator("tab2"),TabFragment.class,bundle);

//添加监听器
tabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
Toast.makeText(FragmentTabHostActivity.this,tabId,Toast.LENGTH_SHORT).show();
}
});
}
}


Fragment实现

同理,需要继承v4包里的Fragment。Fragment里的代码相对简单,需要注意的是其生命周期。在TabActivity中,当Tab切换时,旧Activity会被销毁,回调onDestroy(),新的Activity会被创建,回调onCreate(),这意味着每一次切换都伴随着Activity的创建和销毁。而FragmentTabHost只会创建Fragment一次,之后每次切换tab,只会回调onCreateView(),所以只要在onCreateView()缓存当前的view,就能大大提高加载速度。
//onCreate方法只会调用一次
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
Bundle bundle = getArguments();
//创建tab的时候传入的bundle参数
if (bundle != null){
mTag = bundle.getString("tag");
}
super.onCreate(savedInstanceState);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tab_host_, container, false);
TextView tv = (TextView) rootView.findViewById(R.id.text);
tv.setText(mTag);
return rootView;
}


自定义布局

FragmentTabHost 默认是Tab在上,页面在下的布局,如果我们需要tab在下,页面再上的布局呢。那么我们需要在xml里自定义布局。

注意 :
这里的id为real_content即为最终加载Fragment的容器,必须为FrameLayout。
TabWidget是LinearLayout的子类,需要设置android
4000
:orientation属性,用于显示所有tab
id为tabcontent的FrameLayout在这里仅仅是为了兼容TabHost,如果不设置会抛出异常。

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">

<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<FrameLayout
android:id="@+id/real_content"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"/>

<TabWidget
android:id="@android:id/tabs"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<FrameLayout
android:id="@android:id/tabcontent"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

</LinearLayout>

</android.support.v4.app.FragmentTabHost>

</FrameLayout>


效果如图所示



    


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android