Android 如何自定义FragmentTabHost中某一个Tab的点击效果
2016-11-28 21:50
525 查看
问题
iOS上的Tab Bar相信大家都很熟悉了,就是界面底部几个按钮,点击可以切换子页面。而在Android上,可以用support v4中的
FragmentTabHost来实现类似效果,它继承自
TabHost,每个子页面都是一个
Fragment。
今天遇到一个需求,需要在点击Tab按钮后,不切换子页面,而是跳转到一个新的页面。通过查阅文档,
FragmentTabHost与其父类
TabHost似乎都没有提供相关函数可以自定义Tab的点击事件。只有一个当Tab切换完成后的回调监听
OnTabChangeListener,但是切换已经完成为时已晚啊。
在查阅文档无果后,我祭出了Google,但是却苦于不知道该如何组织关键词(英文不会,中文离谱),试了几个关键词依然无果。既然如此,就尝试看下源码吧,没想到最终还是非常简单就可以解决问题,遂记录一下。
首先我们来看一下
FragmentTabHost的基本使用,来自官方文档
mTabHost = new FragmentTabHost(getActivity()); mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.fragment1); mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"), FragmentStackSupport.CountingFragment.class, null); mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"), LoaderCursorSupport.CursorLoaderListFragment.class, null);
第二行通过
setup进行初始化,三四行通过
addTab方法添加了两个Tab,我们就从Tab的添加入手,开始追踪源码,看看它都做了什么,是如何设置每个Tab的点击事件的。以下的源码经过了简化,只保留部分关键信息。
源码追踪
首先是FragmentTabHost,它继承自
TabHost,增加了一个
addTab的重载方法,第二个参数接收Fragment的class,用于Fragment相关逻辑。在完成对Fragment的处理后,继续调用父类
TabHost的
addTab方法。
public class FragmentTabHost extends TabHost { public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) { ... addTab(tabSpec); } }
然后来到
TabHost,其中成员变量
mTabWidget是Tab的容器。在
addTab方法中,先取出了Tab的View,然后执行mTabWidget的addView,将Tab添加到容器中。
public class TabHost extends FrameLayout { private TabWidget mTabWidget; public void addTab(TabSpec tabSpec) { ... View tabIndicator = tabSpec.mIndicatorStrategy.createIndicatorView(); ... mTabWidget.addView(tabIndicator); ... } }
最后来到
TabWidget,可以看到它继承自我们的老朋友LinearLayout,这为Tab View提供了线性排布。在
addView方法的最后,我们找到了为每个Tab设置点击监听的地方。
public class TabWidget extends LinearLayout { @Override public void addView(View child) { ... super.addView(child); // TODO: detect this via geometry with a tabwidget listener rather // than potentially interfere with the view's listener child.setOnClickListener(new TabClickListener(getTabCount() - 1)); child.setOnFocusChangeListener(this); } }
解决问题
通过一路追踪源码,现在我们已经知道了FragmentTabHost是如何设定每个Tab的点击事件的。最后设置监听器的地方给了我启发,假如能够获取到Tab View,就可以设置自己的点击监听,同时覆盖掉了系统的监听器,从而完成自定义点击效果的任务。
于是从
TabWidget反过来查找获取Tab View的方法。首先
TabWidget提供了
getChildTabViewAt(int index)方法,可以根据Tab的索引获取到Tab View。然后通过
TabHost的
getTabWidget可以获取到TabWidget 。得到目标Tab View后,设定自己的OnClickListener,搞定任务。
下面代码演示了设置第一个Tab点击事件的方法。
mTabHost.getTabWidget().getChildTabViewAt(0).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { } });
总结
系统的源码真的写的非常清楚,只要肯耐心看,很多问题都可以迎刃而解。转载地址:
http://www.jianshu.com/p/3b0ff7a4bde1
相关文章推荐
- 如何自定义FragmentTabHost中某一个Tab的点击效果
- Android 一个Activity 里面放置多个 Fragment 实现点击切换的Tab 页面效果
- Android 得到FragmentTabhost 某一个Tab的View
- Android,自定义一个点击变暗效果的ImageView
- Android FragmentTabhost 监听tab点击事件
- 如何 TabHostFragment自定义 tab键(indicator)
- Android FragmentTabhost 截断tab点击事件
- Android ImageButton 如何实现一个点击效果
- android自定义TabHost点击效果
- Android FragmentTabhost 监听tab点击事件
- android fragmenttabhost 有点击效果却没有切换的解决方法
- Android学习 - 小知识(读取一个已经安装的包的权限与两个Activity跳转的时,如何自定义翻页效果)
- Android 如何自定义一个简单的组件和自定义的点击事件(中级)
- Fragment与自定义布局实现类似tab的效果
- Android中Button自定义点击效果
- Android开发:如何安全的中止一个自定义线程Thread
- Android自定义Button点击效果
- Android中的Button自定义点击效果实例代码
- 如何在Android中写和使用一个自定义的java库
- android开发--------如何去掉TAB下的白线(tabHost去白线)