我在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文件中,如何获得当前显示的片段实例?


当前回答

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

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

其他回答

受泰尼回答的启发,以下是我的观点。与大多数其他实现相比几乎没有修改。

private Fragment getCurrentFragment() {
    FragmentManager fragmentManager = myActivity.getSupportFragmentManager();
    int stackCount = fragmentManager.getBackStackEntryCount();
    if( fragmentManager.getFragments() != null ) return fragmentManager.getFragments().get( stackCount > 0 ? stackCount-1 : stackCount );
    else return null;
}

如果“myActivity”是您当前的活动,则将“myActivity”替换为“this”或使用对您的活动的引用。

你好,我知道这是一个非常老的问题,但我想分享我自己的解决方案。

为了获得用户浏览的片段列表,我创建了一个helper类:

public class MyHelperClass{

    private static ArrayList<Fragment> listFragment = new ArrayList<>();

    public static void addFragment(Fragment f){
        if(!existFragment(f)) {
            listFragment.add(f);
        }
    }
    public static void removeFragment(){
        if(listFragment.size()>0)
            listFragment.remove(listFragment.size()-1);
    }
    public static Fragment getCurrentFragment(){
        return listFragment.get(listFragment.size()-1);
    }
    public static int sizeFragments(){
        return listFragment.size();
    }
    private static Boolean existFragment(Fragment f){
        Boolean ret = false;
        for(Fragment fragment : listFragment){
            if (fragment.getClass() == f.getClass()){
                ret = true;
            }
        }
        return ret;
    }

进入主活动,我重写onAttachFragment方法

@Override
public void onAttachFragment(Fragment f) {
    super.onAttachFragment(f);

    MyHelperClass.addFragment(f);
}

并且,我重写onBackPressed方法:

@Override
public void onBackPressed() {
        General.removeFragment();
        if(General.sizeFragments()>0){
            Fragment fragment = null;
            Class fragmentClass = General.getCurrentFragment().getClass();

            try {
                fragment = (Fragment) fragmentClass.newInstance();
                fragment.setArguments(General.getCurrentFragment().getArguments());
            } catch (Exception e) {
                e.printStackTrace();
            }

            fragmentManager.beginTransaction().replace(R.id.flContent, fragment).commit();
        }else{
            super.onBackPressed();
        }
}

所以通过这种方式,你可以在任何时候通过MyHelperClass.getCurrentFragment()获得活动片段

我希望这对任何人都有帮助

问候

如果你从父活动中获得Fragment的当前实例,你可以

findFragmentByID(R.id.container);

这实际上是视图中填充的fragment的当前实例。我也有同样的问题。我不得不加载相同的片段两次,保持一个备份。

下面的方法不起作用。它只是得到一个带有标签的片段。不要在这个方法上浪费时间。我相信它有它的用途,但获得同一片段的最新版本不是其中之一。

findFragmentByTag()

以上30个答案都不适合我。但这是一个有效的答案:

使用Kotlin,当使用导航组件时:

fun currentVisibleFragment(): Fragment? {
    return supportFragmentManager.fragments.first()?.getChildFragmentManager()?.getFragments()?.get(0)
}

我发现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()不会得到附加的片段,而是之前附加的片段。