使用 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"/>
我正在尝试动态设置工具栏标题,我不知道是否可行。
假设我有项目列表,我单击它的每个项目都会打开新片段,因此我尝试动态更改每个项目的工具栏标题。
我试过了:
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 yourandroid: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"/>