关于Android的Databinding在RecyclerView上使用的记录
首先我是 不太喜欢Databinding这玩意的,虽然用着还是蛮爽的,一绑定所有的控件直接拿到,也不用findViewbyid了,但是这东西出错误了巨难差。你要是在xml里面写错了,AndroidStudio不报错的那种错误,那你就头疼吧。Databinding对象死活就不会生成,纠结到死。 算了,不吐槽了,说不上AndroidStudio以后会对Databinding支持的特别好 也说不好。
废话不多说。这里记录一下在RecyclerView中使用Databinding,在多布局的时候简化布局那还是挺爽的。Databinding的配置自己搞,网上一查一大堆。我默认你们都配置好了Databinding和Glide了。
完成样式:
第一步,我们先创建最基本的MainActivity和它的layout, 这里主activity的layout用Databing纯属是我偷懒不想写findViewById。哈哈哈
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static MessageAdapter adapter = null;
private static RecyclerView recyclerView = null;
private static ActivityMainBinding binding = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
binding.addTextItem.setOnClickListener(this);
binding.addImageItem.setOnClickListener(this);
recyclerView = binding.recyclerview;
adapter = new MessageAdapter(this,initData());
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
//这里初始化一组数据
public List<BaseMessage> initData(){
List<BaseMessage> list = new ArrayList<>();
list.add(new TextMessageBean("新消息一"));
list.add(new TextMessageBean("新消息二"));
list.add(new TextMessageBean("新消息三"));
list.add(new TextMessageBean("新消息四"));
list.add(new ImageMessageBean("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542465393611&di=677e365a4eb62a29278aef1d5d48fa40&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201411%2F11%2F20141111171817_8chGL.jpeg"));
list.add(new TextMessageBean("新消息五"));
list.add(new TextMessageBean("新消息六"));
return list;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.add_text_item:
adapter.updateItem(new TextMessageBean("新消息到了~"));
break;
case R.id.add_image_item:
adapter.updateItem(new ImageMessageBean("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1542468020668&di=43a1083a4d0ae308f90403b34463ec8a&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201605%2F10%2F20160510170018_sKmZe.thumb.700_0.png"));
break;
}
//这个是每次都滚动到最后一行
recyclerView.scrollToPosition(adapter.getItemCount()-1);
}
}
<?xml version="1.0" encoding="utf-8"?>
<layout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
</android.support.v7.widget.RecyclerView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/add_text_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="增加文字消息" />
<Button
android:id="@+id/add_image_item"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="增加图片消息" />
</LinearLayout>
</LinearLayout>
</layout>
第二步,我们创建一个BaseMessage的接口,让两个数据JavaBean都继承它,分别存放文字类型和图片类型,这玩意后期自己还能拓展拓展啥的。
BaseMessage
public interface BaseMessage {
final int TextMessage = 0;
final int ImageMessage = 1;
int getType();
}
TextMessageBean
public class TextMessageBean extends BaseObservable implements BaseMessage{
String msgTime = "";
String content = "";
public TextMessageBean(String message){
setContent(message);
}
public String getMsgTime() {
return msgTime;
}
public void setMsgTime(String msgTime) {
this.msgTime = msgTime;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public int getType() {
return BaseMessage.TextMessage;
}
}
ImageMessageBean(这里面注意特殊写了一个方法让glide处理传入URL设置图片)
public class ImageMessageBean implements BaseMessage{
String imageURL = "";
public ImageMessageBean(String url){
setImageURL(url);
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
@Override
public int getType() {
return BaseMessage.ImageMessage;
}
//这里写了一个static方法,用于特殊处理传入的图片
//第一个参数是默认的绑定数据类型是什么就会传入
//第二个参数是设定的参数
@BindingAdapter({"loadImage"})
public static void loadImage(ImageView imageView,String url){
Glide.with(imageView).load(url).into(imageView);
}
}
第三步,写这个通用的Adapter方法。(Recycler使用就不科普了,来看的都会用 )
public class MessageAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<BaseMessage> list = null;
private Context context = null;
public MessageAdapter(Context cont,List<BaseMessage> li){
this.list = li;
this.context = cont;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
ViewDataBinding binding = null;
switch (viewType){
case BaseMessage.TextMessage:
binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),R.layout.recycler_msg_item,viewGroup,false);
break;
case BaseMessage.ImageMessage:
binding = DataBindingUtil.inflate(LayoutInflater.from(viewGroup.getContext()),R.layout.recycler_img_item,viewGroup,false);
break;
}
return new MyViewHolder(binding);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
((MyViewHolder)viewHolder).getBinding().setVariable(BR.data,list.get(position));
((MyViewHolder)viewHolder).getBinding().executePendingBindings();
}
@Override
public int getItemCount() {
return list.size();
}
@Override
public int getItemViewType(int position) {
return list.get(position).getType();
}
public void updateItem(BaseMessage message){
list.add(message);
notifyDataSetChanged();
}
class MyViewHolder extends RecyclerView.ViewHolder{
ViewDataBinding binding = null;
public MyViewHolder(ViewDataBinding itemView) {
super(itemView.getRoot());
this.binding = itemView;
}
public ViewDataBinding getBinding(){
return binding;
}
}
}