问题描述
这是我第三天处理我的视图点击.我最初使用的是ListView
,然后切换到RecyclerView
.我已经将android:onclick
元素添加到row_layout
上的每个控件中,并且正在我的MainActivity
中处理它们,如下所示:
It is my third day now dealing with the handling of my view clicks. I originally was using ListView
, then I switched to RecyclerView
. I have added android:onclick
elements to every control on my row_layout
and I am handling them in my MainActivity
like this:
public void MyMethod(View view) {}
在我以前的ListView
实现中,我已经完成了setTag(position)
以便能够通过在其内部进行操作而在MyMethod
中获得它:
In my old ListView
implementation, I have done setTag(position)
to be able to get it in MyMethod
by doing this inside it:
Integer.parseInt(view.getTag().toString())
这很好,没有问题.虽然现在我正在处理RecyclerView
并被迫使用ViewHolder
,该方法不提供setTag
方法.搜索2小时后,我发现人们像这样使用setTag
:
This worked nicely without problems. Though now I am dealing with RecyclerView
and being forced to use the ViewHolder
, which does not offer a setTag
method. After searching for 2 hours, I have found that people use setTag
like this:
holder.itemView.setTag(position)
这是可以接受的.虽然当我尝试使用以下行从MyMethod
函数获取值时:
This was acceptable. Though when I try to get the value from the MyMethod
function using the line:
Integer.parseInt(view.getTag().toString())
应用程序崩溃.我已经阅读了适配器内部可以实现onclick处理的几种实现方式,但是我必须使用MainActivity
,因为我使用的是该活动所特有的.
The application crashes. I have read several implementation of onclick handling inside the adapter which works but I have to use the MainActivity
because I am using something that is unique to that activity.
TL; DR我想以一种简单的方式将被单击的行的位置发送到我的MainActivity
.
TL;DR I want to send the position of the clicked row to my MainActivity
in a simple manner.
抱歉,因为我的主题不是很彻底.我有一个RecyclerView
和一个适配器.适配器链接到我的row_layout
.此row_layout
xml具有一个根LinearLayout
.在其中有一个TextView
,另一个LinearLayout
(具有两个TextViews
)和一个Button
(为简单起见).我不想像处理ListView
那样遭受对RecylerView
的点击的困扰.因此,我决定为每个控件添加一个android:onclick
,然后将TextView
和LinearLayout
链接到单个方法,并将Button
(以及以后的Button
)链接到它们的唯一方法.我所缺少的是,我想知道我MainActivity
上每个接收方法的位置.如果我必须将来自适配器并进入MainActivity
的所有内容链接到单个onclick处理程序,就可以了.虽然,我怎么知道哪个控件触发了点击?
I apologize for the confusion since my topic was not very thorough. I have a RecyclerView
and an adapter. The adapter is linked to my row_layout
. This row_layout
xml has one root LinearLayout
. Inside it there is one TextView
, another LinearLayout
(which has two TextViews
) and one Button
(for simplicity). I do not want to suffer for dealing with the clicks on RecylerView
like I did with the ListView
. So, I have decided to add an android:onclick
for every control, then link TextView
and LinearLayout
to a single method and link the Button
(and future Button
s) to their unique methods. What I am missing is that I want to be able to tell the position on each of the receiving methods on my MainActivity
. If I must link everything that comes from the adapter and goes into the MainActivity
to a single onclick handler, so be it. Although, how would I tell which control fired the click?
请求的布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:onClick="MyMethod"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1">
<TextView
android:id="@+id/letter"
android:onClick="MyMethod"
android:layout_width="60dp"
android:layout_height="fill_parent"
/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:onClick="MyMethod"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/firstname"
android:onClick="MyMethod"
android:layout_width="fill_parent"
android:layout_height="17dp" />
<TextView
android:id="@+id/longname"
android:onClick="MyMethod"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
<Button
android:text="Test"
android:onClick="OtherMethod"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:id="@+id/process"/>
</LinearLayout>
推荐答案
您可以通过在适配器内为itemclicklistener
创建接口,然后在MainActivity
中设置onItemClickListener
来实现此目的.
You can achieve this by creating an interface inside your adapter for an itemclicklistener
and then you can set onItemClickListener
from your MainActivity
.
RecyclerViewAdapter
内部的某些位置,您将需要以下内容:
Somewhere inside your RecyclerViewAdapter
you would need the following:
private onRecyclerViewItemClickListener mItemClickListener;
public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
public interface onRecyclerViewItemClickListener {
void onItemClickListener(View view, int position);
}
然后在您的ViewHolder
(我已将其添加为适配器的内部类)内部,将侦听器应用于希望用户单击的组件,如下所示:
Then inside your ViewHolder
(which I've added as an inner class inside my adapter), you would apply the listener to the components you'd like the user to click, like so:
class RecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public ImageView imageview;
RecyclerViewHolder(View view) {
super(view);
this.imageview = (ImageView) view
.findViewById(R.id.image);
imageview.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.onItemClickListener(v, getAdapterPosition());
}
}
}
此示例显示了onClickListener
应用于ViewHolder
内部的图像.
This example shows an onClickListener
being applied to the image inside a ViewHolder
.
recyclerView.setAdapter(adapter);// set adapter on recyclerview
adapter.notifyDataSetChanged();// Notify the adapter
adapter.setOnItemClickListener(new RecyclerViewAdapter.onRecyclerViewItemClickListener() {
@Override
public void onItemClickListener(View view, int position) {
//perform click logic here (position is passed)
}
});
要实现此代码,请在MainActivity
内的适配器中setOnItemClickListener
,如上所示.
To implement this code, you would setOnItemClickListener
to your adapter inside MainActivity
as shown above.
编辑
由于View
被传递到OnItemClickListener
中,因此您可以在侦听器内执行switch
语句,以确保对正确的组件执行正确的逻辑.您需要做的就是从MyMethod
函数中获取逻辑,然后将其复制并粘贴到希望应用的组件上.
Because the View
is getting passed into the OnItemClickListener
, you can perform a switch
statement inside the listener to ensure that the right logic is being performed to the right component. All you would need to do is take the logic from the MyMethod
function and copy and paste it to the component you wish it to be applied to.
示例:
recyclerView.setAdapter(adapter);// set adapter on recyclerview
adapter.notifyDataSetChanged();// Notify the adapter
adapter.setOnItemClickListener(new RecyclerViewAdapter.onRecyclerViewItemClickListener() {
@Override
public void onItemClickListener(View view, int position) {
Switch (view.getId()) {
case R.id.letter:
//logic for TextView with ID Letter here
break;
case R.id.firstname:
//logic for TextView with ID firstname here
break;
....
//the same can be applied to other components in Row_Layout.xml
}
}
});
您还需要在ViewHolder
内部进行一些更改.而不是将OnClickListener
应用于ImageView
,您需要像这样将其应用于整个行:
You would also need to change something inside the ViewHolder
. instead of applying the OnClickListener
to an ImageView
, you would need to apply to the whole row like so:
RecyclerViewHolder(View view) {
super(view);
this.imageview = (ImageView) view
.findViewById(R.id.image);
view.setOnClickListener(this);
}
编辑2
说明:
因此,每个RecyclerView
.您需要三个组件,RecyclerView
,RecyclerViewAdapter
和RecyclerViewHolder
.这些是定义用户看到的实际组件(RecyclerView
)以及该视图中的项目的内容.适配器是将所有组件组装在一起并实现逻辑的地方. Bill Phillips在文章 RecyclerView
第1部分:Big Nerd Ranch上ListView
专家的基础知识.
So, with every RecyclerView
. You need three components, The RecyclerView
, RecyclerViewAdapter
and the RecyclerViewHolder
. These are what define the actual components the user sees (RecyclerView
) and the Items within that View. The Adapter is where everything is pieced together and the Logic is implemented. The ins and outs of these components are nicely explained by Bill Phillips with the article RecyclerView
Part 1: Fundamentals For ListView
Experts over at Big Nerd Ranch.
但是要进一步说明点击事件背后的逻辑,它基本上是利用界面,将信息从RecyclerViewAdapter
传递到RecyclerViewHolder
到您的MainActivity
.因此,如果您遵循RecyclerView
适配器的生命周期,那将是有道理的.
But to further explain the logic behind the click events, it's basically utilizing an interface to pass information from the RecyclerViewAdapter
to the RecyclerViewHolder
to your MainActivity
. So if you follow the life-cycle of the RecyclerView
adapter, it'll make sense.
适配器在MainActivity
内部初始化,然后将使用传递的信息来调用适配器的构造函数.然后,这些组件将通过OnCreateViewHolder
方法传递到适配器中.这本身告诉适配器,这就是您希望列表看起来如何的样子.然后,需要单独初始化布局中的组件,这就是ViewHolder
起作用的地方.就像您在Activities
中初始化的任何其他组件一样,您在ViewHolder
中进行了相同的操作,但是由于RecyclerViewAdapter
使ViewHolder
膨胀,因此您可以在适配器中愉快地使用它们,如Zeeshan Shabbir所示. .但是,对于此示例,您希望多个组件将各种逻辑应用于您的MainActivity
类中的每个单独的逻辑.
The adapter is initialized inside your MainActivity
, the adapter's constructor would then be called with the information being passed. The components would then be passed into the adapter via the OnCreateViewHolder
method. This itself tells the adapter, that's how you would like the list to look like. The components in that layout, would then need to be individually initialized, that's where the ViewHolder
comes into play. As you can see like any other components you would initialize in your Activities
, you do the same in the ViewHolder
but because the RecyclerViewAdapter
inflates the ViewHolder
you can happily use them within your adapter as shown by Zeeshan Shabbir. But, for this example you would like multiple components to have various logic applied to each individual one in your MainActivity
class.
在这里,我们将单击侦听器创建为全局变量(因此,ViewHolder
和Adapter
都可以访问它),在这种情况下,适配器的工作是通过创建Interface
来确保侦听器存在您可以通过初始化监听器.
That's where we create the click listener as a global variable (so it can be accessed by both the ViewHolder
and the Adapter
) the adapter's job in this case is to ensure the listener exists by creating an Interface
you can initialize the listener through.
public interface onRecyclerViewItemClickListener {
void onItemClickListener(View view, int position);
}
在定义了您希望接口保存的信息(例如,组件及其位置)之后,您可以创建一个函数,在该函数中适配器将调用以应用Activity
中的逻辑(相同的方法)您会调用View.OnClickListener
),但是通过创建setOnItemClickListener
,您可以对其进行自定义.
After you've defined the information you would like the interface to hold (E.G. the component and it's position), you can then create a function in which the adapter will call to apply the logic from your Activity
(same way you would called View.OnClickListener
) but by creating a setOnItemClickListener
, you can customize it.
public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
然后,此函数需要将onRecyclerViewItemClickListener
变量传递给它,如在MainActivity
中所见. new RecyclerViewAdapter.onRecyclerViewItemClickListener()
在这种情况下,是您之前使用内部方法创建的接口,因此需要实现
This function then needs onRecyclerViewItemClickListener
variable passed to it, as seen in your MainActivity
. new RecyclerViewAdapter.onRecyclerViewItemClickListener()
in this case it's the interface you created before with the method inside that would need to be implemented hence the
@Override
public void onItemClickListener(View view, int position) {
}
被调用.
在这种情况下,ViewHolder
所做的所有操作都是将信息(自身的组成部分和位置)传递给具有附加组件(在onClick
函数内部)的onItemClickListener
,以最终确定实际的单击功能.
All the ViewHolder
does in this scenario is pass the information (The components it's self and the position) into the onItemClickListener
with the components attached (inside the onClick
function) to finalize the actual click functionality.
如果您仍然希望我更新说明,请告诉我.
if you would like me to update the explanation in anyway, let me know.
这篇关于RecyclerView-在Activity而不是RecyclerViewAdapter中获取位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!