不可观察的数据对象
数据改变了,界面没有更新最新的数据
xml布局
<data>
<variable
name="people"
type="com.example.hellojetpack.databinding.PeopleBean" />
</data>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{people.name +`:`+String.valueOf(people.age)}"
/>
数据对象
class PeopleBean {
var name:String = ""
var age:Int = 0
}
Activity
val people = PeopleBean()
lateinit var binding: ActivityObservableBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_observable)
people.apply {
name = "sunhao"
age = 29
}
binding = DataBindingUtil.setContentView<ActivityObservableBinding>(
this,
R.layout.activity_observable
)
binding.people = people
}
/**
* 观察特定的变量
*/
fun modifyVar(view: View) {
people.apply {
name = "chenmm"
age = 26
}
println("${people.name} : ${people.age}")
}
打印结果
I/System.out: chenmm : 26
数据变了并没有驱动UI进行更新,怎么解决数据更新可以带动UI更新?
采用可观察的数据对象
可观察的数据对象
可观察性是指一个对象将其数据变化告知其他对象的能力。通过数据绑定库,您可以让对象、字段或集合变为可观察。
当其中一个可观察数据对象绑定到界面并且该数据对象的属性发生更改时,界面会自动更新。
可观察字段
在创建实现 Observable 接口的类时要完成一些操作,但如果您的类只有少数几个属性,这样操作的意义不大。在这种情况下,您可以使用通用 Observable 类和以下特定于基元的类,将字段设为可观察字段:
- ObservableBoolean
- ObservableByte
- ObservableChar
- ObservableShort
- ObservableInt
- ObservableLong
- ObservableFloat
- ObservableDouble
- ObservableParcelable
原语版本避免在访问操作期间封箱和开箱。如需使用此机制,请采用 Java 编程语言创建 public final 属性,或在 Kotlin 中创建只读属性,如以下示例所示:
class PeopleBean {
val name = ObservableField<String>()
val age = ObservableInt()
}
fun modifyVar(view: View) {
people.apply {
name.set("chenmm")
age.set(26)
}
println("${people.name.get()} : ${people.age.get()}")
}
结果 UI数据更新
可观察集合
dataBinding 也提供了包装类用于替代原生的 List 和 Map,分别是 ObservableList 和 ObservableMap,当其包含的数据发生变化时,绑定的视图也会随之进行刷新
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.databinding.ObservableList"/>
<import type="android.databinding.ObservableMap"/>
<variable
name="list"
type="ObservableList<String>"/>
<variable
name="map"
type="ObservableMap<String,String>"/>
<variable
name="index"
type="int"/>
<variable
name="key"
type="String"/>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.leavesc.databinding_demo.Main12Activity">
<TextView
···
android:padding="20dp"
android:text="@{list[index],default=xx}"/>
<TextView
···
android:layout_marginTop="20dp"
android:padding="20dp"
android:text="@{map[key],default=yy}"/>
<Button
···
android:onClick="onClick"
android:text="改变数据"/>
</LinearLayout>
</layout>
private ObservableMap<String, String> map;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMain12Binding activityMain12Binding = DataBindingUtil.setContentView(this, R.layout.activity_main12);
map = new ObservableArrayMap<>();
map.put("name", "leavesC");
map.put("age", "24");
activityMain12Binding.setMap(map);
ObservableList<String> list = new ObservableArrayList<>();
list.add("Ye");
list.add("leavesC");
activityMain12Binding.setList(list);
activityMain12Binding.setIndex(0);
activityMain12Binding.setKey("name");
}
public void onClick(View view) {
map.put("name", "leavesC,hi" + new Random().nextInt(100));
}

可观察整个对象
实现 Observable 接口的类允许注册监听器,以便它们接收有关可观察对象的属性更改的通知。
Observable 接口具有添加和移除监听器的机制,但何时发送通知必须由您决定。为便于开发,数据绑定库提供了用于实现监听器注册机制的 BaseObservable 类。
- 实现 BaseObservable 的数据类负责在属性更改时发出通知。
- 具体操作过程是向 getter 分配 Bindable 注释,然后在 setter 中调用 notifyPropertyChanged() 方法
class User : BaseObservable() {
@get:Bindable
var firstName: String = ""
set(value) {
field = value
//注意参数
notifyPropertyChanged(BR.firstName)
}
@get:Bindable
var lastName: String = ""
set(value) {
field = value
notifyPropertyChanged(BR.lastName)
}
}
notifychange() 更新全部字段
var finalPrice:Float = 0.0f
@Bindable
get() {
return field
}
set(value) {
field = value
notifyPropertyChanged(BR.finalPrice)
}
var offPrice:Float = 0f
@Bindable
get() = field
set(value) {
field = value
//更新其他所有字段(不包括 添加Bindable的字段)
notifyChange()
}
var buyCount:Long = 0
双向绑定
双向绑定的意思即为当数据改变时同时使视图刷新,而视图改变时也可以同时改变数据
看以下例子,当 EditText 的输入内容改变时,会同时同步到变量 goods,绑定变量的方式比单向绑定多了一个等号:android:text="@={goods.name}"
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="com.leavesc.databinding_demo.model.ObservableGoods"/>
<variable
name="goods"
type="ObservableGoods" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".Main10Activity">
<TextView
···
android:text="@{goods.name}" />
<EditText
···
android:text="@={goods.name}" />
</LinearLayout>
</layout>
public class Main10Activity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMain10Binding activityMain10Binding = DataBindingUtil.setContentView(this, R.layout.activity_main10);
ObservableGoods goods = new ObservableGoods("code", "hi", 23);
activityMain10Binding.setGoods(goods);
}
}

网友评论