Android导航架构组件 - 获取当前可见片段

问题描述 投票:31回答:10

在尝试导航组件之前,我曾经手动执行片段事务并使用片段标记来获取当前片段。

val fragment:MyFragment = supportFragmentManager.findFragmentByTag(tag):MyFragment

现在在我的主要活动布局中,我有类似的东西:

<fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/nav_host"
        app:navGraph= "@navigation/nav_item"
        android:name="androidx.navigation.fragment.NavHostFragment"
        app:defaultNavHost= "true"
        />

如何通过导航组件检索当前显示的片段?干

supportFragmentManager.findFragmentById(R.id.nav_host)

返回一个NavHostFragment,我想要检索我显示的'MyFragment`。

谢谢。

android android-navigation android-jetpack
10个回答
32
投票

我设法找到了一种方法,现在如下:

NavHostFragment navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host);
navHostFragment.getChildFragmentManager().getFragments().get(0);

如果你知道它是第一个片段。我还在调查没有这个的方法。我同意这不是最好的方法,但这应该是现在的事情。


0
投票

我需要这样做来设置一个底部导航视图,我这样做:

val navController = Navigation.findNavController(requireActivity(), R.id.nav_tabs_home)
        val bottomNavBar: BottomNavigationView = nav_content_view
        NavigationUI.setupWithNavController(bottomNavBar, navController)

0
投票

首先,您通过id获取当前片段,然后您可以找到该片段,具体取决于该ID。

int id = navController.getCurrentDestination().getId();
Fragment fragment = getSupportFragmentManager().findFragmentById(id)l

-1
投票

要获取当前片段,可以调用getPrimaryNavigationFragment()方法

Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.nav_host)
    .getChildFragmentManager().getPrimaryNavigationFragment();

19
投票

我无法找到检索当前片段实例的方法。但是,您可以使用下面的代码获取最后添加的片段的ID。

navController.getCurrentDestination().getId()

它返回导航文件中的ID。希望这可以帮助。


12
投票

您应该查看nav片段的childFragmentManager primaryNavigationFragment属性,这是引用当前显示的片段的位置。

val navHost = supportFragmentManager.findFragmentById(R.id.main_nav_fragment)
    navHost?.let { navFragment ->
        navFragment.childFragmentManager.primaryNavigationFragment?.let {fragment->
                //DO YOUR STUFF
        }
    }
}

2
投票

找到工作方案。

private fun getCurrentFragment(): Fragment? {
    val currentNavHost = supportFragmentManager.findFragmentById(R.id.nav_host_id)
    val currentFragmentClassName = ((this as NavHost).navController.currentDestination as FragmentNavigator.Destination).className
    return currentNavHost?.childFragmentManager?.fragments?.filterNotNull()?.find {
        it.javaClass.name == currentFragmentClassName
    }
}

2
投票

这可能会迟到,但对于仍在寻找的人来说

val currentfraagment=NavHostFragment.findNavController(nav_host_fragment).currentDestination!!.id

然后你可以做类似的事情

if(currentfraagment == R.id.myFragemnt){
     //do something
}

注意,这是针对kotlin的,java代码应该差不多了


1
投票

你可以用getChildFragmentManager()来打电话

NavHostFragment fragment = supportFragmentManager.findFragmentById(R.id.nav_host);
MyFragment frag = (MyFragment) fragment.getChildFragmentManager().findFragmentByTag(tag);

1
投票

在有addOnDestinationChangedListener的活动中使用NavHostFragment

 NavController navController= Navigation.findNavController(MainActivity.this,R.id.your_nav_host);

        navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
            @Override
            public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
                Log.e(TAG, "onDestinationChanged: "+destination.getLabel());
            }
        });

0
投票

在您的活动中定义片段对象。并且从每个片段通过传递片段对象来调用此方法,因此静态片段对象将每次被当前显示片段覆盖。

//method in MainActivity
private static Fragment fragment;

public void setFragment(Fragment fragment){
this.fragment = fragment;
}

//And from your fragment class, you can call
((<yourActivity in which fragment present>)getActivity()).setFragment(<your fragment object>);

//if you want to set it directly;
 ((<yourActivity in which fragment present>)getActivity()).fragment=<your fragment object>;

您还可以设置从片段到活动的回调,以获得更好的方法并传递当前的片段对象。


0
投票

我把Andrei Toaders answerMukul Bhardwajs answerOnBackStackChangedListener结合起来。

作为属性:

private FooFragment fragment;

在我的onCreate

NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host);
FragmentManager navHostManager = Objects.requireNonNull(navHostFragment).getChildFragmentManager();
FragmentManager.OnBackStackChangedListener listener = () -> {
        List<Fragment> frags = navHostManager.getFragments();
        if(!frags.isEmpty()) {
            fragment = (FooFragment) frags.get(0);
        }
};
navController.addOnDestinationChangedListener((controller, destination, arguments) -> {
        if(destination.getId()==R.id.FooFragment){
            navHostManager.addOnBackStackChangedListener(listener);
        } else {
            navHostManager.removeOnBackStackChangedListener(listener);
           fragment = null;
        }
});

这样我就可以得到一个片段,稍后会显示。一个人甚至可以通过frags循环并用instanceof检查多个片段。

© www.soinside.com 2019 - 2024. All rights reserved.