首先,要明白RecyclerView是做什么的?其次是为什么要用RecyclerView?这里牵扯到RecyclerView和ListView的区别,这里不废话,大家自行百度即可!

以下示例我用的Android API 29 ,启用了AndroidX。

第一步,添加依赖

创建一个新的工程,在app/build.gradle中的dependencies闭包添加以下内容:

implementation 'com.android.support:appcompat-v7:29.0.0'

  注意这里的‘29.0.0’要和你的 compileSdkVersion 版本号一致。版本号是28,就改为28。

别的不需要改,以下是此时的项目目录以及gradle文件内容

第二步,创建RecyclerView布局

在你的布局文件中添加RecyclerView,切记要为RecyclerView添加id。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_card"
android:layout_width="match_parent"
android:layout_height="match_parent"/> </RelativeLayout>

第三步,为RecyclerView中的item创建一个统一的布局文件

在layout下创建一个名为layout_rv_card的布局文件,文件名命名要和你的实际业务相匹配方便后期查找。

在此布局文件中,可以添加任何你想展示的视图,在这里我们先创建两个TextView为大家展示:

<?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:gravity="center"
android:orientation="horizontal"> <TextView
android:id="@+id/tv_id"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" /> <TextView
android:id="@+id/tv_state"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center" />
</LinearLayout>

  别忘了添加id。

第四步,创建Adapter

  Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带。

  如果之前没有接触过,先跟着做,做完之后就会理解了。

  我们在项目目录下新建一个Java类,取名为CardAdapter。

  然后在CardAdapter中我们创建一个内部类MyViewHolder继承RecyclerView.ViewHolder。

  为什么要创建内部类?

  答:就是为了方便而已,创建在外部也是可以,但是如果项目大了之后,类太多不好区分,而且基本上因为布局的不同ViewHolder也基本不同,不会复用,所以创建在内部即可。

  为什么要使用ViewHolder?

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

接下来,我们在ViewHolder绑定视图文件,同在activity中类似,itemView顾名思义即列表中每一项的视图,每一项都要绑定。

import android.view.View;
import android.widget.TextView; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; /**
* @Author: Messi Mei
* @Date: 2020/8/24 13:46
* @Email: 709909986@qq.com
**/
public class CardAdapter { class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tvId,tvState;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tvId = itemView.findViewById(R.id.tv_id);
tvState = itemView.findViewById(R.id.tv_state);
}
}
}

第五步,完成Adapter

在我们创建的CardAdapter类继承我们创建的内部类MyViewHolder,并重写提供的三个方法:

onCreateViewHolder(),onBindViewHolder(),getItemCount()
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView; /**
* @Author: Messi Mei
* @Date: 2020/8/24 13:46
* @Email: 709909986@qq.com
**/
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.MyViewHolder> { @NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
} @Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { } @Override
public int getItemCount() {
return 0;
} class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tvId,tvState;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
tvId = itemView.findViewById(R.id.tv_id);
tvState = itemView.findViewById(R.id.tv_state);
}
}
}

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

 @NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.layout_rv_card,parent,false);
return new MyViewHolder(view);
}

也可以写为

@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_rv_card,parent,false);
return new MyViewHolder(view);
}

一样的。

5.2为每一项视图,添加数据。

此处holder为你每一项的MyViewHolder对象,position 定位,可以理解为list下标。

@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tvId.setText(position);
holder.tvState.setText(position+position);
}

5.3返回列表大小

@Override
public int getItemCount() {
return 0;
}

第六步,创建数据接口

创建一个List列表(当然也可以是JsonArray),以此为例,我们创一个Card实体类,为List添加该类泛型。

6.1接下来在CardAdapter创建一个带该list的构造器

List<Card> list;

    public CardAdapter(List<Card> list) {
this.list = list;
}

6.2在getItemCount方法中返回该列表大小

  @Override
public int getItemCount() {
return list == null ? 0 : list.size();
}

6.3在onBindViewHolder方法中绑定真实数据

  @Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tvId.setText(list.get(position).getId());
holder.tvState.setText(list.get(position).getState());
}

以下为整体代码(文末有我在使用RecycleView中对Adapter的改进代码,如有需要可以参考):

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 java.util.List; /** @Author: Messi Mei @Date: 2020/8/24 13:46 @Email: 709909986@qq.com */
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.MyViewHolder> {
private List<Card> list; public CardAdapter(List<Card> list) {
this.list = list;
} @NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_rv_card, parent, false);
return new MyViewHolder(view);
} @Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tvId.setText(list.get(position).getId());
holder.tvState.setText(list.get(position).getState());
} @Override
public int getItemCount() {
return list == null ? 0 : list.size();
} static class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tvId, tvState; MyViewHolder(@NonNull View itemView) {
super(itemView);
tvId = itemView.findViewById(R.id.tv_id);
tvState = itemView.findViewById(R.id.tv_state);
}
}
}

第七步,使用RecycleView

在Activity中创建RecycleView对象并绑定视图,创建Adapter对象。

在initData中初始化数据。

package com.mz.myapplication;

import android.os.Bundle;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList;
import java.util.List; public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private CardAdapter cardAdapter;
private List<Card> list; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
} private void initData() {
list = new ArrayList<>();
for (int i = 0; i < 50; i++) {
Card card = new Card();
card.setId(i+1+"");
if (i%2 == 1){
card.setState("在线");
}else{
card.setState("离线");
}
list.add(card);
}
} private void initView() {
recyclerView = findViewById(R.id.rv_card);
cardAdapter = new CardAdapter(list);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(cardAdapter);
}
}

至此,运行即可。

如果你想要更复杂的列表布局,在布局文件中加入相应的视图即可,修改完后记得在ViewHolder中加入、绑定相应的视图,在Adapter中的onBindViewHolder为其添加、绑定数据。

而我更推荐以下这种方式,用set方法去设置Adapter中的数据,更加灵活。

package com.mz.myapplication;

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 java.util.ArrayList;
import java.util.List; /** @Author: Messi Mei @Date: 2020/8/24 13:46 @Email: 709909986@qq.com */
public class Card2Adapter extends RecyclerView.Adapter<Card2Adapter.MyViewHolder> {
private List<Card> list = new ArrayList<>(); public void setList(List<Card> list) {
this.list = list;
  //一定要记得加
notifyDataSetChanged();
} @NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_rv_card, parent, false);
return new MyViewHolder(view);
} @Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.tvId.setText(list.get(position).getId());
holder.tvState.setText(list.get(position).getState());
} @Override
public int getItemCount() {
return list == null ? 0 : list.size();
} static class MyViewHolder extends RecyclerView.ViewHolder {
private TextView tvId, tvState;
MyViewHolder(@NonNull View itemView) {
super(itemView);
tvId = itemView.findViewById(R.id.tv_id);
tvState = itemView.findViewById(R.id.tv_state);
}
}
}
package com.mz.myapplication;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; import java.util.ArrayList;
import java.util.List; public class Main2Activity extends AppCompatActivity {
private RecyclerView recyclerView;
private Card2Adapter card2Adapter;
private List<Card> list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
initView();
initData();
}
private void initData() {
list = new ArrayList<>();
for (int i = 0; i < 50; i++) {
Card card = new Card();
card.setId(i+1+"");
if (i%2 == 1){
card.setState("在线");
}else{
card.setState("离线");
}
list.add(card);
}
card2Adapter.setList(list);
} private void initView() {
recyclerView = findViewById(R.id.rv_card);
card2Adapter = new Card2Adapter();
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(card2Adapter);
}
}

这样你可以在任意位置修改列表中的数据。

Android中RecyclerView用法,一步一步教你如何使用RecyclerView以及带你走过编码中可能会出现的坑~的更多相关文章

  1. ZHS16GBK编码中汉字缺失

    生产中使用ZHS16GBK编码的Oracle数据库,若出现字,则会出现乱码 原因是此字不存在在ZHS16GBK编码中 解决方法可以:此二字结构相同,但是后面的在ZHS16GBK编码中出现

  2. 一步一步了解Cocos2dx 3.0 正式版本开发环境搭建(Win32/Android)

    cocos2d-x 3.0发布有一段时间了,作为一个初学者,我一直觉得cocos2d-x很坑.每个比较大的版本变动,都会有不一样的项目创建方式,每次的跨度都挺大…… 但是凭心而论,3.0RC版本开始 ...

  3. 一步一步打造自己的Android图片浏览器(原创)

    今天我们试着来制作一个自己的Android图片浏览器. 图片浏览器应该具有什么功能呢?鉴于不同的人不同的理解,这里提出一个基本的需求: 搜索手机内的所有图片,展示于一个列表中: 列表中展示的是图片的缩 ...

  4. 一步一步学android控件(之十五) —— DegitalClock & AnalogClock

    原本计划DigitalClock和AnalogClock单独各一篇来写,但是想想,两个控件的作用都一样,就和在一起写一篇了. DegitalClock和AnalogClock控件主要用于显示当前时间信 ...

  5. 一步一步学android控件(之十六)—— CheckBox

    根据使用场景不同,有时候使用系统默认的CheckBox样式就可以了,但是有时候就需要自定义CheckBox的样式.今天主要学习如何自定义CheckBox样式.在CheckBox状态改变时有时需要做一些 ...

  6. 一步一步学android控件(之六) —— MultiAutoCompleteTextView

    今天学习的控件是MultiAutoCompleteTextView . 提到MultiAutoCompleteTextView 我们就自然而然地想到AutoCompleteTextView ,就想知道 ...

  7. Ace教你一步一步做Android新闻客户端(一)

    复制粘贴了那么多博文很不好意思没点自己原创的也说不出去,现在写一篇一步一步教你做安卓新闻客户端,借此机会也是让自己把相关的技术再复习一遍,大神莫笑,专门做给新手看. 手里存了两篇,一个包括软件视图 和 ...

  8. android一步一步实现视频clientapp(一)

    我开发完毕了一个完整的视频clientapp.如今.分享出来.供刚開始学习的人学习參考(大神就不用看了,比較简单,仅供入门),大家相互交流相互学习. 项目有些功能,我时间也不是非常多.仅仅能时不时更新 ...

  9. 一步一步教你在 Android 里创建自己的账号系统(一)

    大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 大家在 ...

随机推荐

  1. ROS 机器人技术 - 广播与接收 TF 坐标

    上次我们学习了 TF 的基本概念和如何发布静态的 TF 坐标: ROS 机器人技术 - TF 坐标系统基本概念 ROS 机器人技术 - 静态 TF 坐标帧 这次来总结下如何发布一个自定义的 TF 坐标 ...

  2. ubuntu的docker安装

    安装docker 安装 介绍一下docker 的中央仓库们 Docker官方中央仓库: https://hub.docker.com/ 因为docker 网站在国外所以访问速度和你的运气有关还有网络. ...

  3. maven install报The forked VM terminated without saying properly goodbye. VM crash or System.exit called

    idea新导入的工程maven install打包报错误:The forked VM terminated without saying properly goodbye. VM crash or S ...

  4. Python os.fsync() 方法

    概述 os.fsync() 方法强制将文件描述符为fd的文件写入硬盘.在Unix, 将调用fsync()函数;在Windows, 调用 _commit()函数.高佣联盟 www.cgewang.com ...

  5. PHP xml_parser_set_option() 函数

    定义和用法 xml_parser_set_option() 函数为 XML 解析设置选项.高佣联盟 www.cgewang.com 如果成功,该函数则返回 TRUE.如果失败,则返回 FALSE. 语 ...

  6. 2020牛客暑假多校训练营 第二场 G Greater and Greater bitset

    LINK:Greater and Greater 确实没能想到做法. 考虑利用bitset解决问题. 做法是:逐位判断每一位是否合法 第一位 就是 bitset上所有大于\(b_1\)的位置 置为1. ...

  7. 账本APP服务器端开发

    账本APP开发 好好学习,天天向上 本文已收录至我的Github仓库DayDayUP:github.com/RobodLee/DayDayUP,欢迎Star,更多文章请前往:目录导航 上一篇文章我们聊 ...

  8. datagrip安装与破解

    datagrip下载 从官网下载的dataGrip可以免费使用30天,如果已经破解过或者付费过的小伙伴可以跳过这个章节.对于未安装软件的小伙伴,博主这里收集了dataGrip的破解教程,扫描底部博主的 ...

  9. [转]new一个对象的过程中发生了什么?

    来自:沉默哥 | 公号 :程序员小乐 链接:cnblogs.com/JackPn/p/9386182.html Java在new一个对象的时候,会先查看对象所属的类有没有被加载到内存,如果没有的话,就 ...

  10. day13. 迭代器与高阶函数

    一.迭代器 """ 能被next调用,并不断返回下一个值的对象,叫做迭代器(对象) 概念: 迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果 ...