「Efficient Android Threading 笔记」- C1 Android Components and the Need for Multiprocessing Android RecyclerView Android Socket Programming Supporting Multiple Screens Make a Reusable UI in Android App Development 如何在 Android Studio 中包含 *.so library,并使用库中定义的方法? 使用 SpannableString 格式化字符串,实现前景色、下划线、超链接、图文混排等 如何使用 bound service 完成进程间通信? 创建自定义视图 Creating custom views 通过 Android Theme & Style 定制应用的样式 「译」Android ViewPropertyAnimator 介绍 Android Animation Interpolator - Android 动画插值器源码笔记 「译」Android Animation in Honeycomb by Chet Haase(Android 3.0系统中的动画机制) 从 Android Sample ApiDemos 中学习 android.animation API 的用法 如何学习 Android Animation? 如何实现 Android ListView「上拉加载更多」? 「译」向Big Nerd Ranch提问:为什么Fragment在Android App开发中非常重要? 分类整理我在 SegmentFault 上针对某些问题作的回答 Android Servcie 后台服务总结笔记 如何在Android设备旋转时暂存数据以保护当前的交互状态? Android Message Handler 消息处理机制总结笔记 如何获取FragmentTabHost中指定标签页的Fragment? Fragment子类必须包含一个public无参构造器 如何更新及替换ViewPager中的Fragment? 如何使用Android UI Fragment开发“列表-详情”界面? 一个Android音频文本同步的英文有声读物App的开发过程 「Android编程权威指南笔记」Android应用本地化 通过jfeinstein10/SlidingMenu实现Android侧滑菜单 为Ubuntu14.04部署Android App的Eclipse开发环境 「Android编程权威指南笔记」使用ListFragment显示列表 「Android编程权威指南笔记」SDK版本与兼容 「Android编程权威指南笔记」Android布局和组件 「Android编程权威指南笔记」UI Fragment 「Android编程权威指南笔记」Activity 第一次开发iOS App和Android的对比总结笔记 「App Training笔记」创建第一个应用 「App Training笔记」开发入门训练大纲 Android APP - 从远程FTP服务器下载文件到本地

如何获取FragmentTabHost中指定标签页的Fragment?

2015年10月12日

使用FragmentTabHost构建了包含几个标签页的界面,如何获取指定标签页的Fragment?
How to get Fragment in FragmentTabHost?

TabHost中Fragment的Tag

一般通过FragmentTabHost.addTab(TabSpec tabSpec, Class<?> clss, Bundle args)方法添加fragment:

TabSpec tabSpec = mTabHost.newTabSpec("TAB_TAG_" + i).setIndicator("TAB_TITLE_" + i); 
mTabHost.addTab(tabSpec, MyFragment.class, null);    

而方法TabHost.TabSpec newTabSpec(String tag)的参数tag就是fragment的tag.
那么,我们有2种方法获取fragment。

通过Fragment.getTag()获取Fragment

最开始采用了这种办法,首先获取fragment manager管理的fragment列表,然后根据tag从列表中查找fragment:

private Fragment getFragment(int tabId)
{
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    for(Fragment fragment : fragments) {
        String str1 = fragment.getTag();
        String str2 = String.valueOf("TAB_TAG_" + tabId);
        if(str1 != null && str1.equals(str2)) // 最开始没有检查str1是否为空,导致crash!
            return fragment;
    }
    return null;
}

然后掉进坑里了!
因为拿到的fragment列表,不仅仅是TabHost包含的fragment,还包含向attached activity添加的其它fragment,而如果这些fragment并未设置tag,那么fragment.getTag()将返回null,然后就crash了

通过FragmentManager.findFragmentByTag(String tag)获取Fragment

感觉这个方法最简洁。

private Fragment getFragment(int tabId)
{
    return getSupportFragmentManager().findFragmentByTag("TAB_TAG_" + tabId);
}

onTabChanged()中获取的fragment有时为空

打印了一些log发现,

  • 如果第1次切换到某个标签页,在onTabChanged()方法中立刻调用findFragmentByTag()时,返回的总是null,但如果延迟一段时间,就一定可以获取fragment.
  • 如果再次切换到某个标签页,在onTabChanged()中不需要延时,总可以返回fragment.
@Override
public void onTabChanged(final String tabId)
{
    Fragment fg = getSupportFragmentManager().findFragmentByTag(tabId);
    Log.d(TAG, "onTabChanged(): " + tabId + ", fragment " + fg);

    if (fg == null) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Fragment fg = getSupportFragmentManager().findFragmentByTag(tabId);
                Log.d(TAG, "onTabChanged() delay 50ms: " + tabId + ", fragment " + fg);
            }
        }, 50);
    }
}

LogCat输出:

// cannot get the selected fragment immediately if the fragment has never been instantiated.
onTabChanged(): 1, fragment null
onTabChanged() delay 50ms: 1, fragment HistoryFragment{6f7a9d5 #2 id=0x7f09006e 1}
onTabChanged(): 2, fragment null
onTabChanged() delay 50ms: 2, fragment HistoryFragment{10c59e72 #3 id=0x7f09006e 2}

// can get the selected fragment immediately if the fragment already instantiated.
onTabChanged(): 1, fragment HistoryFragment{6f7a9d5 #2 id=0x7f09006e 1}
onTabChanged(): 2, fragment HistoryFragment{10c59e72 #3 id=0x7f09006e 2}

How to get current selected Fragment in FragmentTabHost


知识共享许可协议
li2的博客WeiYi.Li 创作,采用 知识共享 署名-非商业性使用 4.0 国际 许可协议进行许可。
© 2011-2017. All rights reserved by WeiYi.Li. Powerd by Jekyll & LinAnYa's Theme