首页 > 其他分享 >Android中使用Adapter(适配器)给RecycleView设置数据源

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

时间:2023-03-23 11:05:55浏览次数:43  
标签:return String 数据源 适配器 RecycleView private void RecyclerView public


场景

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>

注:

关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

创建RecyclerView

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

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

 

Android中使用Adapter(适配器)给RecycleView设置数据源_android

最终要实现的效果是点击下面的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.RecyclerView
        android: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" />

    <RelativeLayout
        android: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">

        <ImageView
            android: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对应

 

Android中使用Adapter(适配器)给RecycleView设置数据源_Android_02

创建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">

    <TextView
        android: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;

    @NonNull
    private 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;
    }

    @NonNull
    public 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
    @Override
    public 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为下标。

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

重写getItemCount方法

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

@Override
    public 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
    @Override
    public 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);
    }

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

    @Override
    public 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方法中初始化

@Override
    protected 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);
        // 设置adapter
        mRecyclerView.setAdapter(chatAdapter);
    }

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

@Override
        public 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设置数据源_xml_03

 

 

标签:return,String,数据源,适配器,RecycleView,private,void,RecyclerView,public
From: https://blog.51cto.com/BADAOLIUMANGQZ/6144499

相关文章

  • 4-springboot多数据源配置报错Cause: java.lang.IllegalArgumentException: jdbcUrl i
    springboot2.0版本以上的多数据源配置改成:spring.datasource.refunddb.url=jdbc:mysql://refund地址spring.datasource.refunddb.username=uatspring.datasource.refundd......
  • 设计模式之适配器模式
    前提:适配器模式有三种-类、对象、接口适配器。(暂时没想到更啥,先更着以前写的适配器模式吧。。。)使用场景:假设手上有一个ps2插头的设备,但主机对外是usb,这时候需要弄个......
  • SpringBoot多数据源配置以及事务处理
    注:本文转自:https://www.toutiao.com/article/7204651968885686787/?log_from=4fd44355ebbb6_1679021148713背景在高并发的项目中,单数据库已无法承载大数据量的访问,因此需......
  • SpringMVC中的适配器模式
    目录一、适配器模式在SpringMVC框架应用的源码剖析二、模拟适配器的应用三种处理器适配器接口适配器对于三种不同处理器的适配CustomDispatchServlet测试三、分析适配器3.1......
  • Day05-设计模式之适配器模式
    设计模式之适配器模式适配器模式介绍适配器模式(AdapterPattern)是将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作......
  • MybatisPlus(十三) 配置多数据源(一)
    一、引入dynamic-datasource-spring-boot-starter<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifact......
  • 前端设计模式——适配器模式
    适配器模式(AdapterPattern):将一个类的接口转化为客户端所期望的接口,使得原本不兼容的类可以一起工作。在前端开发中,可以使用适配器模式来处理不同浏览器之间的兼容性问题。......
  • aop+自定义注解实现数据源切换
    pom.xml依赖<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"......
  • springboot-整合mysql多数据源配置
    一、springboot+mybatis使用分包方式整合1、application.yml配置文件server:port:8080#启动端口spring:datasource:db1:#数据源1jdbc-url:j......
  • 数据源配置
    spring:#数据源配置datasource:type:com.alibaba.druid.pool.DruidDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://127.0.0.......