Android---RecyclerView的使用

1、步骤

/**
 * recyclerView使用说明
 * 1、导入依赖包
 *       在build.gradle(module) 中的dependencies 添加 implementation 'androidx.recyclerview:recyclerview:1.2.1'
 * 2、在主布局中创建一个recyclerView控件
 * 3、创建Item布局
 * 4、创建Bean类,存放item中的属性值(可根据实际情况自定义属性内容)
 * 5、创建一个Adapter类(通过List将数据和recyclerView进行绑定,并为recyclerView的item自定义监听方法)
 * 6、在主Activity中添加数据,并进行绑定操作
 */

2、实例demo

  1. 导入依赖包
//在build.gradle(Module)中书写
dependencies {
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
}
  1. 在主布局创建recyclerView控件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".recyclerView.RecyclerViewActivity">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
  1. 创建item布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/recycler_v"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="30sp"/>

</LinearLayout>
  1. 创建爱你Bean类
package com.example.viewexample.recyclerView;

public class RecyclerViewBean {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

  1. 创建Adapter类
package com.example.viewexample.recyclerView;

import android.content.Context;
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 com.example.viewexample.R;
import com.example.viewexample.listView.MyAdapter;

import java.util.List;

/**
 * 此处使用ViewHolder,用于性能优化。
 */
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
    private List<RecyclerViewBean> data;
    private Context mContext;

    //添加构造方法
    public RecyclerViewAdapter(List<RecyclerViewBean> data, Context context) {
        this.data = data;
        mContext = context;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //这两种创建view的方式有什么不一样?
        //创建view的方式一
        //View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_view, parent, false);
        //创建view的方式二
        /**
         * 将inflate的(,,null)写成parent,会出现以下错误
         *      java.lang.IllegalStateException
         *      ViewHolder views must not be attached when created
         *      Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot)
         *      解决方案已给出:LayoutInflater.inflate(..,boolean attachToRoot)中的这个boolean不为true
         *      查看源码,此处判断为 attachToRoot = (root!=null),即root为null,此处返回false
         */
        View inflate = View.inflate(mContext, R.layout.recycler_view, null);
        return new MyViewHolder(inflate);
    }

    //绑定数据,传入的参数中有一个MyViewHolder
    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.tv.setText(data.get(position).getName());
    }

    //显示多少个item,为了更严谨做个判空处理。
    @Override
    public int getItemCount() {
        return data == null ? 0 : data.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView tv;
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tv = itemView.findViewById(R.id.recycler_v);
            //为textView绑定点击监听
            tv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnRecyclerItemClickListener != null){
                        mOnRecyclerItemClickListener.onRecyclerItemClick(getAdapterPosition());
                    }
                }
            });
        }
    }

    //在adapter中为item添加监听,方便使用。(recyclerView没有item的监听方法,为item自定义监听方法)
    public interface OnRecyclerItemClickListener{
        void onRecyclerItemClick(int position);
    }
    //创建全局变量
    private OnRecyclerItemClickListener mOnRecyclerItemClickListener;

    //创建一个监听
    public void setOnRecyclerItemClickListener(OnRecyclerItemClickListener listener){
        mOnRecyclerItemClickListener = listener;
    }
}
  1. 在MainActivity书写实际代码
package com.example.viewexample.recyclerView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.example.viewexample.R;

import java.util.ArrayList;
import java.util.List;

/**
 * recyclerView使用说明
 * 1、导入依赖包
 *       在build.gradle(module) 中的dependencies 添加 implementation 'androidx.recyclerview:recyclerview:1.2.1'
 * 2、在主布局中创建一个recyclerView控件
 * 3、创建Item布局
 * 4、创建Bean类,存放item中的属性值(可根据实际情况自定义属性内容)
 * 5、创建一个Adapter类(通过List将数据和recyclerView进行绑定,并为recyclerView的item自定义监听方法)
 * 6、在主Activity中添加数据,并进行绑定操作
 */
public class RecyclerViewActivity extends AppCompatActivity {
    private static final String TAG = "RecyclerViewActivity";
    private List<RecyclerViewBean> data = new ArrayList<>();
    private RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recycler_view);
        //为list添加数据
        for (int i = 0; i < 100; i++) {
            RecyclerViewBean bean = new RecyclerViewBean();
            bean.setName("RecyclerView子元素"+i);
            data.add(bean);
        }
        //获取recyclerView控件,并通过adapter将数据与控件绑定
        mRecyclerView = findViewById(R.id.rv);
        //需要给recyclerView添加一个布局
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(linearLayoutManager);
        //通过adapter将数据和recyclerView进行绑定
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(data,this);
        mRecyclerView.setAdapter(adapter);
        adapter.setOnRecyclerItemClickListener(new RecyclerViewAdapter.OnRecyclerItemClickListener() {
            @Override
            public void onRecyclerItemClick(int position) {
                Log.d(TAG, "onRecyclerItemClick: "+position);
            }
        });
    }
}

3、效果图

在这里插入图片描述

4、java.lang.IllegalStateException错误

        /**
         * 将inflate的(,,null)写成parent,会出现以下错误
         *      解决方案已给出:LayoutInflater.inflate(..,boolean attachToRoot)中的这个boolean不为true
         *      查看源码,此处判断为 attachToRoot = (root!=null),即root为null,此处返回false
         */
    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View inflate = View.inflate(mContext, R.layout.recycler_view, parent);
        return new MyViewHolder(inflate);
    }

D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.viewexample, PID: 9482
    java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot)
        at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7297)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6416)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:4012)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4578)
        at android.view.View.layout(View.java:23141)
        at android.view.ViewGroup.layout(ViewGroup.java:6412)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:23141)
        at android.view.ViewGroup.layout(ViewGroup.java:6412)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:23141)
        at android.view.ViewGroup.layout(ViewGroup.java:6412)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:530)
        at android.view.View.layout(View.java:23141)
        at android.view.ViewGroup.layout(ViewGroup.java:6412)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at android.view.View.layout(View.java:23141)
        at android.view.ViewGroup.layout(ViewGroup.java:6412)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
        at android.view.View.layout(View.java:23141)
        at android.view.ViewGroup.layout(ViewGroup.java:6412)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:798)
        at android.view.View.layout(View.java:23141)
        at android.view.ViewGroup.layout(ViewGroup.java:6412)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3681)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3140)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2126)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8649)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1037)
        at android.view.Choreographer.doCallbacks(Choreographer.java:845)
        at android.view.Choreographer.doFrame(Choreographer.java:780)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1022)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:201)
        at android.os.Looper.loop(Looper.java:288)
        at android.app.ActivityThread.main(ActivityThread.java:7822)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
I/Process: Sending signal. PID: 9482 SIG: 9

5、自定义监听

    //在adapter中为item添加监听,方便使用。(recyclerView没有item的监听方法,为item自定义监听方法)
    public interface OnRecyclerItemClickListener{
        void onRecyclerItemClick(int position);
    }
    //创建全局变量
    private OnRecyclerItemClickListener mOnRecyclerItemClickListener;

    //创建一个监听
    public void setOnRecyclerItemClickListener(OnRecyclerItemClickListener listener){
        mOnRecyclerItemClickListener = listener;
    }

	//借助了点击监听来完成对RecyclerView的item的自定义监听
   public class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView tv;
        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            tv = itemView.findViewById(R.id.recycler_v);
            //为textView绑定点击监听
            tv.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mOnRecyclerItemClickListener != null){
                        mOnRecyclerItemClickListener.onRecyclerItemClick(getAdapterPosition());
                    }
                }
            });
        }
    }

6、方法流程图

图示:RecyclerViewAdapter_onCreateViewHolder如下
RecyclerViewAdapter_onCreateViewHolder
图示:RecyclerViewActivity_onCreate如下
RecyclerViewActivity_onCreate

7、官方文献

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万卷书情似故人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值