簡體   English   中英

Kotlin 數據綁定共享視圖模型不更新兩個視圖

[英]Kotlin databinding shared viewmodel not updating both views

我正在嘗試將共享視圖模型用於活動和活動中顯示的片段,因為兩者都需要由視圖模型更新。 該片段使用 MutableLiveData 不斷更新,但活動不是,我真的不明白為什么。 出於可讀性原因,我確實刪除了與問題無關的 .xml 文件中的布局參數。 我的活動代碼如下所示:

class MainActivity : AppCompatActivity() {

     private lateinit var _binding : MainActivityBinding
     private val _viewModel : MySharedViewModel by viewModels()

     override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
         _binding = DataBindingUtil.setContentView(this, R.layout.main_activity)
         _binding.viewModel = _viewModel
         _binding.lifecycleOwner = this
         ...
     }
}

綁定的生命周期所有者已設置,但 MutableLiveData 似乎並未更新活動。 在活動布局文件中如下:

<layout>
<data>
    <variable
        name="viewModel"
        type="com.customApp.viewModels.MySharedViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout>

    <com.google.android.material.appbar.MaterialToolbar>
        <TextView
            android:id="@+id/totalTime"
            android:text="@{viewModel.topBarText}"
            .../>
    </com.google.android.material.appbar.MaterialToolbar>

    <com.google.android.material.bottomnavigation.BottomNavigationView
    .../>

    <androidx.fragment.app.FragmentContainerView
    .../>

</androidx.constraintlayout.widget.ConstraintLayout>

所以我有帶有始終顯示文本的文本視圖的頂部欄,作為標簽欄的底部導航視圖和包含片段的片段容器視圖。

片段代碼為:

class FirstFragment : Fragment() {
    private val _viewModel : MySharedViewModel by viewModels()
    private lateinit var _binding : FirstFragmentBinding

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        _binding = DataBindingUtil.inflate(inflater, R.layout.first_fragment, container, false)
        _binding.viewModel = _viewModel
        _binding.lifecycleOwner = viewLifecycleOwner
        return _binding.root
    }
}

同樣在這里為綁定設置了生命周期所有者,並且在片段布局中它綁定到了視圖模型:

<layout>
    <data>
        <variable
            name="viewModel"
            type="com.customApp.viewModels.MySharedViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout>
        <TextView
            ...
            android:text="@{viewModel.fragmentText}" />

        <Button
            android:id="@+id/startButton"
            android:onClick="@{() -> viewModel.startIteration()}"
            .../>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

在我的視圖模型中,我只需更新應顯示的文本:

class MySharedViewModel : ViewModel() {
    var topBarText : MutableLiveData<String> = MutableLiveData<String>("Hi")
    var fragmentText : MutableLiveData<String> = MutableLiveData<String>("There")

    private val stringsForTop = arrayOf("Hi","How", "You")
    private val stringsForFragment = arrayOf("There","Are", "?")
    private var index = 0

    fun startIteration() {
        kotlin.concurrent.fixedRateTimer(initialDelay = 1L, period = 1000L) {
            viewModelScope.launch(Dispatchers.Main) {
                topBarText.value = stringsForTop[index]
                fragmentText.value = stringsForFragment[index]
                index++
            }
        }
    }
}

現在,在更新片段文本時,頂部欄中的文本不會更新,並且始終只顯示“Hi”。 我有一種感覺,當片段初始化並且它的 viewLifecycleOwner 綁定到視圖 model 時,視圖 model 的生命周期觀察者活動被覆蓋。 我是否遺漏了某些東西,或者是否有另一種方法可以在視圖模型中向其生命周期所有者注冊活動和片段? 任何幫助表示贊賞。

如果您在 Fragment 中by viewmodels<>()使用,它將創建與Fragment生命周期耦合的ViewModel的新實例。 如果您希望ViewModel的實例與activityViewModels<>()使用的Activity相同,請在Fragment中嘗試以下代碼

private val _viewModel : MySharedViewModel by activityViewModels()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM