首页 > 解决方案 > 如何通过 Kotlin 中的数据绑定设置 Android 复合视图的可见性?

问题描述

我检查了很多答案以找到我的问题,但是我没有成功。我有一个包含复合可绘制对象的活动。

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

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <com.my.profile.widgets.ProfileWidget
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    ....
    </LinearLayout>
</layout>

这是我的 ProfileWidget:

  class ProfileWidget @JvmOverloads constructor(context: Context,
                                                  attrs: AttributeSet? = null,
                                                  defStyleAttr: Int = 0
    ) : LinearLayout(context, attrs, defStyleAttr) {

        @Inject lateinit var viewModel: ProfileWidgetViewData
        @Inject lateinit var viewActions: ProfileWidgetActions

        private val binding: WidgetProfileBinding = DataBindingUtil.inflate(
                LayoutInflater.from(context), R.layout.widget_profile, this, true)
    //    private val binding = WidgetProfileBinding.inflate(LayoutInflater.from(context), this, true)

        override fun onAttachedToWindow() {
            super.onAttachedToWindow()
            setupDependencyInjection()
            setupDataBinding()

            viewActions.testUI()
        }

        private fun setupDependencyInjection() {
            (context as ProfileActivity).getProfileComponent()?.inject(this)
        }

        private fun setupDataBinding() {
            binding.viewModel = viewModel
        }
    }

这是它的布局:

 <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="viewModel"
                type="com.my.profile.widgets.ProfileWidgetViewData" />
        </data>

        <LinearLayout
            android:id="@+id/profilesContainer"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:background="#FF0000"
            >

            <TextView
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:text="profile 1"
                android:visibility="@{viewModel.textView_1.get() ? View.VISIBLE : View.INVISIBLE}"/>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:text="profile 2"
                android:visibility="@{viewModel.textView_2.get() ? View.VISIBLE : View.INVISIBLE}"/>

        </LinearLayout>

    </layout>

最后,我的 ViewModel 类应该使 TextViews 可见/不可见。

 interface ProfileWidgetViewData {
        val textView_1: ObservableBoolean
        val textView_2: ObservableBoolean
    }

    interface ProfileWidgetActions {
        fun testUI()
    }

    class ProfileWidgetViewModelImpl : ProfileWidgetViewData, ProfileWidgetActions {

        override val textView_1 = ObservableBoolean(false)
        override val textView_2 = ObservableBoolean(false)

        override fun testUI() {
            setProfilesContainerVisibility(true)
            setAddProfileContainerVisibility(true)
        }

        private fun setProfilesContainerVisibility(isVisible: Boolean) {
            textView_1.set(isVisible)
        }

        private fun setAddProfileContainerVisibility(isVisible: Boolean) {
            textView_2.set(isVisible)
        }
    }

不幸的是,我在上面的代码中没有看到任何错误。当我启动应用程序时,这两个 TextView 是不可见的,尽管我已将它们设置为可见。

标签: androidkotlinandroid-databinding

解决方案


在 build.gradle 中添加或未添加以下检查(显然您已经添加)

    apply plugin: 'kotlin-kapt'

    android {
        dataBinding {
            enabled = true
        }     
    }
    dependencies {
       kapt "com.android.databinding:compiler:3.1.3"
    }

并在您的 xml 文件中添加以下行以获得可见性或不可见性

 <TextView
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:text="profile 1"
        android:visibility="@{safeUnbox(viewModel.textView_1) ? View.VISIBLE : View.INVISIBLE}"/>

推荐阅读