Динамический заголовок ActionBar из фрагмента с помощью AndroidX Navigation - PullRequest
0 голосов
/ 30 мая 2018

Я использую новый Навигационный компонент от Android Jetpack.

Корневая настройка активности довольно проста:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(toolbar)

    val navController = findNavController(R.id.navigationFragment)
    setupActionBarWithNavController(navController)

    bottomNavigationView.setupWithNavController(navController)
}

Хорошо работает, когда заголовок фрагментаопределяется в графике навигации.Но для одного фрагмента я хочу установить заголовок динамически.

Я пытался с findNavController().currentDestination.label = "Hello world", но он ничего не делает.

Я, конечно, мог бы использовать трюк, такой как (activity as? AppCompatActivity)?.supportActionBar?.title = "Hello world", но ячувствую, что это сломает магию, которую setupActionBarWithNavController() делает для меня.Есть ли способ динамически обновить заголовок панели действий?

Ответы [ 9 ]

0 голосов
/ 03 февраля 2019

Начиная с 1.0.0-alpha08, биты NavigationUI могут динамически устанавливать заголовок ... если динамические биты являются аргументами для действия навигации.

Так, например, в вашем графике навигации выможет иметь что-то вроде этого:

  <fragment
    android:id="@+id/displayFragment"
    android:name="com.commonsware.jetpack.sampler.nav.DisplayFragment"
    android:label="Title: {title}" >
    <argument
      android:name="modelId"
      app:argType="string" />
    <argument
      android:name="title"
      app:argType="string" />
  </fragment>

Здесь атрибут android:label для нашего <fragment> имеет имя аргумента, заключенное в фигурные скобки ({title} в "Title: {title}". Тогда заголовок панели приложения будетустановите значение метки, заменив {title} значением аргумента title.

Если вам нужно что-то более сложное, например, вы хотите посмотреть модель по IDи прочитайте свойство из него - вам нужно будет использовать больше ручных подходов, например, описанных в других ответах на этот вопрос.

0 голосов
/ 04 февраля 2019

Ну, теперь интерфейс навигации поддерживает эту функцию.Теперь заголовок ActionBar меняется динамически.Вам просто нужно настроить ActionBar с помощью NavController.

private lateinit var appBarConfiguration: AppBarConfiguration

private lateinit var navController: NavController

override fun onCreate(savedInstanceState: Bundle?) {
    preferedTheme()
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    setSupportActionBar(toolbar)
    navController = findNavController(R.id.nav_controller_fragment)
    appBarConfiguration = AppBarConfiguration(navController.graph)
    setupActionBarWithNavController(navController, appBarConfiguration)
}

и установить метку панели действий на графике навигации:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/mobile_navigation"
        app:startDestination="@id/mainFragment">

<fragment android:id="@+id/mainFragment"
          android:name="com.cinderellaman.general.ui.fragments.MainFragment"
          android:label="General"
          tools:layout="@layout/main_fragment"/>

А теперьего также поддерживает навигацию вверх:

override fun onSupportNavigateUp(): Boolean {
    return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
}
0 голосов
/ 18 декабря 2018

Удалить метку из файла graph.xml

android:label="fragment_info"

и использовать подход старой школы, если вы хотите динамически установить заголовок фрагмента из самого фрагмента

getActivity().setTitle("Your Title");
0 голосов
/ 17 января 2019

При попытке использовать заголовок действия, похоже, он переопределяет заголовок фрагмента.Находясь в безопасности, вы должны надеть onResume.

override fun onResume() {
    super.onResume()
    activity?.toolbar.title = "YOUR_TITLE_HERE"
}

, это работает для меня!

Примечание: Должен иметь виджет панели инструментов в действии

Добавьте такую ​​панель инструментов в xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

    </com.google.android.material.appbar.AppBarLayout>

    <!-- Other Widgets -->

</androidx.coordinatorlayout.widget.CoordinatorLayout>
своей деятельности
0 голосов
/ 13 декабря 2018

Учитывая, что ваша активность на хосте MainActivity, просто добавьте следующий код в onCreate fun

val navController = Navigation.findNavController(this, R.id.nav_host_fragment)

// setting title according to fragment
navController.addOnDestinationChangedListener { 
    controller, destination, arguments ->
        toolbar.title = navController.currentDestination?.label
}
:
0 голосов
/ 12 июля 2018

Пока проблема не будет исправлена, простой слушатель работает со мной:

/**
 * Temporary solution to dynamically change title of actionbar controlled by Navigation component
 * Should be removed as soon as the bug on Navigation will be fixed: (https://issuetracker.google.com/issues/80267266)
 */
interface TempToolbarTitleListener {
    fun updateTitle(title: String)
}

class MainActivity : AppCompatActivity(), TempToolbarTitleListener {

    ...

    override fun updateTitle(title: String) {
        binding.toolbar.title = title
    }
}

изменить заголовок с фрагмента:

(activity as TempToolbarTitleListener).updateTitle("custom title")
0 голосов
/ 18 июня 2018

На данный момент компоненты Jetpack Navigation Architecture не предоставляют никакого «встроенного» способа сделать это, и вам придется реализовать свой собственный «пользовательский» метод для этого.

Существует существующий запрос функции для получения функциональности для динамических меток в адресатах, добавленных в новые компоненты архитектуры навигации Jetpack.Если вы находитесь здесь, потому что вы хотите / нуждаетесь в этой функции, отметьте существующий запрос функции здесь: https://issuetracker.google.com/issues/80267266

0 голосов
/ 07 июня 2018

Другое решение состоит в том, чтобы использовать ViewModel и LiveData, прикрепить viewmodel к вашей активности и фрагментам, добавить поле liveata внутри viewmodel

val title = MutableLiveData<String>()

Из вашей активности наблюдайте это поле, и если оно изменилось, обновите панель инструментовtitle

viewModel?.title?.observe(this, Observer { 
        my_toolbar.title=it
    })

Из нужного фрагмента измените поле заголовка внутри модели представления

viewModel?.title?.value="New title"
0 голосов
/ 30 мая 2018

Вы можете добавить addOnNavigatedListener внутри своей деятельности, и в зависимости от текущего назначения измените заголовок

 findNavController(nav_host_fragment).addOnNavigatedListener { controller, destination ->
        when(destination.id) {
            R.id.destination1 -> {
                my_toolbar.title= "Some title"
            }
            R.id.destination2 -> {
                my_toolbar.title= "Othertitle"

            }

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...