RecyclerView的使用
RecyclerView 是 Android L 新增的控件,被称为 ListView 的继任者
RecyclerView 概述
在开发 RecyclerView 时充分考虑了扩展性,因此用它可以创建想到的任何种类的的布局。但在使用上也稍微有些不便,比如使用步骤更加复杂,特别是一些控制点击、长压事件需要自己完成。使用 RecyclerView 开发的项目结构大致如下图所示:
从上图可以看到,要使用 RecyclerView,需要先了解清楚 LayoutManager 和 Adapter 元素,分别如下:
- LayoutManager:用来确定每一个 item 如何进行排列摆放,何时展示和隐藏。回收或重用一个 View 的时候,LayoutManager 会向适配器请求新的数据来替换旧的数据,这种机制避免了创建过多的 View 和频繁的调用 findViewById 方法。目前 RecyclerView 库提供了如下三种子 Manager:
- LinearLayoutManager:展示了水平或者垂直的滚动列表,相当于 ListView,但是没有页眉和页尾。
- GridLayoutManager:在网格中展示条目,相当于 GridView。
- StaggeredGridLayoutManager: 在错落的网格中展示条目,比如常见的瀑布流。
定义布局文件
Activity 中加入 RecyclerView
<?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=".RicyclerView">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/ReclyclerViewTest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
定义每个 Item 子项
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/icon_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginRight="6dp"
android:contentDescription="null"
android:maxWidth="20dp"
android:maxHeight="20dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/title_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/icon_img"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:text="Title"
android:textSize="20sp" />
</LinearLayout>
Tip.
- Item 每个子项的父布局,及 xml 最开头的 Layout,一定要是 Wrap_content,不然会出现每个 Item 条目占满一页的情况
编写适配器(Adapter)
示例代码
package top.zzgpro.calculate.Adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import org.w3c.dom.Text;
import java.util.ArrayList;
import top.zzgpro.calculate.ListItem.RecyclerItemData;
import top.zzgpro.calculate.R;
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private ArrayList<RecyclerItemData> mDatas = null;
private LayoutInflater mInflater = null;
public RecyclerViewAdapter(Context context, ArrayList<RecyclerItemData> datas) {
this.mDatas = datas;
this.mInflater = LayoutInflater.from(context);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view=this.mInflater.inflate(R.layout.recycler_item,parent,false);
ViewHolder viewHolder=new ViewHolder(view);
return viewHolder;
}
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
RecyclerItemData name = mDatas.get(position);
holder.setImageView(name.getImage());
holder.setTitle(name.getName());
// holder.setCentent(name.getName());
}
@Override
public int getItemCount() {
return mDatas == null ? 0 : mDatas.size();
}
class ViewHolder extends RecyclerView.ViewHolder{
private TextView title;
private ImageView imageView;
public TextView getTitle() {
return title;
}
public void setTitle(String text) {
this.title.setText(text);
}
public TextView getCentent() {
return centent;
}
public void setCentent(String centent) {
this.centent.setText(centent);
}
public void setImageView(int id){
this.imageView.setImageResource(id);
}
private TextView centent;
public ViewHolder(@NonNull View itemView) {
super(itemView);
this.title=(TextView) itemView.findViewById(R.id.title_tv);
// this.centent=(TextView) itemView.findViewById(R.id.content_tv);
this.imageView=(ImageView) itemView.findViewById(R.id.icon_img);
}
}
}
关键方法
- 类要继承 RecyclerView.Adapter 类
- 要重写三个方法
onCreateViewHolder
目的:创建新 View,被 LayoutManager 所调用
onBindViewHolder
目的:将数据与界面进行绑定的操作
getItemCount
目的:获取数据数量
ViewHolder 内部类
示例代码
class ViewHolder extends RecyclerView.ViewHolder{
private TextView title;
private ImageView imageView;
public TextView getTitle() {
return title;
}
public void setTitle(String text) {
this.title.setText(text);
}
public TextView getCentent() {
return centent;
}
public void setCentent(String centent) {
this.centent.setText(centent);
}
public void setImageView(int id){
this.imageView.setImageResource(id);
}
private TextView centent;
public ViewHolder(@NonNull View itemView) {
super(itemView);
this.title=(TextView) itemView.findViewById(R.id.title_tv);
// this.centent=(TextView) itemView.findViewById(R.id.content_tv);
this.imageView=(ImageView) itemView.findViewById(R.id.icon_img);
}
}
- 定义内部类,继承自 RecyclerView.ViewHolder
- 创建构造方法,调用父类构造方法
- 在 Adapter 中,继承 RecyclerView.Adapter<自定义 ViewHolder>
- 构造自己的逻辑
编写 Activity 后台代码
示例代码
package top.zzgpro.calculate;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.os.Bundle;
import java.util.ArrayList;
import top.zzgpro.calculate.Adapter.RecyclerViewAdapter;
import top.zzgpro.calculate.ListItem.RecyclerItemData;
public class RicyclerView extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ricycler_view);
RecyclerView recyclerView=(RecyclerView) findViewById(R.id.ReclyclerViewTest);
LinearLayoutManager linearLayoutManager=new LinearLayoutManager(this);
//设置横向还是纵向
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
// linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(linearLayoutManager);
RecyclerViewAdapter recyclerViewAdapter=new RecyclerViewAdapter(this,initDatas());
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(recyclerViewAdapter);
}
private ArrayList<RecyclerItemData> initDatas() {
ArrayList<RecyclerItemData> mDatas = new ArrayList<>();
mDatas.add(new RecyclerItemData(R.mipmap.meixi,"梅西"));
mDatas.add(new RecyclerItemData(R.mipmap.cluo,"C罗"));
mDatas.add(new RecyclerItemData(R.mipmap.guadi,"瓜迪奥拉"));
mDatas.add(new RecyclerItemData(R.mipmap.debu,"德布罗意"));
mDatas.add(new RecyclerItemData(R.mipmap.xiaobai,"小白"));
mDatas.add(new RecyclerItemData(R.mipmap.sunke,"孙可"));
return mDatas;
}
}
- 使用 findviewbyid 找到 RecyclerView 的控件
- 创建一个 LayoutManager
- 将 LayoutManager 设置到 RecyclerView
- 实例化自定义的 RecyclerAdapter
- 传入数据
- 将 Adapter 注册到 RecyclerView
效果
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 小周の代码之路!
评论