首页 > 解决方案 > 为什么 DataBinding 视图可见性不起作用

问题描述

我有以下 DataBinding 设置,但只要“isPrivate”为真,可见性就会保持 View.GONE

布局.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:binding="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

<androidx.constraintlayout.motion.widget.MotionLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/scene_1">

    ... 

    <ImageView
        android:id="@+id/iv_car_private"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:src="@drawable/ic_lock"
        binding:visibility="@{viewModel.car.isPrivate}" />

   ...

</androidx.constraintlayout.motion.widget.MotionLayout>

<data>

    <variable
        name="viewModel"
        type="com.app.MyViewModel" />
</data>

</layout>

活动

DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main).also { binding ->
    binding.lifecycleOwner = this
    binding.viewModel = myViewModel
}

绑定适配器

@BindingAdapter("visibility")
fun setVisibility(view: View, isVisible: Boolean) {
    Timber.d("+++ isPrivate: $isVisible")
    view.visibility = if (isVisible) View.VISIBLE else View.GONE
}

更新:

    @BindingAdapter("isPrivate")
    fun setIsPrivate(imageView: ImageView, isPrivate: Boolean) {
        if (isPrivate) {
            imageView.setImageResource(R.drawable.ic_lock)
        } else {
            imageView.setImageDrawable(null)
        }
    }

标签: androidvisibilityandroid-databindingandroid-architecture-components

解决方案


boolean使用三元运算符可以更简单地绑定值:

android:visibility="@{car.isPrivate ? View.GONE : View.VISIBLE}"

这就是我通常在Fragment(for fragment_main.xml)中膨胀它们的方式:

@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    this.mDataBinding = FragmentMainBinding.inflate(inflater, container, false);
    if (this.mDataBinding != null) {
        Car item = ...
        this.mDataBinding.setCar(item);
    }
}

数据绑定的真正美妙之处在于生成它,而不必编写它 - aBindingAdapter仅用于更复杂的操作,或者默认情况下不支持某些属性。


推荐阅读