当前位置:   article > 正文

Android中使用Adapter(适配器)给RecycleView设置数据源_将数据源添加到适配器

将数据源添加到适配器

场景

RecyclerView

RecyclerView是Android一个更强大的控件,其不仅可以实现和ListView同样的效果,还有优化了ListView中的各种不足。其可以实现数据纵向滚动,也可以实现横向滚动(ListView做不到横向滚动)。

因为RecyclerView属于新增的控件,Android将RecyclerView定义在support库里。若要使用RecyclerView,第一步是要在build.gradle中添加对应的依赖库。

Adapter适配器

顾名思义,就是把一些数据给弄得适当,适合以便于在View上显示。可以看作是界面数据绑定的一种理解。它所操纵的数据一般都是一些比较复杂的数据,如数组,链表,数据库,集合等。适配器就像显示器,把复杂的东西按人可以接受的方式来展现。

数据源是各种各样的,而ListView所展示数据的格式则是有一定的要求的。数据适配器正是建立了数据源与ListView之间的适配关系,将数据源转换为ListView能够显示的数据格式,从而将数据的来源与数据的显示进行解耦,降低程序的耦合性。这也体现了Android的适配器模式的使用

RecycleView是对ListView以及GridView的升级,在使用的时候同源更新需要使用Adapter适配器。但是RecycleView使用的适配器并不是之前的BaseAdapter了。RecycleView使用的适配器需要继承RecyclerView.Adapter<VH extends RecycleView.ViewHolder>

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

创建RecyclerView

下面以一个示例入手看看怎样使用一个Adapter给RecyclerView进行赋值。

首先新建一个项目,然后修改activity_main.xml的页面布局如下

 

最终要实现的效果是点击下面的imageView实现录音,并将录音文件的路径显示在上面的RecyclerView中。

关于录音的实现不做讲解,主要介绍录音完成后使用Adapter给上面的RecyclerView添加数据源,这里以显示录音文件的路径为例。

布局页面activity_main.xml的代码如下

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="match_parent"
  5.     xmlns:app="http://schemas.android.com/apk/res-auto">
  6.     <androidx.recyclerview.widget.RecyclerView
  7.         android:id="@+id/recycler"
  8.         android:layout_width="match_parent"
  9.         android:layout_height="wrap_content"
  10.         app:layout_constraintBottom_toTopOf="@+id/layout_bottom"
  11.         app:layout_constraintTop_toTopOf="parent" />
  12.     <RelativeLayout
  13.         android:layout_width="match_parent"
  14.         android:layout_height="101dp"
  15.         android:id="@+id/layout_bottom"
  16.         android:background="#F7F7F7"
  17.         app:layout_constraintBottom_toBottomOf="parent"
  18.         app:layout_constraintStart_toStartOf="parent">
  19.         <ImageView
  20.             android:layout_width="66dp"
  21.             android:layout_height="66dp"
  22.             android:id="@+id/img_voice"
  23.             android:background="@mipmap/ic_launcher"
  24.             android:layout_centerInParent="true"
  25.             />
  26.     </RelativeLayout>
  27. </androidx.constraintlayout.widget.ConstraintLayout>

注意上面添加RecyclerView的全路径以及添加id属性。

添加依赖

然后添加依赖。打开项目下的build.gradle,添加依赖

implementation 'com.android.support:recyclerview-v7:30.0.0'

注意这里的版本要与你上面的compileSdkVersion对应

 

创建item项的布局文件

然后为RecyclerView的item创建统一的布局文件,在layout下-New-XML-Layout XML File,这里命名为layout_chat_item.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="match_parent"
  4.     android:layout_height="50dp"
  5.     android:layout_gravity="center"
  6.     android:orientation="horizontal">
  7.     <TextView
  8.         android:id="@+id/chat_item"
  9.         android:layout_width="0dp"
  10.         android:layout_height="wrap_content"
  11.         android:layout_weight="1"
  12.         android:gravity="center" />
  13. </LinearLayout>

你可以在这里任意设计视图,它将会应用在你RecyclerView中每个项上。

这里为了演示,值简单添加了一个TextView,记得给这个TextView设置ID

创建Adapter

我们在项目下新建一个包adapter,并在包下新建类ChatAdapter。

这个CharAdapter需要继承RecycleView.Adapter<>,并且泛型里面的类型是自定义的继承自RecycleView.ViewHolder的类。

关于ViewHolder

ViewHolder的主要任务:容纳View视图。Adapter连接了后端数据和前端显示,viewHolder的作用就是提供前端的视图文件。

这个自定义ViewHolder可以是外部类,但是为了方便,将其作为ChatAdaprer的内部类

需要在自定义的ViewHolder中绑定视图文件,就好像在MainActivity中绑定activity_main.xml布局文件一样

这里需要绑定我们在上面新建的每一项的布局视图,即layout_chat_item.xml,并且获取到每一项布局视图的控件。

所以此时的ChatAdapter的代码如下

  1. public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {
  2.     class ChatViewHolder extends RecyclerView.ViewHolder{
  3.         private TextView mText;
  4.         public ChatViewHolder(View itemView) {
  5.             super(itemView);
  6.             mText = (TextView) itemView.findViewById(R.id.chat_item);
  7.         }
  8.     }
  9. }

注意此时还没有重写指定的三个方法。

此时我们先创建一个数据实体类ChatBean

  1. package com.badao.audiodemo.bean;
  2. import androidx.annotation.NonNull;
  3. import java.util.List;
  4. public class ChatBean {
  5.    
  6.     private String msg;
  7.     private int code;
  8.     @NonNull
  9.     private String id = "";
  10.    
  11.     private List<ChatItem> data;
  12.     public String getMsg() {
  13.         return msg;
  14.     }
  15.     public void setMsg(String msg) {
  16.         this.msg = msg;
  17.     }
  18.     public int getCode() {
  19.         return code;
  20.     }
  21.     public void setCode(int code) {
  22.         this.code = code;
  23.     }
  24.     public List<ChatItem> getData() {
  25.         return data;
  26.     }
  27.     public void setData(List<ChatItem> data) {
  28.         this.data = data;
  29.     }
  30.     @NonNull
  31.     public String getId() {
  32.         return id;
  33.     }
  34.     public void setId(@NonNull String id) {
  35.         this.id = id;
  36.     }
  37.     public static class ChatItem {
  38.         private int id;
  39.         private String msgNum;
  40.         private String content;
  41.         //语音消息服务器地址
  42.         private String remoteContent;
  43.         private String sender;
  44.         private String receiver;
  45.         private String type;
  46.         private boolean canReceived;
  47.         private String sendTime;
  48.         private String receivedTime;
  49.         //语音时长
  50.         private int voiceDuration;
  51.         private boolean isRead;
  52.         public int getId() {
  53.             return id;
  54.         }
  55.         public void setId(int id) {
  56.             this.id = id;
  57.         }
  58.         public String getMsgNum() {
  59.             return msgNum;
  60.         }
  61.         public void setMsgNum(String msgNum) {
  62.             this.msgNum = msgNum;
  63.         }
  64.         public String getContent() {
  65.             return content;
  66.         }
  67.         public void setContent(String content) {
  68.             this.content = content;
  69.         }
  70.         public String getSender() {
  71.             return sender;
  72.         }
  73.         public void setSender(String sender) {
  74.             this.sender = sender;
  75.         }
  76.         public String getReceiver() {
  77.             return receiver;
  78.         }
  79.         public void setReceiver(String receiver) {
  80.             this.receiver = receiver;
  81.         }
  82.         public String getType() {
  83.             return type;
  84.         }
  85.         public void setType(String type) {
  86.             this.type = type;
  87.         }
  88.         public boolean isCanReceived() {
  89.             return canReceived;
  90.         }
  91.         public void setCanReceived(boolean canReceived) {
  92.             this.canReceived = canReceived;
  93.         }
  94.         public String getSendTime() {
  95.             return sendTime;
  96.         }
  97.         public void setSendTime(String sendTime) {
  98.             this.sendTime = sendTime;
  99.         }
  100.         public String getReceivedTime() {
  101.             return receivedTime;
  102.         }
  103.         public void setReceivedTime(String receivedTime) {
  104.             this.receivedTime = receivedTime;
  105.         }
  106.         public int getVoiceDuration() {
  107.             return voiceDuration;
  108.         }
  109.         public void setVoiceDuration(int voiceDuration) {
  110.             this.voiceDuration = voiceDuration;
  111.         }
  112.         public String getRemoteContent() {
  113.             return remoteContent;
  114.         }
  115.         public void setRemoteContent(String remoteContent) {
  116.             this.remoteContent = remoteContent;
  117.         }
  118.         public boolean isRead() {
  119.             return isRead;
  120.         }
  121.         public void setRead(boolean read) {
  122.             isRead = read;
  123.         }
  124.     }
  125. }

实体类的内容可以自己定义,这里是包含了语音消息实体的相关属性。

然后再回到ChatAdapter,此时重写其三个方法,然后新建上面实体的list作为数据源,并编写其set方法

  1.     private List<ChatBean.ChatItem> mEntityList = new ArrayList<>();
  2.     public void setmEntityList(List<ChatBean.ChatItem> mEntityList) {
  3.         this.mEntityList = mEntityList;
  4.         //一定要记得加,否则视图不会更新!!!
  5.         notifyDataSetChanged();
  6.     }

重写onCreateViewHolder方法

返回我们的内部类MyViewHolder ,此处为将我们的item布局文件和adapter绑定。

  1.     @NonNull
  2.     @Override
  3.     public ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  4.         View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_chat_item, parent, false);
  5.         return new ChatViewHolder(view);
  6.     }

重写onBindViewHolder方法

对每一项的TextView进行赋值,取出实体的某一属性进行显示,position为下标。

  1.     @Override
  2.     public void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {
  3.         holder.mText.setText(mEntityList.get(position).getContent().toString());
  4.     }

重写getItemCount方法

获得实体list的长度,即显示项的个数

  1.     @Override
  2.     public int getItemCount() {
  3.         return mEntityList == null?0:mEntityList.size();
  4.     }

此时完整的ChatAdapter的代码为:

  1. package com.badao.audiodemo.adapter;
  2. import android.content.Context;
  3. import android.view.LayoutInflater;
  4. import android.view.View;
  5. import android.view.ViewGroup;
  6. import android.widget.TextView;
  7. import androidx.annotation.NonNull;
  8. import androidx.recyclerview.widget.RecyclerView;
  9. import com.badao.audiodemo.R;
  10. import com.badao.audiodemo.bean.ChatBean;
  11. import java.util.ArrayList;
  12. import java.util.List;
  13. public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {
  14.     private List<ChatBean.ChatItem> mEntityList = new ArrayList<>();
  15.     public void setmEntityList(List<ChatBean.ChatItem> mEntityList) {
  16.         this.mEntityList = mEntityList;
  17.         //一定要记得加,否则视图不会更新!!!
  18.         notifyDataSetChanged();
  19.     }
  20.     @NonNull
  21.     @Override
  22.     public ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
  23.         View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_chat_item, parent, false);
  24.         return new ChatViewHolder(view);
  25.     }
  26.     @Override
  27.     public void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {
  28.         holder.mText.setText(mEntityList.get(position).getContent().toString());
  29.     }
  30.     @Override
  31.     public int getItemCount() {
  32.         return mEntityList == null?0:mEntityList.size();
  33.     }
  34.     class ChatViewHolder extends RecyclerView.ViewHolder{
  35.         private TextView mText;
  36.         public ChatViewHolder(View itemView) {
  37.             super(itemView);
  38.             mText = (TextView) itemView.findViewById(R.id.chat_item);
  39.         }
  40.     }
  41. }

使用Adapter给RecycleView赋值

在MainActivity中先声明所需对象

  1. public class MainActivity extends AppCompatActivity {
  2.     private RecyclerView mRecyclerView;
  3.     private List<ChatBean.ChatItem> chatItemList;
  4.     private  ChatAdapter chatAdapter;

然后在onCreate方法中初始化

  1.     @Override
  2.     protected void onCreate(Bundle savedInstanceState) {
  3.         super.onCreate(savedInstanceState);
  4.         setContentView(R.layout.activity_main);
  5.         initRecyclerView();
  6.     }
  7.     /**
  8.      * 初始化RecyclerView
  9.      */
  10.     private void initRecyclerView(){
  11.         mRecyclerView = findViewById(R.id.recycler);
  12.         chatItemList = new ArrayList<>();
  13.         chatAdapter = new ChatAdapter();
  14.         // 定义一个线性布局管理器
  15.         LinearLayoutManager manager = new LinearLayoutManager(this);
  16.         // 设置布局管理器
  17.         mRecyclerView.setLayoutManager(manager);
  18.         // 设置adapter
  19.         mRecyclerView.setAdapter(chatAdapter);
  20.     }

然后就是在需要对RecycleView进行赋值的地方,这里为例是在录音结束后的回调方法中,也是在MainActivity中

  1.         @Override
  2.         public void onFinish(Uri uri, int i) {
  3.             File file = new File(uri.getPath());
  4.             ChatBean.ChatItem chatItem = new ChatBean.ChatItem();
  5.             chatItem.setId((int) System.currentTimeMillis());
  6.             chatItem.setSendTime(new Date().toString());
  7.             chatItem.setContent(file.getAbsolutePath());
  8.             chatItemList.add(chatItem);
  9.             chatAdapter.setmEntityList(chatItemList);
  10.         }

直接将实体类对象添加到list中并调用chatAdapter的set方法即可,就会自动在recycleView中更新数据

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/287540
推荐阅读
相关标签
  

闽ICP备14008679号