binding框架是一个UI框架,作用帮助开发者快速开发UI。原理是先通过一定的规则写一个XML的布局,Android studio自动生成一个Binding的java类。
使用Data Binding首先,环境搭建:
Android 的 Gradle 插件版本不低于 1.5.0-alpha1:
classpath ‘com.android.tools.build:gradle:1.5.0’
然后修改对应模块(Module)的 build.gradle的android节点下添加:
dataBinding {
enabled = true
}
下面举两个例子。先贴图。
例一图 例二图
frag_main.xml 布局文件
(1)后面Android studio自动生成的类名字叫FramMainBinding.java 他的名字与这个布局文件的命名有直接关系。
(2)这个布局的基本规则,最外层布局需要用
(3)
(4)android:text="@{person.name}" 这里就是引用PersionEntity对象里面的name值。
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{person.name}"
android:textSize="16dp" />
这是Android studio自动升生成的FramMainBinding.java
package one.example.com.myapplication3.databinding;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.Bindable;
import androidx.databinding.DataBindingComponent;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import one.example.com.myapplication3.db.entity.PersonEntity;
public abstract class FragMainBinding extends ViewDataBinding {
@NonNull
public final TextView age;
@NonNull
public final Button btnShowName;
@NonNull
public final TextView name;
@Bindable
protected PersonEntity mPerson;
protected FragMainBinding(DataBindingComponent _bindingComponent, View _root,
int _localFieldCount, TextView age, Button btnShowName, TextView name) {
super(_bindingComponent, _root, _localFieldCount);
this.age = age;
this.btnShowName = btnShowName;
this.name = name;
}
public abstract void setPerson(@Nullable PersonEntity person);
@Nullable
public PersonEntity getPerson() {
return mPerson;
}
@NonNull
public static FragMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root,
boolean attachToRoot) {
return inflate(inflater, root, attachToRoot, DataBindingUtil.getDefaultComponent());
}
@NonNull
public static FragMainBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root,
boolean attachToRoot, @Nullable DataBindingComponent component) {
return DataBindingUtil.inflate(inflater, one.example.com.myapplication3.R.layout.frag_main, root, attachToRoot, component);
}
@NonNull
public static FragMainBinding inflate(@NonNull LayoutInflater inflater) {
return inflate(inflater, DataBindingUtil.getDefaultComponent());
}
@NonNull
public static FragMainBinding inflate(@NonNull LayoutInflater inflater,
@Nullable DataBindingComponent component) {
return DataBindingUtil.inflate(inflater, one.example.com.myapplication3.R.layout.frag_main, null, false, component);
}
public static FragMainBinding bind(@NonNull View view) {
return bind(view, DataBindingUtil.getDefaultComponent());
}
public static FragMainBinding bind(@NonNull View view, @Nullable DataBindingComponent component) {
return (FragMainBinding)bind(component, view, one.example.com.myapplication3.R.layout.frag_main);
}
}
以上这个类生成后在这里如下图。
下面是binding在Fragment里面的使用。FragmentHome.java类
public class FragmentHome extends Fragment {
FragMainBinding binding;//FragMainBinding这个类自动在frag_main.xml文件创建好后Rebuild project下自动创建好。但是这个frag_main.xml需要按照一定的要求创建。
View v;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = DataBindingUtil.inflate(inflater, R.layout.frag_main, container, false);//绑定frag_main.xml文件获取binding对象。
PersonEntity entity = new PersonEntity("Albert", "24");
binding.setPerson(entity);//把persion对象传进入
v = binding.getRoot();
return v;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
v.findViewById(R.id.btn_showName).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.e("FragmentHome", "onClick: 点击button");
}
});
}
}
PersonEntity.java实体类。
public class PersonEntity implements Serializable {
private int id;
private String name;
private String age;
public PersonEntity(String name, String age) {
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
上面是在Fragment里面使用binding而且使用起来比较简单,下面的例子是在Activity里面使用。相对上面来说稍微复杂一定。
先上activity_list.xml布局文件
//LayoutManager这个值如果不设置就没办法展示数据,在Java代码中设置这个参数也可以
PersonListAdapter.java适配器
public class PersonListAdapter extends RecyclerView.Adapter {
private List extends IPersonBean> beanList;
private final IPersonCallBack mClickCallBack;
public PersonListAdapter(IPersonCallBack clickCallBack) {
mClickCallBack = clickCallBack;
setHasStableIds( true );//为了使 url 没变的时候刷新RecyclerView时ImageView 不重新加载
}
public void addPersonList(final List extends IPersonBean> list) {
if (beanList == null) {
beanList = list;
notifyItemRangeInserted( 0, beanList.size() );
} else {
DiffUtil.DiffResult result = DiffUtil.calculateDiff( new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return beanList.size();
}
@Override
public int getNewListSize() {
return list.size();
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
return beanList.get( oldItemPosition ).getId() == list.get( newItemPosition ).getId();
}
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
IPersonBean newProduct = list.get( newItemPosition );
IPersonBean oldProduct = beanList.get( oldItemPosition );
return newProduct.getId() == oldProduct.getId() && Objects.equals( newProduct.getAge(), oldProduct.getAge() ) && Objects.equals( newProduct.getName(), oldProduct.getName() );
}
} );
beanList = list;
result.dispatchUpdatesTo( this );
}
}
@NonNull
@Override
public PersonViewHolper onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//person_recyclerview_item.xml绑定到PersonRecyclerviewItemBinding上面
PersonRecyclerviewItemBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.person_recyclerview_item, parent, false );
binding.setCallback( mClickCallBack );
return new PersonViewHolper( binding );
}
@Override
public void onBindViewHolder(@NonNull PersonViewHolper holder, int position) {
holder.mBinding.setPersonBean( beanList.get( position ) );
holder.mBinding.executePendingBindings();
}
@Override
public int getItemCount() {
return beanList == null ? 0 : beanList.size();
}
@Override
public long getItemId(int position) {
return beanList.get( position ).getId();
}
static class PersonViewHolper extends RecyclerView.ViewHolder {
final PersonRecyclerviewItemBinding mBinding;
public PersonViewHolper(PersonRecyclerviewItemBinding binding) {
super( binding.getRoot() );
this.mBinding = binding;
}
}
}
ListActivity.java 这里是dataBinding在Activity的使用代码。
public class ListActivity extends FragmentActivity {
private String TAG = "ListActivity";
private ActivityListBinding binding;
private PersonEntity select;
private PersonListAdapter adapter;
@SuppressLint("WrongConstant")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
binding = DataBindingUtil.setContentView( this, R.layout.activity_list );
adapter = new PersonListAdapter( clickCallBack );
binding.recyclerview.setLayoutManager( new LinearLayoutManager( this, LinearLayoutManager.VERTICAL, false ) );//这个参数必须设置,或者在xml布局中设置也可以
binding.recyclerview.setAdapter( adapter );
if (select == null) {
select = new PersonEntity( "暂时么有选择", "" );
}
addTitle( select );
}
@Override
protected void onResume() {
super.onResume();
addData( adapter );//添加数据到ListView里面。放到onCreate里面也可以。
binding.executePendingBindings();//计算挂起的绑定,更新将表达式绑定到已修改变量的任何视图。
}
public void addTitle(PersonEntity select) {
binding.setTitleName( select.getName() );
binding.setTitleAge( select.getAge() );
}
/**
* 自己造数据
*
* @param adapter
*/
public void addData(PersonListAdapter adapter) {
List listBean = new ArrayList<>();
String[] strData = {"AAA", "BBB", "CCC", "DDD", "Jack", "Mary", "Fox", "Albert", "Jason", "FFF", "ggg"};
for (int j = 0; j < strData.length; j++) {
PersonEntity personBean = new PersonEntity( strData[j], "" + (21 + j) );
listBean.add( personBean );
}
adapter.addPersonList( listBean );
}
IPersonCallBack clickCallBack = new IPersonCallBack() {
@Override
public void onClick(IPersonBean person) {
select = (PersonEntity) person;
addTitle( select );
Logs.eprintln( TAG, "点击:" + person.getName() );
}
};
}
PersonEntity.java实体类。
public class PersonEntity implements IPersonBean, Serializable {
@PrimaryKey
private int id;
private String name;
private String age;
public PersonEntity(String name, String age) {
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}