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


当前回答

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

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”或使用对您的活动的引用。

其他回答

In the main activity, the onAttachFragment(Fragment fragment) method is called when a new fragment is attached to the activity. In this method, you can get the instance of the current fragment. However, the onAttachFragment(Fragment fragment) method is not called when a fragment is popped off the back stack, ie, when the back button is pressed to get the top fragment on top of the stack. I am still looking for a callback method that is triggered in the main activity when a fragment becomes visible inside the activity.

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

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

Sev的答案适用于当你按下后退按钮或以其他方式更改后退堆栈时。

不过,我做了一些略有不同的事情。我有一个backstack更改监听器设置在一个基本片段和它的派生片段,这段代码是在监听器:

Fragment f = getActivity().getSupportFragmentManager().findFragmentById(R.id.container);

if (f.getClass().equals(getClass())) {
    // On back button, or popBackStack(),
    // the fragment that's becoming visible executes here,
    // but not the one being popped, or others on the back stack

    // So, for my case, I can change action bar bg color per fragment
}

每次当你显示fragment时,你必须把它标签放入backstack:

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setTransition(FragmentTransaction.TRANSIT_ENTER_MASK);       
ft.add(R.id.primaryLayout, fragment, tag);
ft.addToBackStack(tag);
ft.commit();        

然后当你需要获取当前片段时,你可以使用这个方法:

public BaseFragment getActiveFragment() {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0) {
        return null;
    }
    String tag = getSupportFragmentManager().getBackStackEntryAt(getSupportFragmentManager().getBackStackEntryCount() - 1).getName();
    return (BaseFragment) getSupportFragmentManager().findFragmentByTag(tag);
}

以下是我的解决方案,我发现它适用于低片段场景

public Fragment getVisibleFragment(){
    FragmentManager fragmentManager = MainActivity.this.getSupportFragmentManager();
    List<Fragment> fragments = fragmentManager.getFragments();
    if(fragments != null){
        for(Fragment fragment : fragments){
            if(fragment != null && fragment.isVisible())
                return fragment;
        }
    }
    return null;
}