android之FragmentTabHost使用
在使用淘宝和京东这类购物类App的时候,他们这些应用都有一个底面的导航栏,看起来还是比较好看的。顺便想实现一个购物类的app。这个正好可以用上。
类似的方法
之前在看别人的项目中,看到有有过类似的实现。但是在印象中是使用TabHost+RadioGroup实现的,由于不是记得很清楚了,于是去网上google了一把。发现了有如下几种设计思路:
第一种:使用TabHost+TabSpec实现
第二种:使用TabHost+RadioGroup实现
第三种:就是FragmentTabHost实现
其他两种都可以算是比较过时的用法,
简单的使用
使用FragmentTabHost还是比较简单的,但是也有几点需要注意。
首先是布局:
<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:paddingBottom="0dp"></TabWidget>
</FrameLayout>
</android.support.v4.app.FragmentTabHost>
在FragmentTabHost
中可以放一个FrameLayout
和一个TabWidget
,其中TabWidget
是用来放选项卡的内容的,FrameLayout
是用来承载每个选项卡所对应的界面的。在使用布局的时候需要注意的是这三个控件的id
。
FragmentTabHost
的id
需要是@android:id/tabhost
,FrameLayout
的id
需要是@android:id/tabcontent
,TabWidget
的id
需要是@android:id/tabs
。当布局处理完成之后。需要在Activity
中进行初始化。
mTabHost = (FragmentTabHost) view.findViewById(android.R.id.tabhost);
mTabHost.setup(getActivity(), getFragmentManager(), android.R.id.tabcontent);
需要调用setup()
方法对FragmentTabHost
进行一些初始化操作,然后就可以添加一些选项卡了。
Tag homeTag = new Tag(R.string.tag_home, R.drawable.selector_home, HomeFragment.class);
Tag categoryTag = new Tag(R.string.tag_category, R.drawable.selector_category, CategoryFragment.class);
Tag hotTag = new Tag(R.string.tag_hot, R.drawable.selector_hot, HotFragment.class);
Tag mineTag = new Tag(R.string.tag_mine, R.drawable.selector_mine, MineFragment.class);
Tag cartTag = new Tag(R.string.tag_cart, R.drawable.selector_cart, CartFragment.class);
mTabHost.addTab(mTabHost.newTabSpec("home").setIndicator(setTagIndicator(homeTag)), homeTag.getFragment(), null);
mTabHost.addTab(mTabHost.newTabSpec("category").setIndicator(setTagIndicator(categoryTag)), categoryTag.getFragment(), null);
mTabHost.addTab(mTabHost.newTabSpec("hot").setIndicator(setTagIndicator(hotTag)), hotTag.getFragment(), null);
mTabHost.addTab(mTabHost.newTabSpec("cart").setIndicator(setTagIndicator(cartTag)), cartTag.getFragment(), null);
mTabHost.addTab(mTabHost.newTabSpec("mine").setIndicator(setTagIndicator(mineTag)), mineTag.getFragment(), null);
其中setTagIndicator()
是为选项卡设置布局
:
private View setTagIndicator(Tag tag) {
View view = mInflater.inflate(R.layout.tab_view, null);
ImageView image = (ImageView) view.findViewById(R.id.tab_iamge);
TextView dest = (TextView) view.findViewById(R.id.tab_dest);
image.setImageResource(tag.getPic());
dest.setText(tag.getDest());
return view;
}
到这这里我就完成了简单的选项卡界面的搭建。效果如下:

一些问题
为Fragment设置Presenter
在使用FragmentTabHost
的时候,因为想跟上时代的潮流,使用一把MVP。但是在FragmentTabHost
遇到了一些挫折。在Google的官方的MVP例子中,使用Fragment
作为View。在Activity
中向Fragment
设置Presenter
,但是在FragmentTabHost
中我不能按照demo
中的样子设置Presenter
,原因在于,在Activity
中,我能够拿到Fragment
的实例,但是在使用FragmentTabHost
中不能很好的拿到我想要的Fragment
的实例。虽然可以在FragmentTabHost
的OnTabChangedListener
中拿到Fragment
的实例,但是,这个所拿到的实例是不是当其点的选项卡所应该展示的实例,因此该路径放弃了。然后想到,我为这些Fragment
设置了Tag
那我应该能够通过这些Tag
取到对应Fragment
,但实验下来,还是不行。因此我只能在Fragmnet
的onCreate()
方法中,为该Fragment
设置Presenter
。
Fragment使用懒加载
之前逛掘金的时候,发现有人对Fragment
使用了所谓的懒加载技术,之前在写项目的时候,因为在ViewPager
中使用了Fragment
,如果不使用懒加载技术时,ViewPager
中的Fragment
将会被全部加载,这种感觉体验不好。在FragmentTabHost
中也脑子没动,直接对FragmentTabHost
中的Fragment
使用懒加载技术,因为感觉FragmentTabHost
和ViewPager
类似,都可以包裹多个Fragment
。当写完进行测试的时候,什么鬼?,在setUserVisibleHint()
方法中所打的log
完全没有信息。当时就怀疑是否是自己参考错了,重新去看了一遍使用说明,确认自己写的方法没有错误。反复的测试,还是一样的效果。只能带着困惑去google。原来使用FragmentTagHost
并没有像ViewPager
一样使用了预加载,没有预加载,何来的懒加载呢?