2 sld22525482 sld22525482 于 2016.09.26 14:26 提问

Fragment调用另一个Fragment replace hide 方法无效??求解决。。

selectorListFragment = new SelectorListFragment();
wiredNetWorkFragment = new WiredNetWorkFragment();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        FragmentManager fragmentManager = getActivity().getFragmentManager();


        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            FragmentTransaction ft_info_list = fragmentManager.beginTransaction();
            ft_info_list.replace(R.id.network_set_content, wifiInfoFragment);
            ft_info_list.addToBackStack(null);
            ft_info_list.commit();

            FragmentTransaction fragmentTransaction_right = fragmentManager.beginTransaction();
            fragmentTransaction_right.hide(WifiListFragment.this).commit();

            FragmentTransaction ft_select_list = fragmentManager.beginTransaction();
            ft_select_list.hide(selectorListFragment);
            ft_select_list.commit();

        }
    });

这里的selectorListFragment并没有被隐藏。。。

1个回答

wangclhuangmt
wangclhuangmt   2016.09.26 14:55

从Activity_A打开Activity_B并展示Fragment,此时切换到设置->语言,修改系统语言,之后再次从Launcher启动Activity_A并进入次级Activity_B,控制fragment隐藏/显示按钮失效。

分析后返现,切换语言后,Activity_B执行了onDestroy和onCreate方法,所以Activity_B中的Fragment对象已经是新的了,因此无法控制原Fragment的显示于隐藏,而直接注释掉super.onSaveInstanceState()方法会导致无法保存Activity_B的状态。这里贴一下我的解决方案:
protected void onSaveInstanceState(Bundle outState) {
if (mDialpadFragment != null) {
getFragmentManager().putFragment(outState,"MyFragment",mDialpadFragment);
}
super.onSaveInstanceState(outState);
}
在onSaveinstanceState中保存之前的Fragment对象。

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_bug);
if (savedInstanceState != null) {
mDialpadFragment = (DialpadFragment)getFragmentManager().getFragment(savedInstanceState,"MyFragment");
}
在重新创建的时候判断Bundle如果不为空,则取出之前保存的Fragment。这里因为FragmentManger().getFragment()返回值是Fragment对象,因此需要向下转型为自己的Fragment对象。

缺点:

虽然能够正常使用该对象控制Fragment的显示和隐藏,但如果此时调用mDialpadFragment.isVisible()却会返回false,查看源码后发现isVisible的代码如下:

final public boolean isVisible() {
return isAdded() && !isHidden() && mView != null
&& mView.getWindowToken() != null && mView.getVisibility() == View.VISIBLE;
}
导致isVisible()返回false的主要原因是mView.getWindowToken() == null,这是因为Activity已经重新创建了,之前通过onSaveInstanceState方法保存的WindowToken已经找不到对应的Window,因此getWindowToken()为null。

解决方案:

在DialpadFragment中自定义一个isVisible(Context context):

public boolean isVisible(Context context) {
    return isAdded() && !isHidden() && getView() != null
            && getView().getVisibility() == View.VISIBLE;
}

不去判断windowToken的值。同时最好在onResume之后再使用mDialpadFragment.isVisible(context)来判断Fragment是否可见。

Csdn user default icon
上传中...
上传图片
插入图片