The basic use of Android RecyclerView, a must for beginners

Although the use of RecyclerView is cumbersome, it can be divided into various parts and completed one by one, which is very simple. Here is the most basic item click effect (like the one that comes with ListView, there is color feedback when you click ), click to monitor , and long press to monitor . Later, there are requirements that can be based on this, and more implementation details can be added.

1. Resource files (copy and paste directly, focusing on Adapter)

Function: Realize the color change by pressing, see the effect of the picture

 

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!--按压状态item-->
    <item android:state_pressed="true">
        <shape>
            <!-- size用于展示,此处设置不生效 -->
            <size android:width="800dp" android:height="60dp" />
            <!-- 圆角半径 -->
            <corners android:radius="3dp" />
            <!-- 按压背景颜色 -->
            <solid android:color="#AFAFB0" />
        </shape>
    </item>

    <!--正常状态item-->
    <item android:state_pressed="false">
        <shape>
            <size android:width="800dp" android:height="60dp" />
            <corners android:radius="3dp" />
            <!-- 正常背景颜色 -->
            <solid android:color="#E0E0E0" />
        </shape>
    </item>

</selector>

The pictures are all the same, just to simulate different data, different pictures can be used in actual use

 2. Layout (the layout is relatively simple, and the layout should be used where it needs to be used)

androidx.recyclerview.widget.RecyclerView is the control

1.activity_main.xml

<?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="match_parent"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="20dp" />

</LinearLayout>

2.item.xml

<?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="match_parent"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">

        <ImageView
            android:layout_gravity="center_vertical"
            android:id="@+id/img"
            android:layout_marginStart="20dp"
            android:layout_width="40dp"
            android:layout_height="40dp" />

        <TextView
            android:id="@+id/text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="5dp" />

    </LinearLayout>


</LinearLayout>

Three, the point! Here comes the point! Adapter debut

Suggestion: When beginners write Adapter, they must form a step-by-step idea

After writing proficiently, you can copy and save the code of the Adapter, and paste it directly when using it, which is very fast!

See below is the static inner class of RecyclerView

public abstract static class Adapter<VH extends ViewHolder>

Two key points: 1. Customize the adapter to inherit the above Adapter, 2. And in the custom adapter, declare to inherit the inner class of RecyclerView.ViewHolder

It's so long-winded, please see the notes for more details:

MyAdapter.java ( look carefully at the comments, there are detailed explanations )

package com.rivotek.recyclerview;

import android.annotation.SuppressLint;
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 java.util.List;

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.InnerHolder> {

    //从数据源获取的数组存入list,demo的数据源是模拟,在代码中生成
    private List<TextBean> list;

    /**
     * 点击、长按监听三件套
     */
    //1.定义接口
    public interface OnClickListener {
        void onClick(View v, int position);
    }

    public interface OnLongClickListener {
        void onLongClick(View v, int position);
    }

    //2.声明接口
    private OnClickListener onClickListener;
    private OnLongClickListener onLongClickListener;

    //3.set接口
    public void setOnClickListener(OnClickListener onClickListener) {
        this.onClickListener = onClickListener;
    }

    public void setOnLongClickListener(OnLongClickListener onLongClickListener) {
        this.onLongClickListener = onLongClickListener;
    }

    //构造器,只留这一个构造器,将list传入
    public MyAdapter(List<TextBean> list) {
        this.list = list;
    }

    /**
     * 重写三件套,快捷键生成,
     * 观看每个方法的内部代码
     */
    @NonNull
    @Override
    public InnerHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //将XML布局文件,加载到Java代码(和Activity的onCreate()的setContentVIew()作用一样),参数先复制粘贴,感兴趣可去研究传不同参数的效果
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, null, false);
        //设置背景也可以在XML中设置
        view.setBackgroundResource(R.drawable.item_press);
        view.setClickable(true);
        return new InnerHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull InnerHolder holder, @SuppressLint("RecyclerView") int position) {
        //给每一个item设置不同的数据,从list获取
        holder.textView.setText(list.get(position).getText());
        holder.img.setImageResource(list.get(position).getMipId());

        //给成员接口变量(onClickListener,onLongClickListener)进行非空判断,非空触发回调
        if (onClickListener != null) {
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onClickListener.onClick(v, position);
                }
            });
        }
        if (onLongClickListener != null) {
            holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    onLongClickListener.onLongClick(v, position);
                    return true;
                }
            });
        }
    }

    @Override
    public int getItemCount() {
        return list == null ? 0 : list.size();
    }


    /**
     * 内部类,继承RecyclerView.ViewHolder,作用就是声明item中的控件,findViewById
     */
    public class InnerHolder extends RecyclerView.ViewHolder {
        TextView textView;
        ImageView img;

        public InnerHolder(@NonNull View itemView) {
            super(itemView);
            textView = itemView.findViewById(R.id.text);
            img = itemView.findViewById(R.id.img);
        }
    }

}

TextBean.java (just copy and paste)

package com.rivotek.recyclerview;

public class TextBean {
    private String text;

    private int mipId;

    public TextBean(String text, int mipId) {
        this.text = text;
        this.mipId = mipId;
    }

    public int getMipId() {
        return mipId;
    }

    public void setMipId(int mipId) {
        this.mipId = mipId;
    }

    @Override
    public String toString() {
        return "TextBean{" +
                "text='" + text + '\'' +
                ", mipId=" + mipId +
                '}';
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

}

ItemDecor.java (set the distance between items, just copy and paste)

package com.rivotek.recyclerview;

import android.graphics.Rect;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

public class ItemDecor extends RecyclerView.ItemDecoration {
    private int space;

    public ItemDecor(int space) {
        this.space = space;
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        if(parent.getChildLayoutPosition(view) != 0) {
            outRect.top = space;
        }
    }
}

MainActivity.java ( Please read the notes carefully and build according to your own data source )

package com.rivotek.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 android.widget.TextView;
import android.widget.Toast;

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

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "LXP_MainActivity";
    private RecyclerView recyclerView;
    private List<TextBean> list;
    private MyAdapter adapter;
    //数组的id更具自己在mipmap添加的资源为准,有多少图片,下面for循环就加载多少
    private int[] imgArr = new int[]{
            R.mipmap.phone1, R.mipmap.phone2, R.mipmap.phone3, R.mipmap.phone4,
            R.mipmap.phone5, R.mipmap.phone6, R.mipmap.phone7, R.mipmap.phone8,
            R.mipmap.phone9, R.mipmap.phone10, R.mipmap.phone11, R.mipmap.phone12,
            R.mipmap.phone13, R.mipmap.phone14, R.mipmap.phone15, R.mipmap.phone16,
            R.mipmap.phone17, R.mipmap.phone18, R.mipmap.phone19, R.mipmap.phone20
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findView();

        initData();

        setListener();

    }

    private void findView() {
        recyclerView = findViewById(R.id.recyclerview);
    }

    private void initData() {
        //1.数据容器创建
        list = new ArrayList<>();

        //2.将数据放入list容器
        //demo数据来自本地,和for循环在代码运行中生成,数据还可以从网络或者数据库获取
        for (int i = 0; i < 20; i++) {
            TextBean bean = new TextBean("text : " + i, imgArr[i]);
            list.add(bean);
        }

        //3.创建数据适配器adapter
        adapter = new MyAdapter(list);

        //4.关联adapter和布局manager,添加item之间间距
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.addItemDecoration(new ItemDecor(3));

        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(layoutManager);
    }

    private void setListener() {
        //set监听
        adapter.setOnClickListener(new MyAdapter.OnClickListener() {
            @Override
            public void onClick(View v, int position) {
                Log.i(TAG, "点击---position = " + position);
                Toast.makeText(MainActivity.this, "你点击了第:" + position + "项", Toast.LENGTH_SHORT).show();
            }
        });
        adapter.setOnLongClickListener(new MyAdapter.OnLongClickListener() {
            @Override
            public void onLongClick(View v, int position) {
                Log.i(TAG, "长按---position = " + position);
                Toast.makeText(MainActivity.this, "你长按了第:" + position + "项", Toast.LENGTH_SHORT).show();

            }
        });
    }
}

all right! The RecyclerView with complete basic functions is completed.

 

Guess you like

Origin blog.csdn.net/Benlve/article/details/126638325