场景

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的代码如下

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="http://schemas.android.com/apk/res-auto"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recycler"android:layout_width="match_parent"android:layout_height="wrap_content"app:layout_constraintBottom_toTopOf="@+id/layout_bottom"app:layout_constraintTop_toTopOf="parent" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="101dp"android:id="@+id/layout_bottom"android:background="#F7F7F7"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"><ImageViewandroid:layout_width="66dp"android:layout_height="66dp"android:id="@+id/img_voice"android:background="@mipmap/ic_launcher"android:layout_centerInParent="true"/></RelativeLayout></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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="50dp"android:layout_gravity="center"android:orientation="horizontal"><TextViewandroid:id="@+id/chat_item"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center" /></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的代码如下

public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {class ChatViewHolder extends RecyclerView.ViewHolder{private TextView mText;public ChatViewHolder(View itemView) {super(itemView);mText = (TextView) itemView.findViewById(R.id.chat_item);}}
}

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

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

package com.badao.audiodemo.bean;import androidx.annotation.NonNull;
import java.util.List;public class ChatBean {private String msg;private int code;@NonNullprivate String id = "";private List<ChatItem> data;public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public List<ChatItem> getData() {return data;}public void setData(List<ChatItem> data) {this.data = data;}@NonNullpublic String getId() {return id;}public void setId(@NonNull String id) {this.id = id;}public static class ChatItem {private int id;private String msgNum;private String content;//语音消息服务器地址private String remoteContent;private String sender;private String receiver;private String type;private boolean canReceived;private String sendTime;private String receivedTime;//语音时长private int voiceDuration;private boolean isRead;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getMsgNum() {return msgNum;}public void setMsgNum(String msgNum) {this.msgNum = msgNum;}public String getContent() {return content;}public void setContent(String content) {this.content = content;}public String getSender() {return sender;}public void setSender(String sender) {this.sender = sender;}public String getReceiver() {return receiver;}public void setReceiver(String receiver) {this.receiver = receiver;}public String getType() {return type;}public void setType(String type) {this.type = type;}public boolean isCanReceived() {return canReceived;}public void setCanReceived(boolean canReceived) {this.canReceived = canReceived;}public String getSendTime() {return sendTime;}public void setSendTime(String sendTime) {this.sendTime = sendTime;}public String getReceivedTime() {return receivedTime;}public void setReceivedTime(String receivedTime) {this.receivedTime = receivedTime;}public int getVoiceDuration() {return voiceDuration;}public void setVoiceDuration(int voiceDuration) {this.voiceDuration = voiceDuration;}public String getRemoteContent() {return remoteContent;}public void setRemoteContent(String remoteContent) {this.remoteContent = remoteContent;}public boolean isRead() {return isRead;}public void setRead(boolean read) {isRead = read;}}}

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

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

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

重写onCreateViewHolder方法

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

    @NonNull@Overridepublic ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_chat_item, parent, false);return new ChatViewHolder(view);}

重写onBindViewHolder方法

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

    @Overridepublic void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {holder.mText.setText(mEntityList.get(position).getContent().toString());}

重写getItemCount方法

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

    @Overridepublic int getItemCount() {return mEntityList == null?0:mEntityList.size();}

此时完整的ChatAdapter的代码为:

package com.badao.audiodemo.adapter;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;import com.badao.audiodemo.R;
import com.badao.audiodemo.bean.ChatBean;import java.util.ArrayList;
import java.util.List;public class ChatAdapter extends RecyclerView.Adapter<ChatAdapter.ChatViewHolder> {private List<ChatBean.ChatItem> mEntityList = new ArrayList<>();public void setmEntityList(List<ChatBean.ChatItem> mEntityList) {this.mEntityList = mEntityList;//一定要记得加,否则视图不会更新!!!notifyDataSetChanged();}@NonNull@Overridepublic ChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_chat_item, parent, false);return new ChatViewHolder(view);}@Overridepublic void onBindViewHolder(@NonNull ChatViewHolder holder, int position) {holder.mText.setText(mEntityList.get(position).getContent().toString());}@Overridepublic int getItemCount() {return mEntityList == null?0:mEntityList.size();}class ChatViewHolder extends RecyclerView.ViewHolder{private TextView mText;public ChatViewHolder(View itemView) {super(itemView);mText = (TextView) itemView.findViewById(R.id.chat_item);}}
}

使用Adapter给RecycleView赋值

在MainActivity中先声明所需对象

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

然后在onCreate方法中初始化

    @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initRecyclerView();}/*** 初始化RecyclerView*/private void initRecyclerView(){mRecyclerView = findViewById(R.id.recycler);chatItemList = new ArrayList<>();chatAdapter = new ChatAdapter();// 定义一个线性布局管理器LinearLayoutManager manager = new LinearLayoutManager(this);// 设置布局管理器mRecyclerView.setLayoutManager(manager);// 设置adaptermRecyclerView.setAdapter(chatAdapter);}

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

        @Overridepublic void onFinish(Uri uri, int i) {File file = new File(uri.getPath());ChatBean.ChatItem chatItem = new ChatBean.ChatItem();chatItem.setId((int) System.currentTimeMillis());chatItem.setSendTime(new Date().toString());chatItem.setContent(file.getAbsolutePath());chatItemList.add(chatItem);chatAdapter.setmEntityList(chatItemList);}

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

Android中使用Adapter(适配器)给RecycleView设置数据源相关推荐

  1. Android中关于Adapter的使用(下)BaseAdapter

    我们在前面三篇文章分别介绍了ArrayAdapter和SimpleAdapter的使用,可以先总结一下: 1)ArrayAdapter,是一个跟Array结构对应的Adapter,所以它展示的内容取决 ...

  2. Android中关于Adapter的使用(中)SimpleAdapter

    在前面的两篇文章中,我们讲到了关于ArrayAdapter的使用.用ArrayAdapter来在ListView中展示数据是很不错的,但是很多时候,我们的ListView中,可不只是展示文字,我们还想 ...

  3. Android中的Adapter

    Android是完全遵循MVC模式设计的框架,Activity是Controller,layout是View  因为layout五花八门,很多数据都不能直接绑定上去,所以Android引入了Adapt ...

  4. 【错误记录】Android 中使用 Kotlin 为 EditText 组件设置文本报错 ( Type mismatch. Required:Editable. Found:String )

    文章目录 一.报错信息 二.解决方案 一.报错信息 在 Android 中使用 Kotlin 开发 , EditText 组件如下 : 布局文件 : <EditTextandroid:id=&q ...

  5. Android学习四、Android中的Adapter

    一.Adapter的介绍 An Adapter object acts as a bridge between an AdapterView and the underlying data for t ...

  6. android中段落距离,Android中TextView 行间距和段间距设置

    这里有一篇文章关于设置段落间距(仅供参考):https://blog.csdn.net/yingpaixiaochuan/article/details/77996793 TextView行间距设置 ...

  7. Android中TextView 行间距和段间距设置

    这里有一篇文章关于设置段落间距(仅供参考):https://blog.csdn.net/yingpaixiaochuan/article/details/77996793 TextView行间距设置 ...

  8. Android适配器以及作用,Android Studio:自定义Adapter(适配器)的一些通俗易懂的理解(以一个简单的聊天界面为例)...

    本文是博主对Adapter(适配器)的一些理解,为了加深对Adapter的理解以及记录自己的阶段学习而写,同时也适合初学者阅读,参考本条博客的逻辑进行学习. 第一  先来看看实现这个程序需要需要创建哪 ...

  9. Android 中的adapter和作用以及常见的adapter

    简述: adapter是数据与ui之间的桥梁,它把后台数据与前端ui连接到一起,是一个展示数据的载体. 常用的adapter: BaseAdapter : 基础适配器,对于spinner listvi ...

最新文章

  1. 【原创】大叔经验分享(65)spark读取不到hive表
  2. R卡方检验(CHI-SQUARE TEST)
  3. [转](总结)Linux/UNIX的scp命令用法详解
  4. 表达式目录树(Expression)
  5. django 路径转换器
  6. linux安装了xml怎么编译,linux下libxml库的安装及编译
  7. C语言——小型图书管理系统(课程设计)
  8. 怎么样用计算机才能让电量增多,如何让你的笔记本更省电 这几招你学会能管大用...
  9. BZOJ2038:[2009国家集训队]小Z的袜子——题解
  10. cesium加载倾斜优化_干货 | 6款倾斜摄影裸眼3D采集软件推荐给大家
  11. Tab栏切换效果的制作
  12. TCPUDP测试工具 创建UDP通信设置教程
  13. Android仿饿了么加减控件,小程序仿饿了么弹窗式购物车
  14. VBlog 纯前端博客 2018.5.15更新
  15. 安装mysql详细教程(windows 10安装mysql详细教程新手必看)
  16. 【机器学习】Jackknife,Bootstraping, bagging, boosting, AdaBoosting, Rand forest 和 gradient boosting...
  17. iphone开发中使用动态库(dylib)和动态加载framework (获取iphone的IMSI和设置飞行模式)
  18. docker安装es+mac安装Kibana工具+es查询语法笔记
  19. Pytorch之nn.Conv1d学习个人见解
  20. Beta产品测试报告:那周余嘉熊掌将得队、为了交项目干杯队

热门文章

  1. E1. Rubik‘s Cube Coloring (easy version) 贪心,满二叉树(1300)
  2. int转base64编码
  3. stm32f105vct6例程_STM32F107VCT6 107USB例程USB DEVICE例程
  4. MYSQL中的主表和父表_主表,从表,关联表,父表,子表
  5. unix到底有啥用_观点|什么是Unix以及它为什么这么重要?
  6. mysql 线程缓存_浅析MySQL内存的使用说明(全局缓存+线程缓存)
  7. 一些恶意软件的分析收集整理
  8. BeagleBone Black QNX6.6 BSP中IPL的完善
  9. 2、leetcode1001 最大连续1的个数
  10. 调用枚举接口重写方法提示找不到符号_看看人家那后端API接口写得,那叫一个巴适~...