天天看点

Android DataBinding 的简单使用,@BindingAdapter通过xml传入参数

导入

  • 同时开启dataBinding和viewBinding
android {
   ...
    buildFeatures {
        dataBinding = true
        // for view binding :
        viewBinding = true
    }
    ...
}
           
  • 或者
dataBinding {
        enabled = true
    }
           

转换成databinding布局

  • 在kotlin中xml布局的跟节点必须是layout(不能FrameLayout等),否则会生成ViewBinding类而不是ViewDataBinding类。可以使用Alt+Enter来快速转换成databinding的布局
Android DataBinding 的简单使用,@BindingAdapter通过xml传入参数

xml

<?xml version="1.0" encoding="utf-8"?>
<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>
        <variable
            name="user"
            type="com.zhangyu.myjetpack.bean.User" />
    </data>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".Main3Activity">

        <Button
            android:id="@+id/bt_test_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="onClick"
            android:text="@{user.name}" />

        <Button
            android:id="@+id/bt_test_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{String.valueOf(user.age)}" />

        <Button
            android:id="@+id/bt_test_3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@{user.sex}" />

        <com.zhangyu.myjetpack.view.BindingImageView
            android:id="@+id/iv_img"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            app:isCircle="@{true}"
            app:imgUrl="@{user.portrait}" />

    </LinearLayout>
</layout>
           

自定义BindingImageView

  • 通过BindingAdapter可以通过xml传递属性给自定义view
public class BindingImageView extends androidx.appcompat.widget.AppCompatImageView {
    public BindingImageView(@NonNull Context context) {
        super(context);
    }

    public BindingImageView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public BindingImageView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

	//requireAll如果有多个参数是否需要全部传入
    @BindingAdapter(value = {"imgUrl", "isCircle"},requireAll = false)
    public static void setImageUrl(BindingImageView view, String imgUrl, boolean isCircle) {
        if (isCircle){
            Glide.with(view).load(imgUrl).circleCrop().into(view);
        }else {
            Glide.with(view).load(imgUrl).into(view);
        }
    }
}
           

MainActivity

  • onClick 中给age加1,数据会自动更新到UI上
public class Main2Activity extends AppCompatActivity implements LifecycleOwner {

    private ActivityMain2Binding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main2);
        binding.setUser(new User("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png", "zy", 10, "男"));
    }

    public void onClick(View view) {
        int age = binding.getUser().getAge();
        binding.getUser().setAge(++age);
    }
}

           

Kotlin中需要注意

  • 自定义View中,需要有二级构造函数,让AttributeSet属性可以传入
class EditorBottomNavigation: LinearLayout {

    constructor(context: Context) : this(context, null, 0)

    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)

    constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
        context,
        attrs,
        defStyle
    )
}
           
  • 以下这种只有主构造函数是不能使用BindingAdapter的,因为没有AttributeSet可以设置
class ImageCropView(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) :
    AppCompatImageView(context, attrs, defStyleAttr) {

}

           

继续阅读