RecyclerView简单使用(非常详细)

星期六,又是撸代码的一天
作为一个初级都算不上的小白,一步一个脚印的学吧,学一个记一个
今天记录的是RecyclerView

简述

官方解释为:提供一个固定的View让有限的窗口显示一个大数据集。(抄的)
我的理解是,和ListView差不多的东西
ListView是什么,不知道
总之,它可以呈现一系列数据,呈现方式可以根据给的LayoutManager确定

瀑布流(StaggeredGridLayoutManager)
在这里插入图片描述

列表流 (LinearLayoutManager)

在这里插入图片描述

表格流(GridLayoutManager)
在这里插入图片描述

使用方式在下面的 绑定适配器

创建布局

添加 RecyclerView和每个list布局(偏新手向,选择性跳过)

第一步当然是在xml中添加,在Palette中找到RecyclerView,右键Add添加
在这里插入图片描述
又或者在布局中写入Recy选择
在这里插入图片描述
这时需要给RecyclerView添加id

android:id="@+id/recycler"

然后根据开发需求,创建一个xml文件,我这里命名为recy_list.xml
作为单个list的布局,我这里模仿聊天界面做了个xml
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#cccccc"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:paddingRight="20dp"
    android:paddingLeft="20dp">


    <ImageView
        android:id="@+id/head"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:src="@android:mipmap/sym_def_app_icon" />


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:text="小白"
            android:textColor="@color/black"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/news"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textColor="#666666"
            android:text="今天搬了多少砖"/>

    </LinearLayout>

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="end"
        android:textColor="#999999"
        android:textSize="14sp"
        android:text="2021年4月24日\n19:02:50"/>

</LinearLayout>

最后在Activity绑定等等一系列操作

public class MainActivity extends AppCompatActivity {
 private RecyclerView recycler;//创建
  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();//初始化控件方法
    }

    private void initView() {
        recycler = findViewById(R.id.recycler);//绑定RecyclerView
    }

接下来进入重点,适配器

创建适配器

适配器Adapter,可以让开发者自定义recyclerview绑定的数据,通过上面创建的recy_list文件模板来创建一堆item

创建

  1. 创建一个Adapter类
  2. 继承RecyclerView的Adapte
  3. 泛型定义为Adapter的内部类MyHolder

具体是什么我也不知道,一堆复杂的词
大概就是这样

public class Adapter extends RecyclerView.Adapter<Adapter.MyHolder>  {
	@NonNull
    @Override
    public MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull Adapter.MyHolder holder, int position) {

    }

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

然后Alt+回车生成一堆Adapter的接口,同时MyHolder变红,这个不管它,先来看这三方法干啥的

onCreateViewHolder()

  • 创建ViewHolder时的回调函数
  • 传入 ViewGroup parent 和 int viewType
  • 返回 MyHolder

MyHolder是list中每个item
这里使用LayoutInflater布局加载器来加载view,再将view传给内部类MyHolder用于实例化

    private View view;//在外面定义一个view
    
	@NonNull
    @Override
    public Adapter.MyHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
          view = LayoutInflater.from(context)//实例化LayoutInflater
                //传参 刚才创建的recy_list.xml
                .inflate(R.layout.recy_list, parent, false);
        Adapter.MyHolder myHolder= new Adapter.MyHolder(view);
        return myHolder;
    }

(要传contect,挖坑)
来说一下LayoutInflater,菜鸟教程的解释 LayoutInflater(布局服务)
在这里插入图片描述

然后创建一个内部类MyHolder,继承ViewHolder ,在里面加上刚才的xml中的控件并绑定

  public class MyHolder extends RecyclerView.ViewHolder {
        TextView name, news, time;
        ImageView head;

        public MyHolder(View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.name);
            news = itemView.findViewById(R.id.news);
            time = itemView.findViewById(R.id.time);
            head = itemView.findViewById(R.id.head);
        }
    }

这时,第一个方法解决了!!

onBindViewHolder()

  • 绑定ViewHolder时的回调函数
  • 传入 自定义内部类的 holder 和 int position

激动人心的时候到了,终于绑定数据了

position
可以理解为list中item的下标,就像数组一样,每个item都有自己的标识
那数据怎么来,Adapter初始呗
新增构造方法,记得要传context,顺便加上成员变量

private Context context;
private ArrayList<String> nameList,newsList,timeList;

public Adapter(Context context, ArrayList nameList ,ArrayList newsList ,ArrayList timeList) {
        this.context = context;
        this.nameList = nameList;
        this.newsList = newsList;
        this.timeList = timeList;
    }

然后在onBindViewHolder方法中写绑定,根据position来给各个控件设置

 @Override
    public void onBindViewHolder(@NonNull ButViewHolder holder, int position) {
        //将数据和控件绑定
        holder.name.setText(nameList.get(position));
        holder.news.setText(newsList.get(position));
        holder.time.setText(timeList.get(position));
    }

就剩最后一个方法了

getItemCount()

没有传参,需要返回一个int
这个方法是控制创建item的条数,返回的就是条数
我这里直接给其中一个ArrayList的大小即可

 @Override
    public int getItemCount() {
        return nameList.size();
    }

三个方法搞定了,意味着这个简单的Adapter已经写完了
然后就是让RecyclerView绑定Adapter

绑定适配器

在Activity那边加一个方法,或者直接在onCreate里绑定
setRecyclerView();

创建假数据

 ArrayList name = new ArrayList();
        ArrayList news = new ArrayList();
        ArrayList time = new ArrayList();

        for (int i= 0;i<20;i++){
         name.add("小白    " + i);
            news.add("今天搬砖了?");
            time.add("2021年4月24日\n19:17:04");
        }

绑定适配器

	//适配器
 	RecyclerAdapter adapter = new RecyclerAdapter(this,name,news,time);
    //布局
    LinearLayoutManager manager = new LinearLayoutManager(this);
    //设置布局
    recycler.setLayoutManager(manager);
    //设置动画
    recycler.setItemAnimator(new DefaultItemAnimator());
    //设置适配器
    recycler.setAdapter(adapter);

就这样搞定了,这时运行项目就可以了看见本文开头那个列表流的效果了

适配器调整

都写到这了,再写一点吧

区别显示的实现

假如要给某一条item换上不同的背景
这时就需要在onBindViewHolder中修改
通过position,拿到ArrayList的某个数据进行判断
然后设置这个holder的某个控件的属性即可

点击事件

都九点半了,六千字,好累,写目录时加了这个,想删又不想删,还是写完再回家吧
Adapter点击事件的实现,需要声明View.OnClickListener接口
修改Adapter类,声明View.OnClickListener接口,加上一个onClick方法

public class Adapter 
	extends RecyclerView.Adapter<Adapter.MyHolder>
 	implements View.OnClickListener{

	@Override
    public void onClick(View v) {}
}

想要点击不同的item时做一些不同的事,就又又又要修改onBindViewHolder
给itemView设置点击事件

@Override
    public void onBindViewHolder(@NonNull ButViewHolder holder, int position) {
        //将数据和控件绑定
        holder.name.setText(nameList.get(position));
        holder.news.setText(newsList.get(position));
        holder.time.setText(timeList.get(position));
        
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {}
        });
    }

就这样???
如果我想在Activity中设置点击事件呢,比如跳转页面这种情况
添加点击事件接口,传值嘛
你想要什么就传什么,比如我想要点击的item的name,就传个name

 public interface OnItemClickListener {
        void onItemClick(String name);
    }

有接口,就要Activity那边实现,所以Adapter里新增一个方法
同时,接口里的方法需要传给成员变量

private OnItemClickListener mListener;

public void setOnItemClickListener(OnItemClickListener li) {
        mListener = li;
    }

最后在绑定中的点击事件中添加

holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
            	mListener.onItemClick(nameList.get(position));
            }
        });

这么说好像有些别扭
总结就是

  1. Adapter创建点击事件接口
  2. Activity实现接口
  3. 实现后的接口存入Adapter的成员变量
  4. 当点击item时,触发onBindViewHolder中设置的绑定事件
  5. 绑定事件执行的是 Activity中传给成员变量的方法

这时,点击事件已经完成,就这样吧,回家咯!
下次有时间写个加头或尾的文章类似于B站的独占一行方法

在这里插入图片描述不要在意内容!!!

对本文有任何意见或疑问,或者认为其中说法有误,欢迎在评论区留言!!!
最后,转载请注明出处!!

RecyclerView分页加载的流程可以分为以下步骤: 1. 设置LayoutManager:首先需要设置RecyclerView的LayoutManager,可以选择LinearLayoutManager或GridLayoutManager等。 2. 绑定数据源:将数据源绑定到RecyclerView上,可以使用适配器Adapter来实现。 3. 监听滑动事件:RecyclerView提供了OnScrollListener监听滑动事件,在滑动到底部时触发加载更多数据的操作。 4. 加载更多数据:在滑动到底部时,调用接口或从本地数据库中加载更多数据,并将其添加到已有数据的末尾。 5. 更新适配器:完成数据的加载后,需要更新适配器,通知RecyclerView更新UI。 下面是一个简单的分页加载示例代码: ``` public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> { private List<Item> mDataList = new ArrayList<>(); private OnLoadMoreListener mOnLoadMoreListener; private boolean mIsLoading = false; private boolean mIsEnd = false; public void setDataList(List<Item> dataList) { mDataList = dataList; notifyDataSetChanged(); } public void setOnLoadMoreListener(OnLoadMoreListener listener) { mOnLoadMoreListener = listener; } @Override public int getItemCount() { return mDataList.size(); } @Override public void onBindViewHolder(MyViewHolder holder, int position) { // 绑定ViewHolder数据 } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // 创建ViewHolder } @Override public int getItemViewType(int position) { // 获取ItemView类型 } public void setLoading(boolean loading) { mIsLoading = loading; } public void setEnd(boolean end) { mIsEnd = end; } public boolean isLoading() { return mIsLoading; } public boolean isEnd() { return mIsEnd; } public interface OnLoadMoreListener { void onLoadMore(); } public class MyViewHolder extends RecyclerView.ViewHolder { // ViewHolder相关代码 } } ``` 在Activity或Fragment中,需要监听RecyclerView的滑动事件,当滑动到底部时触发加载更多数据的操作: ``` mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); int lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition(); if (!mAdapter.isLoading() && !mAdapter.isEnd() && lastVisibleItemPosition == mAdapter.getItemCount() - 1) { mAdapter.setLoading(true); mAdapter.notifyItemChanged(mAdapter.getItemCount() - 1); mPresenter.loadMoreData(); } } }); ``` 在Presenter中实现加载更多数据的操作: ``` @Override public void loadMoreData() { mApiService.getMoreData(mPage, mPageSize) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer<List<Item>>() { @Override public void onSubscribe(@NonNull Disposable d) { } @Override public void onNext(@NonNull List<Item> items) { if (items.size() < mPageSize) { mAdapter.setEnd(true); } mAdapter.setDataList(items); } @Override public void onError(@NonNull Throwable e) { mAdapter.setLoading(false); // 显示加载失败提示 } @Override public void onComplete() { mAdapter.setLoading(false); } }); } ``` 在Adapter中更新UI: ``` @Override public void onBindViewHolder(MyViewHolder holder, int position) { if (position == getItemCount() - 1 && !isEnd() && isLoading()) { holder.mProgressBar.setVisibility(View.VISIBLE); holder.mTextView.setText(R.string.loading); } else { holder.mProgressBar.setVisibility(View.GONE); holder.mTextView.setText(mDataList.get(position).getTitle()); } } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_layout, parent, false); return new MyViewHolder(itemView); } @Override public int getItemViewType(int position) { if (position == getItemCount() - 1 && !isEnd() && isLoading()) { return ITEM_TYPE_LOADING; } else { return ITEM_TYPE_NORMAL; } } public class MyViewHolder extends RecyclerView.ViewHolder { ProgressBar mProgressBar; TextView mTextView; public MyViewHolder(View itemView) { super(itemView); mProgressBar = itemView.findViewById(R.id.progress_bar); mTextView = itemView.findViewById(R.id.text_view); } } ```
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值