如何确定从backstack恢复的片段

发布于 2024-12-12 01:18:10 字数 1067 浏览 1 评论 0原文

搜索这个问题有一段时间了,现在没有结果:

How to certainfragment is being returned from backstack? 我在 FragmentActivity 中使用兼容性库和 ListFragment。当选择ListFragment内的某个项目时,将启动一个新的Fragment来替换ListFragment。

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

我问这个是因为我想在创建或恢复片段时加载一些数据,但当用户通过返回时则不然。后退堆栈。

我查看了如何检查片段是否已恢复从后台堆栈? 但想添加更多细节,希望这能引起答案。

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

但请注意:此方法可以在 onDestroy() 之前的任何时间调用。在很多情况下,片段可能大部分被拆除(例如当放置在返回堆栈上且没有 UI 显示时),但直到其所属 Activity 真正需要保存其状态时,才会保存其状态。

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

Been searching for this issue for a while to no avail now:

How to determine fragment is being restored from backstack?
I'm using the compatibility library and a ListFragment inside a FragmentActivity. When an item inside ListFragment is selected, a new Fragment is started to replace the ListFragment.

I noticed that when the FragmentActivity gets paused, the Fragment's onSaveInstanceState is called. 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.

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. 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

Note however: this method may be called at any time before 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.

So onSaveInstanceState is definitely out of the question...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

扛刀软妹 2024-12-19 01:18:10

我认为最简单的方法是在 onViewCreated() 方法中执行此操作:

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

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

因为当 android 将 Fragment 放在 BackStack 上时,它只会破坏其视图,但不会杀死实例本身,因此当恢复 Fragment 时 mAlreadyLoaded 仍为 true从后栈。

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.

灯下孤影 2024-12-19 01:18:10
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.
                }
            }
        });

使用这个addOnBackStackChangedListener。

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.

待天淡蓝洁白时 2024-12-19 01:18:10

当片段进入后台堆栈时,调用 onDestroyView() 。不是onDestroy()

当一个片段从后台堆栈弹出时,调用 onCreateView() 。不是onCreate()

因此,将一个 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;
}

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;
}
最冷一天 2024-12-19 01:18:10

主要编辑:2013 年 10 月 15 日

当应用程序置于后台并返回前台时,先前的解释(保留在下面以供参考)失败。

相反,最好将返回堆栈的当前大小与创建片段时的大小进行比较。放入后台堆栈。


请仔细查看 http://developer.android 中的图 2。 com/guide/components/fragments.html#Creating

这个图告诉你的是,当一个fragment从backstack恢复时,它的onCreate()不会被调用,而它的onCreateView( )是的。


所以,你可能想做这样的事情:

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();
    }
}

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();
    }
}
你又不是我 2024-12-19 01:18:10

如果您将片段添加到后台堆栈,并且经过一些操作,您可以使用fragmentTransaction.hide(fragment)隐藏它,然后像fragmentTransaction.show(fragmentManager.findFragmentByTag(fragment.getName()));一样从后台恢复它;您可以覆盖 onHiddenChanged(boolean hide)

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

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
    }
}
并安 2024-12-19 01:18:10

在某些情况下,您可以使用 isVisible 方法了解它是第一次显示片段还是从后堆栈恢复。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文