您的位置:首页 > 移动开发 > Android开发

Data Binding 打造RecyclerView 万能适配器

2016-02-28 18:49 441 查看
最近因为项目需要,采用了data bind 来封装了一下RecyclerView的适配器,抽象出了Adapter.

至于不了解data bind是什么可以点击这里

我们仔细观察RecyclerAdapter可以发现主要是实现onCreateViewHolder(ViewGroup parent, int viewType)和onBindViewHolder(RecyclerView.ViewHolder holder, int position)这两个方法。

所以在我们的父类中我们将这两个方法抽出来。onCreateViewHolders是创建我们的ViewHolder所以这里我们只需拿到布局的引用即可

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

ViewDataBinding binding = DataBindingUtil.inflate(
LayoutInflater.from(parent.getContext()),
getItemLayoutId(viewType),
parent,
false);

final RecyclerViewHolder holder = new RecyclerViewHolder(binding.getRoot());

holder.setBinding(binding);

if( null != myItemClickListener){
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myItemClickListener.onItemClick(holder.itemView,holder.getLayoutPosition());
}
});
}

if( null != myItemLongClickListener){
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
myItemLongClickListener.onItemLongClick(holder.itemView,holder.getLayoutPosition());
return true;
}
});
}

return holder;
}


onBindViewHolder()方法则主要是我们具体的操作。

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

RecyclerViewHolder recyclerViewHolder = (RecyclerViewHolder) holder;

switch (mMode){
case TYPE_NORMAL:
bindData(recyclerViewHolder,mData.get(position));
break;
case TYPE_CUSTOM:
bindData(recyclerViewHolder,mData.get(position));
bindCustomData(recyclerViewHolder,position,mData.get(position));
break;
}

}


在父类中其实并不用管这些,子类只需继承并实现以下几个方法

/**
* 布局引用
* @param viewType
* @return
*/
abstract public int getItemLayoutId(int viewType);

/**
* data bind Variable 引用
* @return
*/
abstract public int getVariableId();
/**
* 自定义操作
* @param holder
* @param position
* @param item
*/
abstract public void bindCustomData(RecyclerViewHolder holder,int position,T item);

/**
* 加载模式
* @return
*/
abstract public int getStartMode();


getItemLayoutId()这个方法子类实现并返回你的布局文件引用。

getVariableId()这个是返回你布局中使用data binding所命名的变量引用。

bindCustomData()在这个方法中,如果你的布局复杂,可以实现自己具体的事件。

getStartMode()这个方法返回的是你所选择加载的模式,如果你需要使用bindCustomData()这个方法,你不能返回0.

在这里我们还实现了统一的ViewHolder

public class RecyclerViewHolder extends RecyclerView.ViewHolder {

private ViewDataBinding binding;

public RecyclerViewHolder(View itemView) {
super(itemView);
}

public ViewDataBinding getBinding() {
return binding;
}

public void setBinding(ViewDataBinding binding) {
this.binding = binding;
}

}


RecyclerViewHolder中使用了data binding框架。具体使用可以查看链接。

具体例子:

public class UserAdapter extends RecyclerBaseAdapter<User> {

public UserAdapter(List<User> mData, Context mContext) {
super(mData, mContext);
}

@Override
public int getItemLayoutId(int viewType) {
return R.layout.main_item;
}

@Override
public int getVariableId() {
return BR.users;
}

@Override
public void bindCustomData(RecyclerViewHolder holder, int position, User item) {

}

@Override
public int getStartMode() {
return 0;
}
}


可以看到我们继承了RecyclerBaseAdapter实现了一个UserAdapter在这个方法中实现了上面所述的4个方法。

我们的User也很简单:

public class User {

private String name;
private String avatar;
private String age;

public User(){

}

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

public String getAvatar() {
return avatar;
}

public void setAvatar(String avatar) {
this.avatar = avatar;
}

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;
}

}


这有头像,名字,年龄

布局文件 main_item.xml

<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="users"
type="com.red.allrecyclerdemo.models.User"/>

</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:orientation="horizontal">
<ImageView
android:layout_width="45dp"
android:layout_height="45dp"
android:scaleType="centerCrop"
app:error="@{@drawable/default_image}"
app:imageUrl="@{users.avatar}"/>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="5dp"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:text="@{users.name}" />

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{users.age}"/>

</LinearLayout>

</LinearLayout>
</LinearLayout>
</layout>


该布局文件显示我们的头像,姓名,年龄而已,做为一个例子也是够了。

然后查看我们的MainActivity.java

public class MainActivity extends AppCompatActivity {

private UserAdapter mAdapter;
private List<User> mUsers;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
mUsers = new ArrayList<User>();
setData();
mAdapter = new UserAdapter(mUsers,MainActivity.this);
//设置布局管理器
binding.recyclerView.setLayoutManager(new LinearLayoutManager(this));

binding.recyclerView.setAdapter(mAdapter);
}

private void setData(){

for(int i = 0; i < 10; i++){
User user = new User();
user.setAvatar("http://g.hiphotos.baidu.com/image/h%3D200/sign=4d3fabc3cbfc1e17e2bf8b317a91f67c/6c224f4a20a446230761b9b79c22720e0df3d7bf.jpg");
user.setName("小米" + i);
user.setAge(String.valueOf(i));
mUsers.add(user);
}
}
}


效果图:



Data Binding大大简化了我们的工作量,值得学习。

项目源码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  binding Android