安卓RecycleView实现九宫格和点击事件(详解)

不久前做过一个App需要实现的功能比较多,因此打算做成一个九宫格的形式,把主要功能放到一个九宫格里来实现,这里用到的是RecycleView。要求是每个子项的上方是功能图标下方是功能名称,并且给每一个子项实现一个不同的点击事件,具体介绍如下。

一、效果图

在这里插入图片描述

在这里插入图片描述

二、实现思路与代码

2.1 添加依赖和控件

首先需要在项目的build.gradle添加相应的依赖库,在dependencies闭包中添加如下内容。

 implementation 'com.android.support:recyclerview-v7:29.0.0'

其中29表示当前你所用SDK的版本号,注意使用时要与你当前的版本号一致。
然后在Activity中添加RecycleView控件。

  <!--核心功能-->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_central"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/ll_user"
        android:layout_centerInParent="true">

    </androidx.recyclerview.widget.RecyclerView>

2.2 定义主要功能类Central

由于我们这里的每一个子项需要一张图片和一段文字,因此在自定义Central类中定义两个属性值,其中Central_text对应功能名称,Central_icon表示功能图标对应的资源id,创建构造函数将属性赋值,并用getter和setter进行封装。

public class Central {
    
    
    String Central_text;
    int Central_icon;
    public Central(String central_text, int central_icon) {
    
    
        Central_text = central_text;
        Central_icon = central_icon;
    }
    public void setCentral_text(String central_text) {
    
    
        Central_text = central_text;
    }
    public void setCentral_icon(int central_icon) {
    
    
        Central_icon = central_icon;
    }
    public String getCentral_text() {
    
    
        return Central_text;
    }
    public int getCentral_icon() {
    
    
        return Central_icon;
    }
}

2.3 指定布局central_item.xml

接下来需要给每一个子项指定自定义布局,在layout目录下新建布局文件central_item.xml,代码如下:

<?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"
    android:layout_gravity="center"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:orientation="vertical"
        android:gravity="center_vertical"
        android:layout_marginLeft="10dp">
    <ImageView
        android:id="@+id/iv_central_icon"
        android:layout_width="55dp"
        android:layout_height="25dp"
        android:src="@drawable/helper_icon"/>
    <TextView
        android:id="@+id/tv_central_text"
        android:gravity="center"
        android:layout_width="55dp"
        android:layout_height="20dp"
        android:textSize="13sp"
        android:text="健康打卡"/>
    </LinearLayout>
</LinearLayout>

其中ImageView表示功能图标,TextView表示功能名称。

2.4 创建自定义适配器CentralAdapter

接下来也是实现的关键一步,新建CentralAdapter继承自RecyclerView.Adapter,其中的泛型指定为CentralAdapter.ViewHolder,ViewHolder是定义的一个内部类,用来获取Image View、TextView的实例。这里我贴上主要代码。

public class CentralAdapter extends RecyclerView.Adapter<CentralAdapter.ViewHolder> {
    
    
    private  List<Central> mCentral;
    private Context context;


    public CentralAdapter(List<Central> mCentral,Context context) {
    
    
        this.mCentral = mCentral;
        this.context=context;
    }

    static class ViewHolder extends RecyclerView.ViewHolder{
    
    
        View centralView;
        ImageView iv_central_icon;
        TextView tv_central_text;
        
        public ViewHolder(@NonNull View view) {
    
    
            super (view);
            centralView=view;
            iv_central_icon=view.findViewById (R.id.iv_central_icon);
            tv_central_text=view.findViewById (R.id.tv_central_text);
            ll_Background=view.findViewById (R.id.ll_background);
        }
    }
    @NonNull
    @Override
    public CentralAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    
    
        View view= LayoutInflater.from (parent.getContext ()).
                inflate (R.layout.central_item,parent,false);
        ViewHolder holder=new ViewHolder (view);


        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull CentralAdapter.ViewHolder holder, final int position) {
    
    

        final Central central=mCentral.get (position);

        holder.iv_central_icon.setImageResource (central.getCentral_icon ());
        holder.tv_central_text.setText (central.getCentral_text ());
        holder.centralView.setOnClickListener (new View.OnClickListener () {
    
    
            @Override
            public void onClick(View view) {
    
    
               Intent intent=new Intent ();
                AlertDialog.Builder builder=new AlertDialog.Builder (context);
                builder.setTitle ("你点击了");
                builder.setCancelable (true);

                switch (position){
    
    
                    //健康打卡
                    case 0:
                   /**
                      *这里写对应的点击事件
                      */
                        break;
                    //个人轨迹
                    case 1:
                        break;
                    //澡堂预约
                    case 2:
                        break;
                    //风险等级
                    case 3:
                        break;
                    //请假申请
                    case 4:
                        break;
                    //危险区域
                    case 5:
                        break;
                    //领取绿码
                    case 6:
                        break;
                    //防疫导航
                    case 7:
                        break;
                }
                  builder.setMessage (central.getCentral_text ());
                  builder.show ();
            }
        });
    }
    @Override
    public int getItemCount() {
    
    
        return mCentral.size ();
    }
}

注意在Adapter中有两个字段,子项集合和上下文context,这里通过构造函数赋值,上下文context为后续的事件处理需要。
代码中onCreateViewHolder()方法是用来创建ViewHolder实例的,加载central_item布局并通过构造函数将布局传入。onBindViewHolder()方法是用于对RecycleView子项的数据进行赋值(在子项被滚动到屏幕内时执行),通过position参数获取当前项的实例,然后将数据设置到ViewHolder的ImageView和textView中。getItemCount()会告诉RecycleView有多少子项,返回数据的长度。

2.5 Activity中实现

2.5.1 定义全局变量

    public List<Central> centralList = new ArrayList<> ();
    RecyclerView recyclerView;

2.5.2 初始化Central类集合

这一步利用构造函数将每一个Central初始化并添加到Central集合中,我把他写在了一个函数方法中,需要在onCreate()方法中调用

  /**
     *初始化核心功能数组
     */
    private void initCentral() {
    
    
        Central central_clock = new Central (getString (R.string.central_health_clock), R.mipmap.central_health_clock);
        centralList.add (central_clock);
        Central central_trail = new Central (getString (R.string.central_trail_mine), R.mipmap.central_trail_mine);
        centralList.add (central_trail);
        Central central_bath = new Central (getString (R.string.central_bespeak_bath), R.mipmap.central_bespeak_bath);
        centralList.add (central_bath);
        Central central_levelMap1 = new Central (getString (R.string.central_level_map),R.mipmap.central_level_map);
        centralList.add (central_levelMap1);
        Central central_out = new Central (getString (R.string.central_bespeak_out), R.mipmap.central_bespeak_out);
        centralList.add (central_out);
        Central central_danger = new Central (getString (R.string.central_area_danger), R.mipmap.central_area_danger);
        centralList.add (central_danger);
        Central central_qr = new Central (getString (R.string.central_health_qr), R.mipmap.central_health_qr);
        centralList.add (central_qr);
        Central central_navigation=new Central (getString (R.string.central_navigation_pre),R.mipmap.central_navigation_pre);
        centralList.add (central_navigation);

    }

2.5.3 RecycleView适配

这里总共有八个功能,要求将八个功能分成两行展示,这一步在初始化数组之后执行,实现代码如下。


        recyclerView = ((RecyclerView) findViewById (R.id.rv_central));
        StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager
                (2, StaggeredGridLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager (layoutManager);
        CentralAdapter centralAdapter = new CentralAdapter (centralList, getContext ());
        recyclerView.setAdapter (centralAdapter);

    

其中创建了一个StaggeredGridLayoutManager的实例,通过构造函数传入了两个参数,第一个参数用于指定布局的列数,第二个参数用于指定布局的排列方向。这里我指定了列数为两列,横向排列。如果要实现3x3的排列,将第一个参数改成3即可。
到这里就完成了。

三、结语

对于以上大家有什么问题欢迎评论指正!如果有需要,后续我会上传源代码。
另外随着编程量的增加,代码的规范性和可读性逐渐提升了,后续可能会对之前发布的博客进行一次更新,另外Java的基础巩固以及进阶学习要尽早提上日程,后面也会发布相关的博客。加油,代码人!

猜你喜欢

转载自blog.csdn.net/qq_44706002/article/details/112688039