如果在RecyclerView里面的item同时出现三个 ViewPager+TabLayout+Fragment的布局的话,
并且你写入了数据,如果没有什么以外的话,出来的效果是这样的。
我基本上都是已经写入了假数据的,可是第二和第三个ViewPager只能看到title。你没看错我今天遇到的坑就是这样的。
第一次遇到这种问题,我还能怎么办我也很绝望啊。
然后只能埋头研究了,经过一晚上的奋斗,终于得知道了bug所在。其实看了一些源码+上一些猜想才想到怎么修这个bug的。
那么废话不多说,直接上代码把。首先我们解决第一部分,先看看FragmentPagerAdapter源码里面的的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;
}
在String name = makeFragmentName(container.getId(), itemId);
和mCurTransaction.add(container.getId(), fragment,makeFragmentName(container.getId(), itemId));
这句代码中我们发现fragment都是以container的id+itemId(gettemId()) 两个参数计算出来作为fragment的储存的tag key值。
FragmentManager是activity自己创建的东西,你又不可能自己new一个,然后呢所有的Fragment都塞进FragmentManager
取的时候是根据布局的id取的,而我又用了三个相同的布局,那么问题就简单了,直接存储重复id然后不论你创建多少个都
只能取出你创建的第一个viewPage的item布局
解决办法:
重写继承了FragmentPagerAdapter的getItemId()方法如下
@Override
public long getItemId(int position) {
return pageData.get(position).hashCode();
}
然而你会发现问题还是没有解决,那么我们再来继续解决问题。
第二个问题跟第一个相似,那就是instantiateItem下面的ViewGroup。
请仔细看此方法
mCurTransaction.add(container.getId(), fragment,makeFragmentName(container.getId(), itemId));
有没有发现这里还有一个getId。那么问题来了,你仔细想看,既然Fragment都是在一个池子里面的,那么你将Fragment根据ID塞进
ViewGroup里面的话是啥情况,先说明ViewGroup其实就是ViewPager。我们三个item都是ViewPager。那么你直接根据id塞入的话,activity回去寻找id为你添加进入改id的ViewGroup的控件,可是我们这里有三个。
so?明白了没?
只能设置给第一个ViewPager.
所以不论你添加多少个ViewPager 下面都不会有数据显示出来就是这个问题。
解决办法:
在RecyclerView创建ViewHolder初始化所有view控件的时候设置viewPager这么一句
viewPager.setId(datas.get(position).hashCode());
然后问题就基本上解决了。
是不是很惊喜很意外,这么简单的bug让我长篇大论啰嗦了这么多。