不久前做过一个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的基础巩固以及进阶学习要尽早提上日程,后面也会发布相关的博客。加油,代码人!