ViewPager的Fragment中嵌套的Fragment怎么实现刷新数据?
我在ViewPager的Fragment中又嵌套了两个Fragment。希望实现按下对应按钮显示其中一个Fragment,隐藏另一个Fragment的功能。
现在这个功能实现了,但是问题来了,当我想刷新这两个Fragment里数据时,出现了奇怪的现象。当我刷新完后,按下按钮想要隐藏当前Fragment ,显示另一个Fragment时,在那个Fragment里把两个FragMent的UI都显示了出来,我的hide功能被屏蔽了。怎么解决这个问题呢?
下面是我的代码
嵌套的Fragment的代码,两个Fragment代码类似,在管理他们的那个Fragment里面使用setUI()刷新
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.bottom_fragment_one, container, false);
tmpD= (TextView) view.findViewById(R.id.tmp_d);
tmpN = (TextView) view.findViewById(R.id.tmp_n);
imageD= (SimpleDraweeView) view.findViewById(R.id.image_d);
imageN= (SimpleDraweeView) view.findViewById(R.id.image_n);
setUI();
return view;
}
//用来设置UI,更新UI时重新从数据库获取数据,进行设置
public void setUI(){
Forecast forecast = mFrecastDao.getForecastByCity(mCity);
tmpD.setText(forecast.getDaily_1_max());
tmpN.setText(forecast.getDaily_1_min());
imageD.setImageURI(getImageUri(forecast.getDaily_1_code_d()));
imageN.setImageURI(getImageUri(forecast.getDaily_1_code_n()));
}
两个按钮实现隐藏其中一个Fragment,显示另一个的功能
@Override
public void onClick(View v) {
FragmentManager fm = getChildFragmentManager();
// 开启Fragment事务
FragmentTransaction transaction = fm.beginTransaction();
switch (v.getId())
{
case R.id.button_left:
transaction.hide(mBottomTwo);
transaction.show(mBottomOne);
break;
case R.id.button_right:
transaction.hide(mBottomOne);
transaction.show(mBottomTwo);
break;
}
// 事务提交
transaction.commit();
}
同时调用两个Fragment的刷新代码进行刷新
public void UpdateUI(){
mBottomOne.setUI();
mBottomTwo.setUI();
}
Answers
我按照你的流程写了一个demo,复现了你描述的bug现象,
建议你在合适的地方打印
子Fragment的数量
,比如在
UpdateUI()
或者
onClick()
:
Log.d(TAG, "child fragment count: " + getChildFragmentManager().getFragments().size());
不清楚你在父fragment何处调用
ft.add()
来添加子fragment,我是在
onCreateView
.
当滑动ViewPager时,导致父fragment视图被销毁,即
onDestroyView()
被调到,
再次滑动到该父fragment时,重建视图,即
onCreateView()
被调到,
ft.add()
被再次调到,再次添加2个子fragment,这就导致了你提到的问题,而并非是
ft.hide()
不起作用。
你可以加更多的打印信息观察这些方法被调用的情况,尤其要打印你调用的add.
一个变通的方法可以解决这个问题,在commit之前先remove所有的子Fragment:
// workaround: remove child fragment to avoid child fragment added again.
if (fm.getFragments() != null && fm.getFragments().size() > 0) {
Log.d(TAG, "remove all child fragment");
for (Fragment childFragment : fm.getFragments()) {
ft.remove(childFragment);
}
}
// then, ft.add();
// lastly, ft.commit();
搞定!