目录
RecyclerView概述
背景:当我们需要制作例如淘宝商品列表时,数据很多,我们不可能一个一个敲出来,这个时候,我们就应该使用RecyclerView。
RecyclerView是官方在5.0之后新添加的组件,推出用来替代传统的ListView和GridView列表控件。
RecyclerView使用方法
1.布局文件中添加RecyclerView控件
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
2.构造一些数据 一般用数组
这些数据是需要添加在activity_main布局中的
3.添加布局文件,需要创建一个新的布局
在这个布局文件中,我们需要添加的组件就是每一条数据中所需要的控件。
在这个示例中,我们只添加了一个TextView
item_list.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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="100dp">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
4.借助于两个系统提供的类
编写MyAdapter
1.加载布局
2.给控件赋值
3.显示数据的条数
在onCreateViewHolder方法中,我们看到return 的是一个MyViewHolder,为什么不直接return view呢。因为在数据滚动之后,会将屏幕外面的数据进行回收,然后创建下面新的数据,所以MyViewHolder起到的作用是回收利用,节约内存。
缓存中存的内存是当前页面展示的数据数量+1,因为还有一个等待回收的数据。
5.把得到的布局填充到RecyclerView控件
核心代码
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
要点在代码注释和上述解释中都有讲述
综上得到
简单示例一
package com.hnucm.android_04_09;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
List<String> list=new ArrayList<>();//动态扩容
RecyclerView recyclerView;
MyAdapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView=findViewById(R.id.recyclerView);
for(int i=0;i<20;i++){
list.add("这是第"+i+"条数据");
}
myAdapter=new MyAdapter();
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder>{
// 加载布局
@NonNull
@Override
// 数据滚动后,会将屏幕外面的数据回收,然后创建下面的新的数据
// 存的数据是页面的数加1,还有一个等待回收的数据
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_list, parent, false);
MyViewHolder myViewHolder=new MyViewHolder(view);
// 为什么不return一个view,要return一个MyViewHolder
return myViewHolder;
}
// 给布局里面的控件赋值
// position 当前列表的第几条
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.textView.setText(list.get(position));
}
//表示显示数据的条数
@Override
public int getItemCount() {
return list.size();
}
}
//回收利用,节约内存
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView textView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
textView=itemView.findViewById(R.id.textView2);
}
}
}
运行结果
示例二:模仿QQ聊天界面
根据示例一可以改写。
首先,我们需要一个ImageView和三个TextView控件
所以我们的数据可以写在一个类中。
创建实体类Chat
package com.hnucm.android_04_09;
public class Chat {
private String name;
private String content;
private String time;
private int img;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public int getImg() {
return img;
}
public void setImg(int img) {
this.img = img;
}
}
MainACtivity.java
package com.hnucm.android_04_09;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
List<Chat> list=new ArrayList<>();//动态扩容
RecyclerView recyclerView;
MyAdapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView=findViewById(R.id.recyclerView);
for(int i=0;i<20;i++){
Chat chat=new Chat();
chat.setName("name:"+i);
chat.setName("content"+i);
chat.setTime("time"+i);
chat.setImg(R.drawable.a1);
list.add(chat);
}
myAdapter=new MyAdapter();
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder>{
// 加载布局
@NonNull
@Override
// 数据滚动后,会将屏幕外面的数据回收,然后创建下面的新的数据
// 存的数据是页面的数加1,还有一个等待回收的数据
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_list, parent, false);
MyViewHolder myViewHolder=new MyViewHolder(view);
// 为什么不return一个view,要return一个MyViewHolder
return myViewHolder;
}
// 给布局里面的控件赋值
// position 当前列表的第几条
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.nameTV.setText(list.get(position).getName());
holder.contentV.setText(list.get(position).getContent());
holder.timeTV.setText(list.get(position).getTime());
holder.imageView.setBackground(getResources().getDrawable(list.get(position).getImg()));
}
//表示显示数据的条数
@Override
public int getItemCount() {
return list.size();
}
}
//回收利用,节约内存
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView nameTV;
TextView contentV;
TextView timeTV;
ImageView imageView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
nameTV=itemView.findViewById(R.id.textView3);
contentV=itemView.findViewById(R.id.textView4);
timeTV=itemView.findViewById(R.id.textView5);
imageView=itemView.findViewById(R.id.imageView);
}
}
}
改变的地方
RecyclerView一行设置多个列表
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new GridLayoutManager(this,2));
示例
本实例模仿了淘宝的购物界面
Main_Activity代码:
package com.hnucm.c201901020241;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
List<Shop> list =new ArrayList<>();
RecyclerView recyclerView;
MyAdapter myAdapter;
String name[]={"回力男鞋帆布鞋男士高帮百搭蓝色2020春季新款男生鞋子", "回力男鞋夏季初中学生百搭高帮板鞋2021新款韩版",
"回力官方旗舰店帆布鞋女小白百搭运动运动板鞋男","长沙销量过百 超20种颜色回力高帮帆布鞋女",
"回力男鞋2021年新款潮春季男士休闲鞋百搭鞋","Warrior/回力运动跑步鞋 男 舒适透气"};
String buy[]={"3万+人付款","3000+人付款","2000+人付款","2000+人付款","1500+人付款","300+人付款"};
String infor[]={"店铺12万人购买过","图案","商城同款|车缝线|硫化","英伦风|硫化","帆布|系带","青春潮流风"};
String price[]={"¥169","¥89","¥120","¥99","¥93","¥50"};
int img[]={R.drawable.a1,R.drawable.a2,R.drawable.a3,R.drawable.a4,R.drawable.a5,R.drawable.a6};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=findViewById(R.id.textView6);
recyclerView=findViewById(R.id.recyclerView);
for(int i=0;i<6;i++){
Shop shop=new Shop();
shop.setName(name[i]);
shop.setBuy(buy[i]);
shop.setInfor(infor[i]);
shop.setPrice(price[i]);
shop.setImg(img[i]);
list.add(shop);
}
myAdapter=new MyAdapter();
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new GridLayoutManager(this,2));
}
public class MyAdapter extends RecyclerView.Adapter<MyViewHolder>{
@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.shop_list,parent,false);
MyViewHolder myViewHolder=new MyViewHolder(view);
return myViewHolder;
}
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
holder.nameTV.setText(list.get(position).getName());
holder.buyTV.setText(list.get(position).getBuy());
holder.inforTV.setText(list.get(position).getInfor());
holder.priceTV.setText(list.get(position).getPrice());
holder.imageView.setBackground(getResources().getDrawable(list.get(position).getImg()));
}
@Override
public int getItemCount() {
return list.size();
}
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView nameTV;
TextView buyTV;
TextView inforTV;
TextView priceTV;
ImageView imageView;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
nameTV=itemView.findViewById(R.id.textView);
buyTV=itemView.findViewById(R.id.textView4);
inforTV=itemView.findViewById(R.id.textView2);
priceTV=itemView.findViewById(R.id.textView3);
imageView=itemView.findViewById(R.id.imageView4);
}
}
}
shop类
package com.hnucm.c201901020241;
public class Shop {
private String name;
private String infor;
private String price;
private String buy;
private int img;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInfor() {
return infor;
}
public void setInfor(String infor) {
this.infor = infor;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getBuy() {
return buy;
}
public void setBuy(String buy) {
this.buy = buy;
}
public int getImg() {
return img;
}
public void setImg(int img) {
this.img = img;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:background="#FAFAFA"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
app:srcCompat="@drawable/c1" />
<EditText
android:id="@+id/editTextTextPersonName2"
android:layout_width="230dp"
android:layout_height="40dp"
android:layout_marginLeft="10dp"
android:focusable="false"
android:background="@drawable/bg_border"
android:ems="10"
android:hint=" 回力"
android:inputType="textPersonName" />
<ImageView
android:id="@+id/imageView3"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="20dp"
app:srcCompat="@drawable/c3" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginLeft="20dp"
app:srcCompat="@drawable/c2" />
</LinearLayout>
<TextView
android:id="@+id/textView5"
android:layout_width="40dp"
android:layout_height="30dp"
android:layout_marginTop="24dp"
android:textColor="#FF5000"
android:text="综合"
app:layout_constraintEnd_toStartOf="@+id/textView6"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout" />
<TextView
android:id="@+id/textView7"
android:layout_width="40dp"
android:layout_height="30dp"
android:text="价格"
app:layout_constraintEnd_toStartOf="@+id/imageView5"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView6"
app:layout_constraintTop_toTopOf="@+id/textView6" />
<TextView
android:id="@+id/textView6"
android:layout_width="40dp"
android:layout_height="30dp"
android:text="销量"
app:layout_constraintEnd_toStartOf="@+id/textView7"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView5"
app:layout_constraintTop_toTopOf="@+id/textView5" />
<TextView
android:id="@+id/textView8"
android:layout_width="40dp"
android:layout_height="30dp"
android:text="筛选"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/imageView5"
app:layout_constraintTop_toTopOf="@+id/textView7" />
<ImageView
android:id="@+id/imageView5"
android:layout_width="40dp"
android:layout_height="30dp"
android:layout_marginBottom="4dp"
app:layout_constraintBottom_toBottomOf="@+id/textView8"
app:layout_constraintEnd_toStartOf="@+id/textView8"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/textView7"
app:srcCompat="@drawable/c4" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="396dp"
android:layout_height="500dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView7" />
</androidx.constraintlayout.widget.ConstraintLayout>
实现效果:
Android第一讲笔记(常用控件以及线性布局)
Android第二讲笔记(约束布局ConstraintLayout)
Android第三讲笔记(Activity简单操作)