简体   繁体   English

如何确定从Backstack恢复的片段

[英]How to determine fragment restored from backstack

Been searching for this issue for a while to no avail now: 一直在寻找这个问题但现在无济于事:

How to determine fragment is being restored from backstack? 如何确定片段是从backstack恢复? I'm using the compatibility library and a ListFragment inside a FragmentActivity. 我在FragmentActivity中使用兼容性库和ListFragment。 When an item inside ListFragment is selected, a new Fragment is started to replace the ListFragment. 选择ListFragment中的项目时,将启动新的片段以替换ListFragment。

I noticed that when the FragmentActivity gets paused, the Fragment's onSaveInstanceState is called. 我注意到当FragmentActivity暂停时,会调用Fragment的onSaveInstanceState。 But when the Fragment is put into the back stack via FragmentTransaction, onSaveInstanceState doesn't get called, then the lifecycle methods onCreateView and onActivityCreated gets called with null savedInstanceState Bundle. 但是当Fragment通过FragmentTransaction放入后台堆栈时,onSaveInstanceState不会被调用,那么使用null savedInstanceState Bundle调用生命周期方法onCreateView和onActivityCreated。

I'm asking this because I want to load some data when the Fragment is created or restored, but not so when user comes back via. 我问这个是因为我想在创建或恢复Fragment时加载一些数据,但是当用户通过它回来时却不是这样。 backstack. 堆栈中。

I've looked at How to check if Fragment was restored from a backstack? 我看过如何检查片段是否从后台恢复? but want to add more details in hopes this would incite an answer. 但希望增加更多细节,希望这会引发答案。

Edit: just noticed http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle) says 编辑:刚刚注意到http://developer.android.com/reference/android/app/Fragment.html#onSaveInstanceState(android.os.Bundle)

Note however: this method may be called at any time before onDestroy(). 但请注意:可以在onDestroy()之前的任何时间调用此方法。 There are many situations where a fragment may be mostly torn down (such as when placed on the back stack with no UI showing), but its state will not be saved until its owning activity actually needs to save its state. 在许多情况下,片段可能大部分被拆除(例如放置在没有显示UI的后台堆栈上),但是在其拥有的活动实际上需要保存其状态之前,其状态将不会被保存。

So onSaveInstanceState is definitely out of the question... 所以onSaveInstanceState绝对是不可能的......

I think that most simple way is do this for example in onViewCreated() method: 我认为最简单的方法是在onViewCreated()方法中执行此操作:

if (savedInstanceState == null && !mAlreadyLoaded) {
    mAlreadyLoaded = true;

    // Do this code only first time, not after rotation or reuse fragment from backstack
}

Because when android put fragment on backstack, it only destroy its view, but don't kill instance itself, so mAlreadyLoaded will be still true when fragment will be restored from backstack. 因为当android将片段放在backstack上时,它只会破坏它的视图,但是不会杀死实例本身,因此当从backstack恢复片段时,mAlreadyLoaded仍然是真的。

getSupportFragmentManager().addOnBackStackChangedListener(new OnBackStackChangedListener() {    
            public void onBackStackChanged() {
                Log.i(TAG, "back stack changed ");
                int backCount = getSupportFragmentManager().getBackStackEntryCount();
                if (backCount == 0){
                                   // block where back has been pressed. since backstack is zero.
                }
            }
        });

use this addOnBackStackChangedListener. 使用这个addOnBackStackChangedListener。

When a fragment goes to back-stack onDestroyView() called. 当一个片段进入后台堆栈onDestroyView()调用。 Not onDestroy() . 不是onDestroy()

And when a fragment pops from back-stack onCreateView() called. 当一个片段从后台堆栈中弹出onCreateView()调用。 Not onCreate() . 不是onCreate()

So add a boolean mIsRestoredFromBackstack to fragment and follow as below: 所以在片段中添加一个boolean mIsRestoredFromBackstack ,如下所示:

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    mIsRestoredFromBackstack = false;
}

@Override
public void onResume()
{
    super.onResume();
    if(mIsRestoredFromBackstack)
    {
        // The fragment restored from backstack, do some work here!
    }
}

@Override
public void onDestroyView()
{
    super.onDestroyView();
    mIsRestoredFromBackstack = true;
}

MAJOR EDIT : Oct 15 2013 主要编辑 :2013年10月15日

The previous explanation (kept below for reference) fails when the application is put to the background and brought back to the foreground. 当应用程序放到后台并返回到前台时,先前的解释(保留在下面以供参考)失败。

Instead, it is better to compare the current size of the backstack with the one when the fragment was created & put into the backstack. 相反,最好将后台堆叠的当前大小与创建碎片并放入后台堆叠时的大小进行比较。


Take a good look at Figure 2 in http://developer.android.com/guide/components/fragments.html#Creating http://developer.android.com/guide/components/fragments.html#Creating中仔细查看图2

What this figure tells you is that when a fragment is restored from the backstack, its onCreate() is not called, while its onCreateView() is. 这个数字告诉你的是,当从backstack恢复一个片段时,它的onCreate()不会被调用,而它的onCreateView()就是。


So, you may want to do something like this: 所以,你可能想做这样的事情:

public class MyFragment extends Fragment {
    int mBackStackSize = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBackStackSize = getFragmentManager().getBackStackEntryCount();
    }

    public boolean isRestoredFromBackstack() {
        return mBackStackSize > getFragmentManager().getBackStackEntryCount();
    }
}

If you added fragment to backstack, and after some manipulation you hide it using fragmentTransaction.hide(fragment) and then restore it from backstack like fragmentTransaction.show(fragmentManager.findFragmentByTag(fragment.getName())); 如果你将片段添加到backstack,并在一些操作后使用fragmentTransaction.hide(片段)隐藏它,然后从backstack恢复它,如fragmentTransaction.show(fragmentManager.findFragmentByTag(fragment.getName())); you can override onHiddenChanged(boolean hidden) 你可以覆盖onHiddenChanged(布尔隐藏)

@Override
public void onHiddenChanged(boolean hidden) {
    // TODO Auto-generated method stub
    super.onHiddenChanged(hidden);
    if (!hidden) {
        //fragment became visible
        //your code here
    }
}

在某些情况下,您可以使用isVisible方法来了解它是首先显示片段还是从Backstack恢复。

Fragment.getFragmentManager() == null 

在添加之前和弹出之后

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM