Привязка данных ведет себя неожиданно между фрагментами и активностью - PullRequest
1 голос
/ 13 апреля 2020

Поэтому я пытаюсь выяснить, почему я не могу переопределить свойство с привязкой к данным mainActivity.toolbarViewConfig.title.value = "help me please". Кажется, что свойство установлено только один раз, и это будет работать в моей деятельности или во фрагменте A. Если я попытаюсь присвоить свойству значение во фрагменте B, это не сработает. Если я попытаюсь переопределить свойство, установив прослушиватель для кнопки в действии, это не будет работать. Так что, очевидно, что-то странное происходит с привязкой. Все виды предложений будут оценены. Я сидел, царапая мою голову 4 дня подряд. Пожалуйста, помогите мне не стать лысым.

Активность:

override fun onCreate(savedInstanceState: Bundle?) {
    requestWindowFeature(Window.FEATURE_NO_TITLE)
    super.onCreate(savedInstanceState)


    val binding = ActivityMainBinding.inflate(layoutInflater)
    binding.toolbarViewConfig = toolbarViewConfig
    setContentView(binding.root)


    window.setFlags(
        WindowManager.LayoutParams.FLAG_FULLSCREEN,
        WindowManager.LayoutParams.FLAG_FULLSCREEN)

    val navController = findNavController(R.id.nav_host_fragment)
    val appBarConfiguration = AppBarConfiguration(navController.graph)
    findViewById<androidx.appcompat.widget.Toolbar>(R.id.toolbar).setupWithNavController(navController,appBarConfiguration)}

Фрагмент A:

override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {

    val mainActivity = activity!! as MainActivity
    mainActivity.toolbarViewConfig.title.value = "This works!" //Works fine. 

    return inflater.inflate(R.layout.fragment_home, container, false)
}

Фрагмент B:

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View?
{
    val viewModel = ViewModelProvider(this).get(GoOnlineViewModel::class.java)

    val binding = DataBindingUtil.inflate<FragmentSellerGoOnlineBinding>(
        inflater, R.layout.fragment_seller_go_online,
        container, false
    ).apply {
        this.lifecycleOwner = viewLifecycleOwner
        this.viewModel = viewModel}

    val mainActivity = activity!! as MainActivity
    mainActivity.toolbarViewConfig.title.value = "This does not work" //When I navigate from Fragment A to B this will not be set

    viewModel.navigationCommand.observe(viewLifecycleOwner, Observer {
        when(it) {
            is NavigationCommand.To ->
                Navigation.findNavController(requireView()).navigate(it.directions)
        }
    })


    return binding.root
}

ToolbarViewConfig:

class ToolbarViewConfig(
var title: MutableLiveData<String> = MutableLiveData(""))

Activity_main. xml:

<layout 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">

<data>
    <import type="android.view.View"/>

    <variable
        name="toolbarViewConfig"
        type="my.app.willow.models.ToolbarViewConfig" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/constraintLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:background="@color/white"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{toolbarViewConfig.title}"
            android:layout_gravity="center"
            android:id="@+id/toolbar_title"/>

    </androidx.appcompat.widget.Toolbar>

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/toolbar"
        app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>

1 Ответ

1 голос
/ 13 апреля 2020

Вы забыли назначить lifecycleOwner в вашем ActivityMainBinding. Без этого ваш Activity никогда не будет прослушивать изменения и просто прочтет текущее значение один раз.

Я считаю, что FragmentA создает свой вид и устанавливает заголовок во время ActivityMainBinding.inflate(layoutInflater). Таким образом, в следующей строке, когда вы устанавливаете toolbarViewConfig в вашем ActivityMainBinding, он уже может прочитать начальное значение заголовка LiveData (установленное FragmentA), но никогда не будет реагировать на любые последующие изменения, сделанные в FragmentB.

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