DataBinding的基本使用(五)
DataBinding基本使用包括以下内容:
- 单纯的摆脱findviewbyid
- 绑定基本数据类型及String
- 绑定Model数据
- 绑定事件
- 通过静态方法转换数据类型
- 通过运算符操作数据
- 自定义Binding的类名
- 绑定相同Model的操作
- model变量改变自动更新数据
- 绑定List/Map等集合数据
- Observable自动更新
- Databinding与include标签的结合
- DataBinding与RecyclerView的结合
3.12 Databinding与include标签的结合
布局文件
activity_five.xml
<?xml version="1.0" encoding="utf-8"?><!--布局以layout作为根布局-->
<layout>
<data >
<import type="www.zhang.com.databinding.model.Content"/>
<variable
name="con"
type="Content"/>
</data>
<!--我们需要展示的布局-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"
android:layout_height="56dp"
android:layout_width="match_parent"
bind:content="@{con}" />
<!--通过命名空间将写有toolbar的xml文件中定义的content对象作为属性绑定con对象,这2个对象是同一个类-->
<TextView
android:text="@string/app_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
toolbar.xml
<?xml version="1.0" encoding="utf-8"?>
<layout >
<data>
<import type="www.zhang.com.databinding.model.Content"/>
<variable
name="content"
type="Content"/>
</data>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/toolbar"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="56dp"
android:layout_width="match_parent"
app:title="@{content.title}"
app:subtitle="@{content.subTitle}"
android:background="@color/colorPrimary"
app:titleTextColor="@android:color/white"
app:subtitleTextColor="@android:color/white" />
</layout>
在activity_five.xml中的include属性中定义了一个id,同时又在toolbar.xml中的Toolbar标签中又定义了一个id,其作用是通过binding.toolbar.toolbar等同于Toolbar控件,可以方便做一些操作等
FiveActivity中
public class FiveActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
ActivityFiveBinding binding =DataBindingUtil.setContentView(FiveActivity.this, R.layout.activity_five);
Content con = new Content("Title","SubTitle");
binding.setCon(con);
// binding.toolbar.setContent(con); //这个测试没有效果,不会显示toolbar的title/subTitle
// binding.toolbar.toolbar.setTitle("");
// binding.toolbar.toolbar.setSubtitle("");
//下面的代码也可以通过DataBinding绑定数据
binding.toolbar.toolbar.setNavigationIcon(R.mipmap.ic_launcher);
setSupportActionBar(binding.toolbar.toolbar);
binding.toolbar.toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
Content
public class Content extends BaseObservable {
private String title;
private String subTitle;
public Content(String title, String subTitle) {
this.title = title;
this.subTitle = subTitle;
}
@Bindable public String getSubTitle() {
return subTitle;
}
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
notifyPropertyChanged(BR.subTitle);
}
@Bindable public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
notifyPropertyChanged(BR.title);
}
}
3.13 DataBinding与RecyclerView的结合
布局文件
activity_five.xml
<?xml version="1.0" encoding="utf-8"?><!--布局以layout作为根布局-->
<layout>
<data >
<import type="www.zhang.com.databinding.model.Content"/>
<variable
name="con"
type="Content"/>
</data>
<!--我们需要展示的布局-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar"
android:layout_height="56dp"
android:layout_width="match_parent"
bind:content="@{con}" />
<!--通过命名空间将写有toolbar的xml文件中定义的content对象作为属性绑定con对象,这2个对象是同一个类-->
<android.support.v7.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</layout>
recycler_item.xml
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data>
<variable
name="str"
type="String"/>
</data>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:orientation="vertical">
<TextView
android:text="@{str}"
android:gravity="center_vertical"
android:textColor="@android:color/black"
android:textSize="16sp"
android:layout_width="match_parent"
android:layout_height="48dp" />
</LinearLayout>
</layout>
FiveActivity
public class FiveActivity extends AppCompatActivity {
private ActivityFiveBinding binding;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
binding = DataBindingUtil.setContentView(FiveActivity.this, R.layout.activity_five);
initToolbar();
initRecyclerView();
}
private void initRecyclerView() {
LinearLayoutManager manager = new LinearLayoutManager(FiveActivity.this);
binding.recycler.setLayoutManager(manager);
binding.recycler.setHasFixedSize(true);
MyAdapter adapter = new MyAdapter(getApplicationContext());
binding.recycler.setAdapter(adapter);
}
private void initToolbar() {
Content con = new Content("Title","SubTitle");
binding.setCon(con);
// binding.toolbar.setContent(con); //这个测试没有效果,不会显示toolbar的title/subTitle
// binding.toolbar.toolbar.setTitle("");
// binding.toolbar.toolbar.setSubtitle("");
//下面的代码也可以通过DataBinding绑定数据
binding.toolbar.toolbar.setNavigationIcon(R.mipmap.ic_launcher);
setSupportActionBar(binding.toolbar.toolbar);
binding.toolbar.toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
}
MyAdapter
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private Context mContext;
String[] datas;
public MyAdapter(Context context) {
mContext = context;
datas = context.getResources().getStringArray(R.array.item_list);
}
@Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(mContext), R.layout.recycler_item, parent, false);
return new MyViewHolder(binding);
}
@Override
public void onBindViewHolder(MyAdapter.MyViewHolder holder, int position) {
String name = datas[position];
holder.getBinding().setVariable(www.zhang.com.databinding.BR.str,name);
//holder.getBinding().setStr(name); //两者都可以
//executePendingBindings()方法说明
// When a variable or observable changes, the binding will be scheduled to change before the next frame.
// There are times, however, when binding must be executed immediately.
// To force execution, use the executePendingBindings() method.
holder.getBinding().executePendingBindings();//此方法必须执行在UI线程,当绑定的数据修改时更新视图(不知道翻译的准不准)
}
@Override
public int getItemCount() {
return datas.length;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private RecyclerItemBinding binding;
public MyViewHolder(ViewDataBinding binding) {
super(binding.getRoot());
this.binding = (RecyclerItemBinding) binding;
}
public RecyclerItemBinding getBinding() {
return binding;
}
public void setBinding(RecyclerItemBinding binding) {
this.binding = binding;
}
}
}
参考文章