不拆卸的onSaveInstanceState触发一个片段() [英] Detaching a Fragment not triggering onSaveInstanceState()

查看:112
本文介绍了不拆卸的onSaveInstanceState触发一个片段()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的Andr​​oid应用程序有一个动作条这里面片段占有一定的变化的FrameLayout 。我试图用的onSaveInstanceState 当标签被更改保存片段的状态,所以它可以在 onCreateView

问题是,的onSaveInstanceState 永远不会被调用。在片段 onDestroyView onCreateView 被称为方法,但捆绑提供给 onCreateView 仍然空。

有人请给我解释一下,当的onSaveInstanceState 实际上是所谓的,我怎么能确定它被调用切换标签,或保存和恢复状态的最佳做法时,的片段当它被分离并重新连接?

片段:

  @覆盖
    公共查看onCreateView(LayoutInflater充气器,容器的ViewGroup,
        捆绑savedInstanceState){
    查看查看= inflater.inflate(R.layout.event_log,集装箱,FALSE);    //检索保存状态
    如果(savedInstanceState!= NULL){
        的System.out.println(日志检索);
    }其他{
        的System.out.println(日志为空);
    }    返回视图。
}@覆盖
公共无效的onSaveInstanceState(捆绑outState){
    的System.out.println(日志保存);
    super.onSaveInstanceState(outState);
    //更多code
}

活动:

  / **
 *拆下当前片段,因为另外一个被附接。
 * /
@覆盖
公共无效onTabUnselected(标签选项卡,FragmentTransaction英尺){
    如果(tab.getText()。等于(的getString(R.string.tab_events))){
        如果(frEventLog!= NULL){
            ft.detach(frEventLog);
    }
}


解决方案

片段#的onSaveInstanceState 只调用时,活动托管片段被破坏,有机会的话,你可以回来相同的活动和碎片仍添加到 FragmentManager 。最常见的情况是屏幕旋转。

我觉得你的片段也将需要做的<一个href=\"http://developer.android.com/reference/android/app/Fragment.html#setRetainInstance%28boolean%29\"><$c$c>setRetainInstance(true)的onCreate 为例。不完全肯定这一点,虽然。

您也应该看到被调用此方法时,你preSS例如home键。这会破坏活动,但您可以通过使用例如任务列表回去吧。

如果你只是分离()片段所有你需要做的就是它后面是要求 FragmentManager 它。

有两个例子,你应该看看:

<一个href=\"https://github.com/android/platform_development/blob/master/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.java\"><$c$c>ActionBar FragmentTabs 和<一个href=\"https://github.com/android/platform_development/blob/master/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.java\"><$c$c>TabHost FragmentTabs

TabHost 例使用

  ft.add(containerId,片段标签);
//后来
片段= mActivity.getSupportFragmentManager()findFragmentByTag(标签)。

找previously加入片段 S,的情况下工作,直到删除() A 片段


关于 onCreateView / onDestroyView :这就是所谓一旦片段被分离,因为下一次连接时,它需要创建一个新的查看。需要注意的是片段#onDetached()分离不叫()片段,因为它仍然附着在活动。它只是从视图层次结构分离。


有是如何留住片段状态另一个很好的例子/如何使用碎片保留在Android的训练状态 - <一个href=\"http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html#config-changes\">Caching 的位图

这例如缺少一个临界线,但:

 公共静态RetainFragment findOrCreateRetainFragment(FragmentManager FM){
    RetainFragment片段=(RetainFragment)fm.findFragmentByTag(TAG);
    如果(片段== NULL){
        片段=新RetainFragment();
        。fm.beginTransaction()加(片段,TAG).commit(); //&LT;&LT;添加此
    }
    返回片段;
}

My Android application has an ActionBar that changes which Fragment occupies a certain FrameLayout. I am trying to use onSaveInstanceState to save the state of a Fragment when the tab is changed, so that it can be recovered in onCreateView.

The problem is, onSaveInstanceState is never called. The Fragment's onDestroyView and onCreateView methods are called, but the Bundle supplied to onCreateView remains null.

Can someone please explain to me when onSaveInstanceState is actually called, how I can make sure it gets called when switching tabs, or the best practice for saving and restoring the state of a Fragment when it is detached and re-attached?

Fragment:

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
        Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.event_log, container, false);

    // Retrieve saved state
    if (savedInstanceState != null){
        System.out.println("log retrieved");
    } else {
        System.out.println("log null");
    }

    return view;
}

@Override
public void onSaveInstanceState(Bundle outState) {
    System.out.println("log saved");
    super.onSaveInstanceState(outState);
    // more code
}

Activity:

/**
 * Detach the current Fragment, because another one is being attached.
 */
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    if (tab.getText().equals(getString(R.string.tab_events))){
        if (frEventLog != null) {
            ft.detach(frEventLog);
    }
}

解决方案

Fragment#onSaveInstanceState is only called when the Activity hosting the Fragment is destroyed AND there is a chance that you can come back to the same activity AND the fragment is still added to the FragmentManager. The most common case would be screen rotation.

I think your Fragment will also need to do setRetainInstance(true) in onCreate for example. Not exactly sure about that point though.

You should also see this method being called when you press the home button for example. That will destroy the activity but you can go back to it by using the task list for example.

If you just detach() the fragment all you need to do to get it back is to ask the FragmentManager for it.

There are two examples you should have a look at:

ActionBar FragmentTabs and TabHost FragmentTabs

The TabHost example uses

ft.add(containerId, fragment, tag);
// later
fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag);

to find the instances of previously added Fragments, works until you remove() a Fragment


Regarding onCreateView / onDestroyView: That is called once a fragment gets detached because the next time you attach it needs to create a new View. Note that Fragment#onDetached() is not called when you detach() the fragment because it is still attached to the Activity. It is only detached from the view-hierarchy.


There is another nice example on how to retain fragment state / how to use fragments to retain state in Android Training - Caching Bitmaps.

That example is missing a critical line though:

public static RetainFragment findOrCreateRetainFragment(FragmentManager fm) {
    RetainFragment fragment = (RetainFragment) fm.findFragmentByTag(TAG);
    if (fragment == null) {
        fragment = new RetainFragment();
        fm.beginTransaction().add(fragment, TAG).commit(); // << add this
    }
    return fragment;
}

这篇关于不拆卸的onSaveInstanceState触发一个片段()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆