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


当前回答

final FragmentManager fm=this.getSupportFragmentManager();
final Fragment fragment=fm.findFragmentByTag("MY_FRAGMENT");

if(fragment != null && fragment.isVisible()){
      Log.i("TAG","my fragment is visible");
}
else{
      Log.i("TAG","my fragment is not visible");
}

其他回答

我的方法是基于try / catch,如下所示:

MyFragment viewer = null;
    if(getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT) instanceOf MyFragment){
    viewer = (MyFragment) getFragmentManager().findFragmentByTag(MY_TAG_FRAGMENT);
}

但也许有更好的办法……

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

为了获得用户浏览的片段列表,我创建了一个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()获得活动片段

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

问候

反应式方式:

Observable.from(getSupportFragmentManager().getFragments())
    .filter(fragment -> fragment.isVisible())
    .subscribe(fragment1 -> {
        // Do something with it
    }, throwable1 -> {
        // 
    });

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

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

你也可以很容易地在logcat中使用URL,它将重定向到当前片段源代码的源代码。首先,你需要在主机活动中添加一个OnBackStackChangedListener,比如-

activity.getChildFragmentManager().addOnBackStackChangedListener(backStackListener);

OnBackStackChangedListener的实现是-

    public FragmentManager.OnBackStackChangedListener backStackListener = () -> {

    String simpleName = "";
    String stackName = getStackTopName().trim();

    if (Validator.isValid(stackName) && stackName.length() > 0) {

      simpleName = stackName.substring(Objects.requireNonNull(stackName).lastIndexOf('.') + 1).trim();

      List<Fragment >
       fragmentList = getChildFragmentManager().getFragments();
      Fragment myCurrentFragment;

      for (int i = 0; i < fragmentList.size(); i++) {
       myCurrentFragment= fragmentList.get(i);
       if (myCurrentFragment.getClass().getSimpleName().equals(simpleName)) {
        //Now you get the current displaying fragment assigned in myCurrentFragment.
        break;
       }
       myFragment = null;
      }
     }


     //The code below is for the source code redirectable logcat which would be optional for you.
     StackTraceElement stackTraceElement = new StackTraceElement(simpleName, "", simpleName + ".java", 50);
     String fileName = stackTraceElement.getFileName();
     if (fileName == null) fileName = "";
     final String info = "Current Fragment is:" + "(" + fileName + ":" +
     stackTraceElement.getLineNumber() + ")";
     Log.d("now", info + "\n\n");
    };

getStackTopName()方法是-

public String getStackTopName() {
    FragmentManager.BackStackEntry backEntry = null;
    FragmentManager fragmentManager = getChildFragmentManager();
    if (fragmentManager != null) {
        if (getChildFragmentManager().getBackStackEntryCount() > 0)
            backEntry = getChildFragmentManager().getBackStackEntryAt(
                    getChildFragmentManager().getBackStackEntryCount() - 1
            );
    }
    return backEntry != null ? backEntry.getName() : null;
}