Android应用ViewPager和TabLayout动态加载Fragment,并实现view和tab动态刷新。

原创 2016年12月01日 23:35:22

Android应用ViewPager和TabLayout动态加载Fragment

 

1 应用背景和目的

项目中需要实现根据服务器端返回的主题模块加载相应的主题内容,其中有三个主题模块为默认加载,该应用程序启动时手机端需加载出来,其余主题模块根据网络请求服务器端返回的主题进行加载。达到由服务器端自动配置主题,推送给手机用户动态加载相应主题内容的效果。

下图为模拟示例,其中tab0、tab1、tab2为默认主题,tab3、tab4、tab5为网络端推动过来的主题模块,并且加载插入的位置在tab0与tab1之间。


2 实现框架

Android端app利用ViewPager和TabLayout的方式实现相应主题内容Fragment的动态加载。示例程序app name为VFTest,运用这个方式,动态加载fragment之后,切换tab,会出现程序崩溃,如下图所示。


查看崩溃得logcat日志如下图所示:


崩溃得原因是Can't change tag of fragment CommonFragment{44d090b0#1 id=0x7f0c0071 android:switcher:2131492977:1}。分析知FragmentPagerAdapter为之前加载好的Fragment设置的tag,由于在原有位置插入了一个新的Fragment,导致两个tag不一致,switcher在切换时出错抛出的异常。

3 解决方案

         根据问题,拟解决方案是,当在原有位置加载新的Fragment时,重新调用FragmentPagerAdapter的instantiateItem接口,刷新adapter的中fragment。查看instantiateItem源码,
@Override
public Object instantiateItem(ViewGroup container, int position) {
    if (mCurTransaction == null) {
        mCurTransaction = mFragmentManager.beginTransaction();
    }

    final long itemId = getItemId(position);

    // Do we already have this fragment?
    String name = makeFragmentName(container.getId(), itemId);
    Fragment fragment = mFragmentManager.findFragmentByTag(name);
    if (fragment != null) {
        if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);
        mCurTransaction.attach(fragment);
    } else {
        fragment = getItem(position);
        if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);
        mCurTransaction.add(container.getId(), fragment,
                makeFragmentName(container.getId(), itemId));
    }
    if (fragment != mCurrentPrimaryItem) {
        fragment.setMenuVisibility(false);
        fragment.setUserVisibleHint(false);
    }

    return fragment;
}
其中final long itemId = getItemId(position);决定是否重新加载新的Fragment,于是需要在自定的FragmentPagerAdapter中重写getItemId,得到不同的itemId,即:
@Override
public long getItemId(int position) {
    super.getItemId(position);
    if (fragments != null) {
        if (position < fragments.size()) {
            return fragments.get(position).hashCode();       //important
        }
    }
    return super.getItemId(position);
}

不同的Fragment分配的HashCode不同,从而实现刷新adapter中的fragment。

 

当然可能还遇到另一个问题,就是加载的Fragment的内容没有来得及刷新,这里在动态加载之后,还需要记录当前ViewPager的Item的位置,动态加载之后,需要跳到其对应的原有Fragment重置之后的位置,才能即时刷新Fragment内容。

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

TabLayout的ViewPager中的Fragment点击刷新的问题

使用Fragment的时候难免会遇到想在视力可见或不可见之中做些操作,此时通常想到类似Activity的onResume()和onPause()方法。Fragment中也确实也这两个方法,然而亲测su...
  • nnmmbb
  • nnmmbb
  • 2017-03-31 14:06
  • 1247

FragmentPagerAdapter刷新fragment最完美解决方案

先感谢kingjxl2006的博客

Android标签页TabLayout控件实战及ViewPager取消预加载

一、概述在2015年的google大会上,google发布了新的Android Support Design库,里面包含了几个新的控件,其中就有一个TabLayout,它就可以完成TabPageInd...

TabLayout和动态生成fragment的个数

1.在布局中先书写tablayout的布局,以及与之相对应的viewpager android.support.design.widget.TabLayout android:layout_...

Android笔记--在切换fragment时,让fragment里的listview实时刷新数据的一种方法

使用FragmentPagerAdapter 可以处理多个 Fragment 页面的横向滑动。 但在使用过程中,会发现当从fragmentA切换到fragmentB页面时,需要的功能是fragmen...

Android ViewPager刷新Fragment数据(ViewPager获取Fragment对象)

ViewPager没有提供根据position获取Fragment的方法,单纯的用FragmentStatePagerAdapter(或者FragmentPagerAdapter)里面自己创建的Fra...

笔记:ViewPager+FragmentPagerAdapter数据刷新问题

做了一个ViewPager+FragmentPagerAdapter滑动功能,后面由于一个需求,要求每次离开ViewPager对应页面回来后都有跟服务器请求数据,来确保数据是否发生改变。。。。这里省略...

动态加载fragment配合TabLayout

这种配合使用TabLayout来控制,获取position比较方便,fragment不需要一次性全部加载,而是在第一次使用的时候加载。也需要WindowManager和事务进行管理。因为没有用到Vie...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)