Установить заголовок панели инструментов динамически с помощью навигационного компонента
Я пытаюсь установить заголовок панели инструментов динамически, я не знаю, возможно ли это или нет.
Предположим, у меня есть список элементов, каждый элемент, по которому я щелкнул, это новый открытый фрагмент, поэтому я пытаюсь динамически изменять заголовок панели инструментов для каждого элемента.
Я старался:
it.findNavController().navigate(direction)
it.findNavController().currentDestination!!.label = someTitle
Но это не работает.
Есть несколько смежных тем, а именно:
Как установить заголовок на панели приложения с помощью компонента Navigation Architecture
Но это не решает мою проблему эффективно, это обходной путь.
1 ответ
Навигация поддерживает аргументы в метках начиная с версии 1.0.0-alpha08 или выше:
Метки назначения при использовании с методами NavigationUI теперь будут автоматически заменяться
{argName}
случаи в вашемandroid:label
с правильным аргументом 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)
Конечно, вы можете прослушивать навигационные события самостоятельно и использовать свои собственные 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()
был получен из android:name
в nav_graph.xml
.
<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
}
и удалите атрибут lable из тега в вашем nav_graph.xml, чтобы он был таким
<fragment
android:id="@+id/myFragment"
android:name=".MyFragment"/>