使用 navigation-component 动态设置工具栏标题

Set toolbar title dynamically using navigation-component

我正在尝试动态设置工具栏标题,我不知道是否可行。

假设我有项目列表,我单击它的每个项目都会打开新片段,因此我尝试动态更改每个项目的工具栏标题。

我试过了:

it.findNavController().navigate(direction)
it.findNavController().currentDestination!!.label = someTitle

但是没用。

有一些相关主题,即:

但它并没有有效地解决我的问题,这是一个work-around。

Navigation 1.0.0-alpha08 或更高版本起,导航支持标签中的参数:

Destination labels, when used with NavigationUI methods, will now automatically replace {argName} instances in your android:label with the correct argument b/80267266

因此您可以将标签设置为 android:label="{dynamicTitle}",然后将参数传递给 navigate 调用。当您使用 Safe Args 时,您需要向目标添加一个参数:

<fragment
    android:id="@+id/myFragment"
    android:name=".MyFragment"
    android:label="{dynamicTitle}">
  <argument
      android:name="dynamicTitle"
      app:argType="string"/>
</fragment>

然后在构建路线时传入您的动态标题:

val directions = YourDirections.actionToMyFragment(someTitle)
it.findNavController().navigate(directions)

当然,您可以 listen for navigation events 自己并使用自己的 OnDestinationChangedListener 做任何您想做的事情,包括将标签设置为您想要的任何内容。不需要使用 NavigationUI,调用 NavigationUI 方法后添加的任何侦听器都将覆盖它设置的任何内容。

如果您传递自定义 Object 作为参数,您可以使用 navController.addOnDestinationChangedListener.

navController.addOnDestinationChangedListener(new NavController.OnDestinationChangedListener() {
    @Override
    public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
        Log.i(TAG, "onDestinationChanged");
        switch (destination.getId()) {
            case R.id.mainFragment:
                updateToolbarAndBottomNavigation("Main Title", "Main Subtitle", View.VISIBLE);
                break;
            case R.id.shopFragment:
                updateToolbarAndBottomNavigation("custom title", null, View.VISIBLE);
                break;
            case R.id.shopcartFragment:
                StoreEntity store = (StoreEntity) arguments.get("storeEntity");
                Log.i(TAG, "onDestinationChanged: ShopCartFragment args: "+store.getName());
                updateToolbarAndBottomNavigation(store.getName(), null, View.GONE);
                break;
        }

    }
});

private void updateToolbarAndBottomNavigation(String title, String subtitle, int visibility) {
    getSupportActionBar().setTitle(title);
    getSupportActionBar().setSubtitle(subtitle);
    bottomNavigationView.setVisibility(visibility);
}

arguments.get() 是从 nav_graph.xml 中的 android:name 检索到的。

<fragment
        android:id="@+id/shopcartFragment"
        android:name="com.myapp.ShopcartFragment"
        tools:layout="@layout/fragment_shopcart" >
        <argument
            android:name="storeEntity" // GET ARGUMENTS NAME HERE
            app:argType="com.myapp.LocalDatabase.StoreEntity" />
    </fragment>

希望能帮到更多人!

您可以添加更新片段标题的方法,并在片段的 onStart() 方法中调用它

fun updateToolbarTitle(title: String) {
    supportActionBar?.title = title
}

并从 nav_graph.xml 中的标签中删除标签属性 所以它会像那样

<fragment
    android:id="@+id/myFragment"
    android:name=".MyFragment"/>