FragmentTransaction.show()和hide()没有效果

旅行者3号 发布于 2014/01/13 22:49
阅读 14K+
收藏 0
主界面猜用FragmentActivity,在二级界面奔溃之后(就是弹出系统提示的“XXX停止运行”),返回主界面,在切换fragment的时候调用FragmentTransaction.show()和hide()没有效果。
加载中
0
y
yangqing_dt
楼主解决了吗?我也遇到了相同的问题,不知道什么原因
y
yangqing_dt
回复 @郝炯淞 : 谢谢,我研究下,代码重构,原来的代码没有这个问题,新代码就遇到了,不知道什么原因还
旅行者3号
旅行者3号
没有解决,据说是fragment被挂起了。不明觉厉。得研究下FragmentTabHost源码
0
y
yangqing_dt

已经解决了,受你提示,考虑到二级页面崩溃后,activity在onSaveInstanceState 的时候保存了fragment的实例,由于崩溃activity 重新走onCreate方法,不能重新创建fragment 导致show 或hidden 的时候不起作用

解决方法:onSaveInstanceState的时候不保存当前activity的状态就ok了

@Override
protected void onSaveInstanceState(Bundle outState) {
// super.onSaveInstanceState(outState);
}


0
y
yihongyuelan

引用来自“yangqing_dt”的评论

已经解决了,受你提示,考虑到二级页面崩溃后,activity在onSaveInstanceState 的时候保存了fragment的实例,由于崩溃activity 重新走onCreate方法,不能重新创建fragment 导致show 或hidden 的时候不起作用

解决方法:onSaveInstanceState的时候不保存当前activity的状态就ok了

@Override
protected void onSaveInstanceState(Bundle outState) {
// super.onSaveInstanceState(outState);
}


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

分析后返现,切换语言后,Activity_B执行了onDestroy和onCreate方法,所以Activity_B中的Fragment对象已经是新的了,因此无法控制原Fragment的显示于隐藏,而直接注释掉super.onSaveInstanceState()方法会导致无法保存Activity_B的状态。这里贴一下我的解决方案:

    @Override
    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是否可见。

欢迎交流:yihongyuelan@gmail.com

0
帆与海
楼主解决了获取短信的问题了么,最近做项目也遇到了这样的需求,求帮忙,不胜感激
返回顶部
顶部