首先,要明白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. c++输出左右对齐设置

    #include<iostream> int main(){ using std::cout; cout.setf(std::ios::left); int w = cout.width( ...

  2. PHP boolval() 函数

    boolval 函数用于获取变量的布尔值.高佣联盟 www.cgewang.com 版本要求:PHP 5 >= 5.5.0, PHP 7. 语法 boolean boolval ( mixed ...

  3. C/C++编程笔记:C语言开发球球大作战(源码分享),你想试试吗?

    游戏背景 <球球大作战>是Superpop一款自主研du发的免费手机网络游戏. 以玩家间的实时互动PK产生游戏乐趣为设计宗旨,通过简单的规则将玩家操作直接转化为游戏策略,体验智谋碰撞的战斗 ...

  4. SeekBar滑动时,progress数值不连续

    问题描述 logcat 你是否也遇见过这样的情况,SeekBar的进度不连续 这是我在做一个编辑图片的APP时,观察我打印的log,发现progress不是连续的 这时候可能就有人问:是你代码写的不对 ...

  5. “随手记”开发记录day14

    今天继续昨天没有完成的增加“修改”功能.对于已经添加的记账记录,长按可以进行修改和删除的操作. 但是今天并没有完成……

  6. Python面向对象,站在更高的角度来思考

    开篇 面向过程编程和面向对象编程是两种基本的编程思想. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去 ...

  7. js 事件对象相关笔记

    事件对象     event就是一个事件对象 写到我们的监听函数的括号里面 当形参来看     事件对象只有有了事件才存在,他是系统给我们自动创建的 不需要我们传递参数     事件对象是我们事件的一 ...

  8. GhostNet:more features from cheap operation

  9. 2020-05-27:SpringCloud用了那些组件?分布式追踪链怎么做的?熔断器工作原理?

    福哥答案2020-05-27: SpringCloud分布式开发五大组件详解服务发现——Netflix Eureka客服端负载均衡——Netflix Ribbon断路器——Netflix Hystri ...

  10. C#LeetCode刷题之#27-移除元素(Remove Element)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3624 访问. 给定一个数组 nums 和一个值 val,你需要原 ...