44

我的 MainActivity 中有一个 ListFragment。这是我设置片段对象的方式。

FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
Fragment newFragment = new MyFragment();
fragmentTransaction.replace(R.id.framecontainer, newFragment, "tag");
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();

问题是当用户按下后退按钮时,我至少必须通过调用来更改操作栏和菜单

getActionBar().setTitle(title);
getActionBar().setDisplayHomeAsUpEnabled(isEnabled);
invalidateOptionsMenu();

我必须知道当前正在显示什么样的片段,以便我知道如何设置操作栏。我将设置选项存储在片段中作为参数。

String title = fragment.getArguments().getString("KEY_TITLE");
boolean isEnabled = fragment.getArguments().getBoolean("KEY_ISENABLED");

我确实搜索了相关问题,我意识到我可以通过调用来获取片段

MyFragment fragment = (MyFragment) getSupportFragmentManager()
        .findFragmentByTag("tag");

但是,我必须将所有标签存储在自定义堆栈中,并在每次用户按下后退按钮时调用pop()onBackPressed()

所以,我的问题是我有没有办法直接从堆栈中获取当前可见的片段?

注意:请记住,片段类型不同,而不仅仅是 MyFragment。

4

5 回答 5

72

这样的事情应该可以帮助您的活动在后台解决这个问题:

private Fragment getCurrentFragment(){
    FragmentManager fragmentManager = getSupportFragmentManager();
    String fragmentTag = fragmentManager.getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1).getName();
    Fragment currentFragment = fragmentManager.findFragmentByTag(fragmentTag);
    return currentFragment;
}

@Override
public void onBackPressed() {
    Fragment fragmentBeforeBackPress = getCurrentFragment();
    // Perform the usual back action
    super.onBackPressed();
    Fragment fragmentAfterBackPress = getCurrentFragment();
}

希望这可以帮助。

于 2013-02-22T16:31:32.157 回答
36
FragmentManager.findFragmentById(fragmentsContainerId) 

函数返回返回堆栈顶部Fragment的链接。使用示例:

    fragmentManager.addOnBackStackChangedListener(new OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            Fragment fr = fragmentManager.findFragmentById(R.id.fragmentsContainer);
            if(fr!=null){
                Log.e("fragment=", f.getClass().getSimpleName());
            }
        }
    });

编辑:现在在 2018 年有getFragments方法,FragmentManager其中 return List<Fragment>。来自文档:The order of the fragments in the list is the order in which they were added or attached. 所以看起来我们可以从该列表中取出最后一个片段:

     List<Fragment> list = fragmentManager.getFragments();
     //get last one 
     Fragment topFragment = list.get(list.size() - 1);
于 2014-04-05T13:05:16.620 回答
3

看起来有些事情已经变得更好了,因为下面的代码对我来说非常适合,但我没有在已经提供的答案中找到它,也没有在相邻的问题中找到它。

科特林:

supportFragmentManager.fragments[supportFragmentManager.fragments.size - 1]

爪哇:

getSupportFragmentManager().getFragments()
.get(getSupportFragmentManager().getFragments().size() - 1)
于 2018-11-10T16:20:46.137 回答
1

已经有一个标记为正确的答案,我的附加信息与此没有什么不同。但是,我在使用接收器时遇到了麻烦,试图弄清楚接收器所在的片段是否是堆栈上的当前顶部片段。你可以很容易地在很多 NPE 和 Index 中跑出界。因此我写了这个,也许它可以帮助某人。

private boolean isFragmentOnTop(Activity parentActivity, final String fragmentName){
        FragmentManager fmManager = parentActivity.getFragmentManager();
        if(fmManager.getBackStackEntryCount() == 0){
            LOG.i("BackStack entry count is 0: " + this);
            return false;
        }
        String fragmentNameOnStackTop = "";
        final FragmentManager.BackStackEntry topEntry = fmManager.getBackStackEntryAt(fmManager.getBackStackEntryCount() -1);
        if(topEntry != null) {
            fragmentNameOnStackTop = topEntry.getName();
        }
        LOG.d("Got fragments name: " + fragmentNameOnStackTop);
        return fragmentNameOnStackTop != null ? fragmentNameOnStackTop.equals(fragmentName) : false;
    }

请注意,这适用于具有一些片段的活动。请注意,如果您使用 ViewPager 和 childfragmentmanager。

并且不要忘记将 fragmentName 设置为FragmentTransaction.addToBackStack(fragmentName)

于 2014-08-28T11:32:35.630 回答
1

这个辅助方法从栈顶获取片段:

public Fragment getTopFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String fragmentTag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return getSupportFragmentManager().findFragmentByTag(fragmentTag);
}
于 2017-10-17T07:06:38.760 回答