Android XML绑定MutableLiveData不起作用

3

我有一个包含CollapsingToolbarLayoutCoordinatorLayout活动。 我已将活动的标题绑定到CollapsingToolbarLayouttitle属性上,如下所示(由于布局太大,只发布相关代码部分):

<?xml version="1.0" encoding="utf-8"?>
<layout>
    <data>
        <variable name="viewModel"
                  type="com.android.myapp.ui.activity.home.HomeActivityViewModel"/>
    </data>
    <RelativeLayout 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:layout_width="match_parent"
                    android:layout_height="match_parent">

        <androidx.drawerlayout.widget.DrawerLayout
                android:id="@+id/drawerLayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:focusableInTouchMode="true">

            <androidx.coordinatorlayout.widget.CoordinatorLayout
                    android:id="@+id/main_content"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                <com.google.android.material.appbar.AppBarLayout
                        android:id="@+id/app_bar_layout"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        app:layout_behavior="com.android.myapp.ui.behavior.scroll.appbar.DisableableAppBarLayoutBehavior"
                        android:fitsSystemWindows="true">

                    <com.google.android.material.appbar.CollapsingToolbarLayout
                            android:id="@+id/appbar"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:fitsSystemWindows="true"
                            app:title="@{viewModel.pageTitle}"
                            app:collapsedTitleTextAppearance="@style/CollapsedAppBarTitleStyle"
                            app:contentScrim="?attr/colorPrimary"
                            app:expandedTitleGravity="bottom|center_horizontal"
                            app:expandedTitleMarginBottom="85dp"
                            app:expandedTitleTextAppearance="@style/ExpandedAppBarTitleStyle"
                            app:layout_scrollFlags="scroll|exitUntilCollapsed">
        <!--Remaining layout-->
</layout>

你可以看到,pageTitle属性绑定到xml中的CollapsingToolbarLayout title属性。

现在在HomeActivityViewModel中:

class HomeActivityViewModel(application: Application) : AndroidViewModel(application) {
    var isToolbarExpandable = MutableLiveData<Boolean>() // For handling the expansion of toolbar on navigation. This works perfectly
    var pageTitle = MutableLiveData<String>()

    init {
        isToolbarExpandable.value = true
        pageTitle.value = "Home"
    }
}

HomeActivity中:

class HomeActivity : AppCompatActivity() {
    private lateinit var homeViewModel: HomeActivityViewModel
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivitySafaricomHomeBinding>(this, R.layout.activity_safaricom_home)
        binding.lifecycleOwner = this
        setSupportActionBar(toolbar)
        homeViewModel = getHomeViewModel()
        binding.viewModel = homeViewModel
    }

    private fun getHomeViewModel(): HomeActivityViewModel = ViewModelProviders.of(this).get(HomeActivityViewModel::class.java)
}

这种情况下页面标题已正确设置。但当我尝试在创建活动和第一个子片段之后的任何时间设置标题时,问题就开始了(我正在使用NavHostFragment,因此第一个片段将在创建活动后立即创建并附加)。我唯一能够更改标题的地方是活动的onCreate和起始片段的onCreate生命周期方法。我使用viewmodel作为共享viewmodel来从所有子片段更改标题。我在片段中通过以下方式获取ViewModel:

ViewModelProviders.of(activity!!).get(HomeActivityViewModel::class.java)

之后,每当我尝试更改标题时,它就不会改变。无论是在按下按钮、延迟后、在下一个碎片中,都没有作用。唯一有效的地方是在活动的onCreate直到第一个片段的onCreateView中。我在HomeActivity中为pageTitle添加了一个观察者,但在第一次更改后,甚至观察者也没有被触发。在调试时,我可以看到它是检索到相同的viewmodel实例,并且实际上pageTitle正在被更改,但它在创建后就停止观察。这里有什么问题吗?请帮忙解决。


你尝试过调试生成的代码,在其中使用 CollapsingToolbarLayout#setTitle(CharSequence title) 吗? - pskink
@pskink,我现在检查了一下,发现第二次也没有调用@Override protected void executeBindings() - Harikrishnan
为什么没有被调用? - pskink
就像我之前提到的一样,我在Activity中添加的Observer在创建后也没有被调用。因此,我认为一切都停止了对pageTitle可变的live data的观察。但我不知道为什么会这样。 - Harikrishnan
1个回答

12

LiveData 由于没有生命周期,无法与 DataBinding 一起使用。

之后

binding.viewModel = homeViewModel

尝试添加

binding.lifecycleOwner = this

所以,总的来说

binding.viewModel = homeViewModel
binding.lifecycleOwner = this

我昨天也尝试过这个,但没有成功。我会更新问题。 - Harikrishnan
你能否分享一个关于这个问题的示例项目? - theapache64
1
如果您不设置生命周期所有者,则只会得到如描述的一个状态更改。这是正确答案。 - Rob Gorman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接