63

找了好久这个问题,现在无果:

如何确定片段正在从后台恢复?我在 FragmentActivity 中使用兼容性库和 ListFragment。当 ListFragment 中的某个项目被选中时,会启动一个新的 Fragment 来替换 ListFragment。

我注意到,当 FragmentActivity 暂停时,会调用 Fragment 的 onSaveInstanceState。但是当通过 FragmentTransaction 将 Fragment 放入回栈时,不会调用 onSaveInstanceState,然后使用 null savedInstanceState Bundle 调用生命周期方法 onCreateView 和 onActivityCreated。

我问这个是因为我想在创建或恢复 Fragment 时加载一些数据,但当用户返回时不是这样。后台。

我看过如何检查片段是否从后台恢复? 但想添加更多细节,希望这会引发答案。

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

但是请注意:此方法可以在 onDestroy() 之前的任何时间调用。在很多情况下,一个片段可能大部分被拆除(例如当放置在没有显示 UI 的后台堆栈时),但它的状态不会被保存,直到它拥有的 Activity 实际需要保存它的状态。

所以 onSaveInstanceState 绝对是不可能的......

4

6 回答 6

44

I think that most simple way is do this for example in onViewCreated() method:

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.

于 2012-07-22T19:26:25.880 回答
32
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.

于 2011-10-27T17:18:13.807 回答
20

When a fragment goes to back-stack onDestroyView() called. Not onDestroy().

And when a fragment pops from back-stack onCreateView() called. Not onCreate().

So add a boolean mIsRestoredFromBackstack to fragment and follow as below:

@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;
}
于 2016-01-07T11:07:56.627 回答
8

MAJOR EDIT: Oct 15 2013

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

What this figure tells you is that when a fragment is restored from the backstack, its onCreate() is not called, while its onCreateView() is.


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();
    }
}
于 2013-03-24T12:11:44.290 回答
4

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())); you can override onHiddenChanged(boolean hidden)

@Override
public void onHiddenChanged(boolean hidden) {
    // TODO Auto-generated method stub
    super.onHiddenChanged(hidden);
    if (!hidden) {
        //fragment became visible
        //your code here
    }
}
于 2013-09-25T14:34:51.713 回答
0

In some cases you can use isVisible method to understand is it first showing of a fragment or is it restored from the backstack.

于 2012-08-16T10:35:14.533 回答