如何在 RecyclerView Java 中创建 OnClick 事件
Posted
技术标签:
【中文标题】如何在 RecyclerView Java 中创建 OnClick 事件【英文标题】:How to Make an OnClick Event in a RecylcerView Java 【发布时间】:2021-04-10 01:18:16 【问题描述】:我在尝试在我的 CategoriesAdapter.Java 中创建 OnClickListener 时遇到问题
我正在尝试做的事情的简短摘要:我正在尝试构建应用程序的一部分,以显示某些业务类型的“类别”,即技术、金融等
我想确保用户能够点击一个类别并基本上将他们带到所需的类别; "用户点击'财务'用户转到'财务'类别。
如果你能帮助我,我会把我的代码贴在这里。
CategoriesAdapter.Java
package com.example.tencil.HelperClasses.HomeAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.tencil.R;
import com.example.tencil.User.CategoriesHelperClass;
import java.util.ArrayList;
import static android.content.ContentValues.TAG;
public class CategoriesAdapter extends RecyclerView.Adapter<CategoriesAdapter.ViewHolder>
ArrayList<CategoriesHelperClass> categories;
private ArrayList<CategoriesHelperClass> mTitle = new ArrayList<>();
private ArrayList<CategoriesHelperClass> mImages = new ArrayList<>();
private android.content.Context mcontext;
public CategoriesAdapter(ArrayList<CategoriesHelperClass> categories)
this.categories = categories;
this.mTitle = mTitle;
this.mImages = mImages;
this.mcontext = mcontext;
//Returns Categories View Dynamically
public ViewHolder onCreateViewHolder( ViewGroup parent, int viewType)
View view = LayoutInflater.from ( parent.getContext () ).inflate ( R.layout.categories_card_design, parent, false );
ViewHolder holder = new ViewHolder ( view );
return new ViewHolder ( view );
public void onBindViewHolder( ViewHolder holder, int position)
Log.d (TAG, "OnBindViewHolder: Called.");
holder.image.setImageResource ( com.example.tencil.HelperClasses.HomeAdapter.CategoriesHelperClass.getImage () );
holder.title.setText ( com.example.tencil.HelperClasses.HomeAdapter.CategoriesHelperClass.getTitle () );
holder.parentLayout.setOnClickListener ( new View.OnClickListener ()
public void onClick(View v)
Log.d (TAG, "OnClick: Clicked on" + mImages.get ( position ));
Toast.makeText ( mcontext, (CharSequence) mTitle.get ( position ), Toast.LENGTH_SHORT ).show ();
);
public int getItemCount()
return categories.size ();
//HOLDS VIEWS
public static class ViewHolder extends RecyclerView.ViewHolder
ImageView image;
TextView title;
RelativeLayout parentLayout;
public ViewHolder(View itemView)
super ( itemView );
//HOOKS
image = itemView.findViewById ( R.id.categories_image );
title = itemView.findViewById ( R.id.categories_title );
parentLayout = itemView.findViewById ( R.id.parentLayout );
UserDashboard.XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_
android:layout_
android:background="@color/colorPrimary"
android:gravity="center_horizontal"
android:orientation="vertical"
tools:context=".User.UserDashboard">
<com.google.android.material.navigation.NavigationView
android:id="@+id/navigation_view"
android:layout_
android:layout_
android:layout_gravity="start"
android:background="#fff"
android:theme="@style/navigationTheme"
app:headerLayout="@layout/menu_header"
app:menu="@menu/main_menu" />
<LinearLayout
android:id="@+id/content"
android:layout_
android:layout_
android:background="@color/lightWhite"
android:orientation="vertical">
<RelativeLayout
android:layout_
android:layout_
android:background="@color/colorPrimary"
android:padding="20dp">
<ImageView
android:id="@+id/menu_icon"
android:layout_
android:layout_
android:src="@drawable/menu_icon" />
</RelativeLayout>
<ScrollView
android:layout_
android:layout_>
<LinearLayout
android:layout_
android:layout_
android:background="#fff"
android:orientation="vertical">
<RelativeLayout
android:layout_
android:layout_>
<TextView
android:id="@+id/app_name"
android:layout_
android:layout_
android:layout_centerHorizontal="true"
android:fontFamily="@font/raleway_bold"
android:paddingTop="8dp"
android:text="@string/tencil"
android:textColor="@color/colorAccent"
android:textSize="28sp" />
</RelativeLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_gravity="center"
android:orientation="horizontal"
android:paddingTop="20dp">
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<RelativeLayout
android:id="@+id/card_1"
android:layout_
android:layout_
android:layout_margin="10dp"
android:background="@drawable/card_3"
android:elevation="8dp"
android:onClick="cardClicked1">
<ImageView
android:layout_
android:layout_
android:layout_centerInParent="true"
android:src="@drawable/tencilw" />
</RelativeLayout>
<TextView
android:layout_
android:layout_
android:text="@string/socialmedis"
android:textAlignment="center" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<RelativeLayout
android:id="@+id/card_2"
android:layout_
android:layout_
android:layout_margin="10dp"
android:background="@drawable/card_1"
android:elevation="8dp"
android:onClick="cardClicked2">>
<ImageView
android:layout_
android:layout_
android:layout_centerInParent="true"
android:src="@drawable/piggy" />
</RelativeLayout>
<TextView
android:layout_
android:layout_
android:text="@string/finance"
android:textAlignment="center" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<RelativeLayout
android:id="@+id/card_3"
android:layout_
android:layout_
android:layout_margin="10dp"
android:background="@drawable/card_2"
android:elevation="8dp"
android:onClick="cardClicked3">
<ImageView
android:layout_
android:layout_
android:layout_centerInParent="true"
android:src="@drawable/pws" />
</RelativeLayout>
<TextView
android:layout_
android:layout_
android:text="@string/tech"
android:textAlignment="center" />
</LinearLayout>
<LinearLayout
android:layout_
android:layout_
android:orientation="vertical">
<RelativeLayout
android:id="@+id/card_4"
android:layout_
android:layout_
android:layout_margin="10dp"
android:background="@drawable/card_4"
android:elevation="8dp"
android:onClick="cardClicked4">
<ImageView
android:layout_
android:layout_
android:layout_centerInParent="true"
android:src="@drawable/analysisw" />
</RelativeLayout>
<TextView
android:layout_
android:layout_
android:text="@string/fintech"
android:textAlignment="center" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_
android:layout_
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:background="@drawable/banner_background">
<LinearLayout
android:id="@+id/featured_background"
android:layout_
android:layout_
android:layout_margin="10dp"
android:background="@drawable/banner_background"
android:orientation="vertical">
<TextView
android:layout_
android:layout_
android:layout_marginLeft="10dp"
android:layout_marginTop="50dp"
android:text="@string/featured_companies"
android:textAllCaps="true"
android:textColor="#000"
android:textSize="25dp" />
<TextView
android:layout_
android:layout_
android:layout_margin="10dp"
android:text="@string/featured_companies_description" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/featured_recycler"
android:layout_
android:layout_
android:layout_marginStart="10dp"
android:layout_toEndOf="@+id/featured_background"
android:background="#fff" />
</RelativeLayout>
<LinearLayout
android:layout_
android:layout_
android:layout_marginTop="20dp"
android:orientation="vertical"
android:padding="20dp">
<RelativeLayout
android:layout_
android:layout_>
<TextView
android:layout_
android:layout_
android:fontFamily="@font/raleway_bold"
android:text="@string/categories"
android:textAllCaps="true"
android:textColor="#000"
android:textSize="20sp" />
<TextView
android:id="@+id/view_all"
android:layout_
android:layout_
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:onClick="viewAllClicked"
android:text="@string/view_all" />
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_
android:id="@+id/parentLayout"
android:layout_ />
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
</androidx.drawerlayout.widget.DrawerLayout>
CategoriesHelperClass.java
package com.example.tencil.HelperClasses.HomeAdapter;
public class CategoriesHelperClass
static int image;
static String title;
//SETTER
public CategoriesHelperClass(int image, String title)
this.image = image;
this.title = title;
//GETTER
public static int getImage()
return image;
public static String getTitle()
return title;
控制台错误消息
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tencil, PID: 5226
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.RelativeLayout.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
at com.example.tencil.HelperClasses.HomeAdapter.CategoriesAdapter.onBindViewHolder(CategoriesAdapter.java:55)
at com.example.tencil.HelperClasses.HomeAdapter.CategoriesAdapter.onBindViewHolder(CategoriesAdapter.java:25)
任何帮助将不胜感激这已经困扰了我几个小时。
【问题讨论】:
欢迎来到 Stack Overflow。从错误消息来看,holder.parentLayout
为空。请正确考虑formatting错误信息。
大家好,我现在得到以下信息: E/RecyclerView:未连接适配器;跳过布局
【参考方案1】:
这就是你在 kotlin 中使用回调解决这个问题的方法,在 java 中你需要使用监听器
在你的Activity
/Fragment
中有一个函数可以处理这样的导航
请注意,下面的代码就像一个伪代码,您必须进行相应的调整
private fun navigateTo(title: String)
//handle navigation with the title normally here
val intent = Intent(this, Category::class.java)
intent.putExtra("Title", title)
startActivity(intent)
在您的 Activity 的 onCreate 中
val categoriesAdapter = CategoriesAdapter( title ->
navigateTo(title)
)
这是 Adapter 和 ViewHolder 类
private class CategoriesAdapter(val callBack:(String)-> Unit)
override fun onCreateViewHolder(): CategoriesViewHolder
return CategoriesViewHolder(callBack)
private class CategoriesViewHolder(val callBack: (String) -> Unit)
fun bind()
item.setOnClickListener
callBack(title)
当您单击某个项目时,您将从视图持有者的 bind 方法中获取标题和任何您想要的详细信息,该方法在任何给定时间仅包含 1 个单个项目,并且将运行该方法命名为callBack
并将其标题发送回适配器,适配器什么也不做,只是再次调用相同的方法并在Activity
中为其发送标题,然后您的Activity
将运行navigateTo
方法并执行所需的操作。
在 java 中,您将在您的 Activity
/Fragment
中创建一个 Listener
,如果我没记错的话,您将直接从您的 ViewHolder 中使用它,这将产生相同的效果
【讨论】:
感谢您的回复,我会尽快尝试 大家好,我现在得到以下信息: E/RecyclerView:未连接适配器;跳过布局 有时它会在日志中输出此错误,但它可以正常工作,除非您在屏幕上没有看到任何视图,否则没关系【参考方案2】:在java中,你必须将view的每个元素转换成它的类,findViewById()
返回T
类的成员,所以你会得到普通的View而不是ImageView、TextView等。
public static class ViewHolder extends RecyclerView.ViewHolder
ImageView image;
TextView title;
RelativeLayout parentLayout;
public ViewHolder(View itemView)
super ( itemView );
//HOOKS
image = (ImageView) itemView.findViewById ( R.id.categories_image );
title = (TextView) itemView.findViewById ( R.id.categories_title );
parentLayout = (RelativeLayout) itemView.findViewById ( R.id.parentLayout );
另外,如果你想点击整行,你应该使用holder.itemView.setOnClickListener()
。仅当您触摸行视图中的可用空间时,在 RelativeLayout 上调用单击侦听器才会起作用,因此它可能不会每次都起作用。
【讨论】:
感谢您的回复,我会尽快尝试 大家好,我现在得到以下信息: E/RecyclerView:未连接适配器;跳过布局 @RyanKimber 有什么东西还是不行吗? 大家好,有没有办法让点击监听器在数组中循环? @RyanKimber 也许this 会帮助你。【参考方案3】:从列表中获取数据并设置为视图(在 onBindViewHolder 方法中)
CategoriesHelperClass item = categories.get(position);
holder.image.setImageResource ( item.getImage () );
holder.title.setText ( item.getTitle () );
holder.itemView.setOnClickListener ( new View.OnClickListener ()
public void onClick(View v)
Log.d (TAG, "OnClick: Clicked on" + mImages.get ( position ));
Toast.makeText ( mcontext, item.getTitle (), Toast.LENGTH_SHORT ).show ();
);
这两个列表不需要,你可以用类别列表处理图像和图像
private ArrayList<CategoriesHelperClass> mTitle = new ArrayList<>();
private ArrayList<CategoriesHelperClass> mImages = new ArrayList<>();
【讨论】:
感谢您的回复,我会尽快尝试 大家好,我现在得到以下信息: E/RecyclerView:未连接适配器;跳过布局以上是关于如何在 RecyclerView Java 中创建 OnClick 事件的主要内容,如果未能解决你的问题,请参考以下文章
我找不到在 Android Studio 中创建的 recyclerview 的 setOnItemClickListener
如何在 xml 和 kotlin 组合中创建类似布局的计算器
在 recyclerview Gridlayoutmanager 中创建总线布局时的间距问题