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();
    }
阅读 8.4k
1 个回答

我按照你的流程写了一个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();

搞定!

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
1 篇内容引用
推荐问题
宣传栏