我在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()

其他回答

你也可以很容易地在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;
}
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");
}

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

findFragmentByID(R.id.container);

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

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

findFragmentByTag()

如果getFragmentManager()不工作,然后尝试与getSupportFragmentManager(),并在加载片段时添加一个标签。

public void onBackPressed(){

    Fragment fragment=getSupportFragmentManager().findFragmentByTag(/*enter your tag*/);


    if(fragment!=null && fragment.isVisible())
    {
        //do your code here
    }
    else
    {
       //do your code here
    }

}

这是获得当前片段的简单方法。

getFragmentManager().addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
  @Override public void onBackStackChanged() {
    currentFragment = fragmentManager.findFragmentById(R.id.content);
    if (currentFragment !=  null && (currentFragment instanceof LoginScreenFragment)) {
      logout.setVisibility(View.GONE);
    } else {
      logout.setVisibility(View.VISIBLE);
    }
  }
});