Android DataBinding 数据绑定
Android DataBinding
Databinding作为支持MVVM模式的一种数据绑定框架,类似ButterKnife取代findViewById,它可以直接在 layout 布局 xml 文件中绑定数据,接下来就从三个方面进行分析并写一个监视View层的数据变化来理解DataBinding框架。
- 什么是DataBinding 数据绑定 (what)
- 为什么要用DataBinding (why)
- 怎么去用DataBinding (how)
what
谷歌Android 团队发布了一个数据绑定框架(Data Binding Library),官方原生支持 MVVM 模型,取代findViewById直接在 layout 布局 xml 文件中绑定数据,自动建立layout文件的java对象。对于MVVM模型中直接在ViewModel层中与View层进行数据绑定,为开发者提供一个结构清晰、方便分工合作、代码解耦,正是由于它会自动建立layout文件的java对象,所以它在项目中会比较沉重,但是整体利大于弊,是很不错的框架。
why
说它的几个优点就可以感受到它的强大
- 完全能替代findViewById,会自动建立layout文件的java对象
- 完全代替R.id.xx,解决复杂layout布局中找不到id的的问题
- 只需要在ViewModel层中进行数据操作,View层就可以自动更新UI
- 支持对一个或多个数据进行监听,更好的完成UI逻辑
- 分层清晰,UI层和逻辑层解耦度大,后期维护性强
它还有一些优点就不一一赘述,就这些就够我们先用的,接下来我们通过一个View层监视数据变化来了解使用它。
how
Step 1
Gradle中进行配置
android {
...
dataBinding{
enabled=true;
}
}
Step 2
定义一个实体类
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Step 3
在xml里通过–layout–、–data–进行实体数据的绑定,例如将User进行数据的绑定,用户可随意设定“user”,需要在View层控件中声明:android:text=”@{user.name]”。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!--dataBinding-->
<data>
<variable name="user" type="com.xxx.databinding.myapplication.User"/>
</data>
<!--View-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:text="@{user.name}"
android:textSize="24sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
写到这里时将项目Build一下,这时就会自动在build/intermediates/classes/debug/com/xxx/databinding下生成ActivityMainBinding.class文件,就这样就绑定成功了。
例如
activity_main => ActivityMainBinding
fragment_main =>FragmentMainBinding
MainActivity.java
在MainActivity中进行绑定,并设置一个用户,通过setUser()进行View层交互。
(activity 场合)
public class MainActivity extends AppCompatActivity {
private User mUser;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUser=new User("Java");
binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.setUser(mUser);
}
}
(fragment场合)
public class MainFragment extends Fragment {
private FragmentMainBinding binding;
private User mUser;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding= DataBindingUtil.inflate(inflater,R.layout.fragment_main,container,false);
mUser=new User("Java");
return binding.getRoot();
}
}
这就是在不同场合使用Databinding的情况。列子中先定义一个死数据“Java”进行代码演示。此时程序运行View层显示“java”。
Step 4
添加一个功能来通过点击按钮来改变View层的数据变化,定义事件处理程序。onChangeClick的参数应该与View.OnClickListener中的onClick的参数相同。
public interface ChangeViewHandlers {
void onChangeClick(View view);
}
通过像User这样的变量在 variable 中描述,这样在每个视图中就可以使用。
<!--dataBinding-->
<data>
<variable name="user" type="com.dhc.databinding.myapplication.User"/>
<variable name="handlers" type="com.dhc.databinding.myapplication.ChangeViewHandlers"/>
</data>
绑定点击事件,添加一个Button来进行点击操作与接口方法相关联 android:onClick=”@{handlers.onChangeClick}”。
activity_main.xml
<Button
android:id="@+id/change_btn"
android:text="Change"
android:onClick="@{handlers.onChangeClick}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
android:onClick与View.OnClickListener中onClick属性相对应。同样,View.OnLongClickListener中的onLongClick与android:onLongClick相对应。
点击事件的实现。在MainActivity中实现了接口并接受事件。打印日志。
MainActivity.java
public class MainActivity extends AppCompatActivity implements ChangeViewHandlers {
private User mUser;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUser=new User("Java");
binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.setUser(mUser);
binding.setHandlers(this);
}
@Override
public void onChangeClick(View view) {
Log.d("Debug","Change User name");
}
}
log:D/Debug: Change User name
动态变更数据,点击按钮来进行数据的变更。完成后”Android”会显示在Log中,但是在页面View层还没有进行显示,因此要进行更改视图,以便监视对象。
public class MainActivity extends AppCompatActivity implements ChangeViewHandlers {
private User mUser;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUser=new User("Java");
binding= DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.setUser(mUser);
binding.setHandlers(this);
}
@Override
public void onChangeClick(View view) {
Log.d("Debug","Change User name");
mUser.setName("Android");
Log.d("Debug",mUser.getName());
}
}
log:D/Debug: Change User name
D/Debug: Android
Step 5
继承BaseObservable
继承BaseObservable,并对getter和setter进行修改,在getName()添加@Bindable来监视常量BR.name。将BR.name赋给setName(),当setter发生调用后,进行通知改变。
public class User extends BaseObservable{
private String name;
public User(String name) {
this.name = name;
}
@Bindable
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
notifyPropertyChanged(BR.name);
}
}
此时,点击后,View层就显示为“Android”。
*使用ObservableField
如果不想用继承,另外一种方法来变更,注意它的字段类型是ObservableField。
public class User {
public ObservableField<String> name=new ObservableField<>();
public User(String name) {
this.name.set(name);
}
}
此时,点击后,View层就显示为“Android”。
总结
以上就是使用DataBinding简单的进行数据的绑定,通过一个点击事件来绑定数据,我们不用考虑它怎么使用,事件也不用考虑怎么发生的。将结构进行分离,通过数据绑定来实现View层的数据变化。
上一篇: 朱棣攻入都城后,为什么就能掌握国家大权并即皇帝位?
下一篇: Tensorflow的一些常见函数