Android JetPack架构-1-视图绑定viewBinding以及数据绑定dataBinding

2,217 阅读3分钟

developer.android.google.cn/topic/libra…

 添加组件
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"

使用视图绑定

优点:Null安全,类型安全

//1. 在项目build.gradle中添加
android {
        ...
        viewBinding {
            enabled = true
        }
    }
    
//2. 会自动生成ActivityMainBinding类,
private lateinit var binding: ActivityMainBinding

override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
	
	binding = ActivityMainBinding.inflate(layoutInflater)
	
	setContentView(binding.root)
}

//3. 绑定类的示例可以引用xml中任意视图
binding.tv1.text = "show text"

binding.btn1.setOnClickListener {
    binding.tv1.text = "show text end"
}

可以在布局中添加tools:viewBindingIgnore="true" 来忽略被绑定

Activity修饰符非public会导致出错:Caused by: java.lang.IllegalAccessException: is not accessible from java.lang.Class<android.app.AppComponentFactory>

dataBinding也要加进来才能使用, 加上后貌似不需要viewBinding了,官网上有句话「注意:即使应用模块不直接使用数据绑定,也必须为依赖于使用数据绑定的库的应用模块配置数据绑定。」这话说的非常过分,组件是你分的,我还不能选择性的使用。各模块间还是耦合的很深,就是不能单独只使用viewBinding了呗,不想用dataBinding还不行了

想要使用viewBinding要升级AS3.6以上,升上来还不能单独使用,,,,。用了dataBinding后,viewBinding默认也有,那单独搞viewBinding啥用的,,,,(难道使用kotlin可以单独使用,java就是被割了呗)

使用数据绑定

启用:在build.gradle中添加
android {
        ...
        dataBinding {
            enabled = true
        }
    }
将xml布局文件用layout作为根标记,并添加data标签

现在布局文件变为:

<?xml version="1.0" encoding="utf-8"?>
<layout>

    <data>
			// 定义可在当前布局中使用的实体类
        <variable
            name="user"
            type="cn.readsense.aac.User" />
    </data>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <TextView
            android:id="@+id/tv1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="@{user.name}" />//应用语法
    </LinearLayout>
</layout>
添加User实体类
public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}
Activity的onCreate方法中绑定数据
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

binding.setUser(new User("icount"));

binding.btn1.setText("点击");//viewBinding方式设置
binding.btn1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
		binding.tv1.setText("icount2");//viewBinding方式设置
        binding.setUser(new User("icount2"));//dataBinding方式设置
    }
});
绑定其他组件方式,Fragment或RecyclerView
    ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
    // or
    ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

使用可观察的数据对象

将一个对象的属性变化通知给其他对象,被称为可观察对象

修改User实体类:

public class User {
    private ObservableField<String> name = new ObservableField<>();

    public ObservableField<String> getName() {
        return name;
    }

    public void setName(ObservableField<String> name) {
        this.name = name;
    }
}

修改Activity中绑定使用, 可以看到,数据绑定后修改了可观察对象的属性值,对应的View也会相应的被修改

User icount = new User();

binding.setUser(icount);
icount.getName().set("icount");

binding.btn1.setText("点击");
binding.btn1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        icount.getName().set("icount2");
    }
});

前面是使用Observable接口包装属性实现可观察对象,可以直接集成BaseObservable来实现同样的效果,这样代码更加具有可读性。

// User类修改为:
public class User extends BaseObservable {
    
    private String name;
//get时添加Bindable注解
    @Bindable
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        notifyPropertyChanged(BR.name);//数值修改后将会通知观察者
    }
}
//Activity修改为
User icount = new User();
binding.setUser(icount);
icount.setName("dou");

binding.btn1.setText("点击");
binding.btn1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        icount.setName("icount2");
    }
});

够了够了,不要再学了