我在Android中玩碎片。

我知道我可以通过使用以下代码更改一个片段:

FragmentManager fragMgr = getSupportFragmentManager();
FragmentTransaction fragTrans = fragMgr.beginTransaction();

MyFragment myFragment = new MyFragment(); //my custom fragment

fragTrans.replace(android.R.id.content, myFragment);
fragTrans.addToBackStack(null);
fragTrans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragTrans.commit();

我的问题是,在Java文件中,如何获得当前显示的片段实例?


当前回答

它非常简单,不需要编写太多代码 yourFragment.isAdded () 或 yourFragment.isVisible ();

我更喜欢isAdded(),它们都返回布尔值使用它在if条件,必须在onCreate()初始化你的片段,否则你会得到空点异常。

其他回答

这样比暴露在这里更安全

supportFragmentManager.fragments.lastOrNull()?.let { currentFragment ->
               
      //Do something here
 }
public Fragment getVisibleFragment() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    if(fragments != null) {
        for (Fragment fragment : fragments) {
            if (fragment != null && fragment.isVisible())
                return fragment;
        }
    }
    return null;
}

这对我很有用。在遍历片段列表之前,需要执行空检查。可能存在这样一种情况,即堆栈上没有加载任何片段。

返回的片段可以与您想放入堆栈中的片段进行比较。

下面是一个Kotlin解决方案:

if ( this.getSupportFragmentManager().getBackStackEntryCount()>0 ) {
    var fgmt = this.getSupportFragmentManager().fragments[this.getSupportFragmentManager().getBackStackEntryCount()-1]
    if( fgmt is FgmtClassName ) {
        (fgmt as FgmtClassName).doSth()
    }
}

简化的方法:

with ( this.getSupportFragmentManager() ) {
    if ( getBackStackEntryCount()>0 ) {
        var fgmt = fragments[getBackStackEntryCount()-1]
        if ( fgmt is FgmtClassName ) {
            (fgmt as FgmtClassName).doSth()
        }
    }
}

我发现findFragmentByTag不是那么方便。如果你在你的Activity或父Fragment中有字符串currentFragmentTag,你需要将它保存在onSaveInstanceState中并在onCreate中恢复。即使你这样做,当Activity重新创建时,onAttachFragment将在onCreate之前调用,所以你不能在onAttachFragment中使用currentFragmentTag(例如。更新一些基于currentFragmentTag的视图),因为它可能还没有恢复。

我使用以下代码:

Fragment getCurrentFragment() {
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if(fragments.isEmpty()) {
        return null;
    }
    return fragments.get(fragments.size()-1);
}

FragmentManager的文档中指出

列表中片段的顺序是它们被添加或附加的顺序。

当你需要做基于当前片段类型的事情时,只需使用MyFragment的getCurrentFragment()实例而不是currentFragmentTag.equals("my_fragment_tag")。

注意,onAttachFragment中的getCurrentFragment()不会得到附加的片段,而是之前附加的片段。

在androidx.fragment:fragment-ktx:1.4中,有一种新的方法可以让我们获得最近添加到容器中的片段。 如果你使用FragmentContainerView作为你的片段的容器,这将很容易:

val fragmentContainer: FragmentContainerView = ...
val currentFragment: Fragment = fragmentContainer.getFragment()