關於Android的Databinding在RecyclerView上使用的記錄
阿新 • • 發佈:2018-12-22
首先我是 不太喜歡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;
}
}
}