导入
- 同时开启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) {
}