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


当前回答

当您在事务中添加片段时,您应该使用标记。

fragTrans.replace(android.R.id.content, myFragment, "MY_FRAGMENT");

...稍后,如果你想检查片段是否可见:

MyFragment myFragment = (MyFragment)getSupportFragmentManager().findFragmentByTag("MY_FRAGMENT");
if (myFragment != null && myFragment.isVisible()) {
   // add your code here
}

参见http://developer.android.com/reference/android/app/Fragment.html

其他回答

您可以使用以下代码获取当前片段

FragmentClass f = (FragmentClass)viewPager.getAdapter().instantiateItem(viewPager, viewPager.getCurrentItem());

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

我最近不得不这样做,这里没有一个答案真正适合这种情况。

如果你确信只有一个片段是可见的(全屏),那么真的要找到backstack顶部的内容。例如,作为Fragment的Kotlin:

import androidx.fragment.app.Fragment

fun Fragment.setVisibilityChangeListener(clazz: Class<out Fragment>, listener: (Boolean) -> Unit) {
    fragmentManager?.run {
        addOnBackStackChangedListener {
            val topFragmentTag = getBackStackEntryAt(backStackEntryCount - 1).name
            val topFragment = findFragmentByTag(topFragmentTag)
            listener(topFragment != null && topFragment::class.java == clazz)
        }
    }
}

像这样使用它:

class MyFragment: Fragment {
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        setVisibilityChangeListener(this::class.java) { visible -> 
            // Do stuff
        }
    }
}

签出此解决方案。我成功拿到了现在的碎片。

if(getSupportFragmentManager().getBackStackEntryCount() > 0){
        android.support.v4.app.Fragment f = 
         getSupportFragmentManager().findFragmentById(R.id.fragment_container);
        if(f instanceof ProfileFragment){
            Log.d(TAG, "Profile Fragment");
        }else if(f instanceof SavedLocationsFragment){
            Log.d(TAG, "SavedLocations Fragment");
        }else if(f instanceof AddLocationFragment){
            Log.d(TAG, "Add Locations Fragment");
        }

我知道这是一个老帖子,但之前也遇到了麻烦。找到了一个解决方案,这是在onBackStackChanged()监听函数

  @Override
    public void onBackPressed() {
        super.onBackPressed();

         Fragment f = getActivity().getFragmentManager().findFragmentById(R.id.fragment_container);
      if(f instanceof CustomFragmentClass) 
        // do something with f
        ((CustomFragmentClass) f).doSomething();

    }

这对我来说很有效,因为我不想遍历每个片段,我必须找到一个可见的片段。