现在是我处理点击次数的第三天。我最初使用ListView
,然后切换到RecyclerView
。我已在android:onclick
的每个控件上添加了row_layout
个元素,我正在MainActivity
处理这些元素:
public void MyMethod(View view) {}
在我原来的ListView
实施中,我已经完成了setTag(position)
,可以通过在MyMethod
内完成此操作:
Integer.parseInt(view.getTag().toString())
这很好用,没有问题。虽然现在我正在处理RecyclerView
并被迫使用ViewHolder
,但不提供setTag
方法。搜索了2个小时后,我发现人们使用setTag
这样:
holder.itemView.setTag(position)
这是可以接受的。虽然当我尝试使用以下行从MyMethod
函数获取值时:
Integer.parseInt(view.getTag().toString())
应用程序崩溃。我已经阅读了适配器内部的onclick处理的几个实现,但是我必须使用MainActivity
,因为我正在使用该活动独有的东西。
TL; DR我想以简单的方式将点击的行的位置发送到MainActivity
。
编辑:我为这个混乱道歉,因为我的主题不是很彻底。我有一个RecyclerView
和一个适配器。适配器已链接到我的row_layout
。这个row_layout
xml有一个根LinearLayout
。其中有一个TextView
,另一个LinearLayout
(有两个TextViews
)和一个Button
(为简单起见)。我不想像处理RecylerView
那样处理ListView
点击而受到影响。因此,我决定为每个控件添加android:onclick
,然后将TextView
和LinearLayout
链接到单个方法并链接Button
(以及将来的Button
s)他们独特的方法。我缺少的是,我希望能够在MainActivity
上告诉每个接收方法的位置。如果我必须链接来自适配器的所有内容并进入MainActivity
到单个onclick处理程序,那就这样吧。虽然,我怎么知道哪个控件触发了点击?
编辑2:请求的布局
<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>
答案 0 :(得分:10)
您可以通过在适配器内为itemclicklistener
创建一个接口来实现此目的,然后您可以从onItemClickListener
设置MainActivity
。
在RecyclerViewAdapter
内的某处,您需要以下内容:
private onRecyclerViewItemClickListener mItemClickListener;
public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
public interface onRecyclerViewItemClickListener {
void onItemClickListener(View view, int position);
}
然后在ViewHolder
(我已经在我的适配器中添加内部类)中,您可以将侦听器应用于您希望用户单击的组件,如下所示:
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
内的图片。
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)
}
});
要实现此代码,您应setOnItemClickListener
MainActivity
内的适配器,如上所示。
修改强>
因为View
已传递到OnItemClickListener
,您可以在侦听器内执行switch
语句,以确保正确的逻辑正在执行到正确的组件。您需要做的就是从MyMethod
函数中获取逻辑并将其复制并粘贴到您希望应用它的组件中。
示例:
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
,您需要像这样应用于整行:
RecyclerViewHolder(View view) {
super(view);
this.imageview = (ImageView) view
.findViewById(R.id.image);
view.setOnClickListener(this);
}
编辑2
说明:
所以,每个RecyclerView
。您需要三个组件,RecyclerView
,RecyclerViewAdapter
和RecyclerViewHolder
。这些是定义用户看到的实际组件(RecyclerView
)和该视图中的项目的内容。适配器是将所有内容拼凑在一起并实现逻辑的地方。比尔菲利普斯在Big Nerd Ranch上发表文章RecyclerView
Part 1: Fundamentals For ListView
Experts很好地解释了这些组成部分的细节。
但为了进一步解释点击事件背后的逻辑,它基本上利用interface将信息从RecyclerViewAdapter
传递到RecyclerViewHolder
到MainActivity
}。因此,如果您遵循RecyclerView
适配器的生命周期,它就会有意义。
适配器在MainActivity
内初始化,然后将通过传递的信息调用适配器的构造函数。然后,组件将通过OnCreateViewHolder
方法传递到适配器。这本身告诉适配器,你希望列表看起来如何。然后,需要单独初始化该布局中的组件,即ViewHolder
发挥作用的位置。正如您在Activities
中初始化的任何其他组件一样,您可以在ViewHolder
中执行相同操作,但由于RecyclerViewAdapter
对ViewHolder
进行了膨胀,您可以愉快地使用它们在你的适配器内,如Zeeshan Shabbir所示。但是,对于此示例,您希望多个组件将各种逻辑应用于MainActivity
类中的每个组件。
在这种情况下,我们将点击侦听器创建为全局变量(因此ViewHolder
和Adapter
都可以访问)适配器的工作是通过创建Interface
来确保监听器存在,您可以通过初始化监听器。
public interface onRecyclerViewItemClickListener {
void onItemClickListener(View view, int position);
}
在您定义了接口要保存的信息(EG组件及其位置)之后,您可以创建一个适配器将调用以应用您的逻辑的函数。 Activity
(与调用View.OnClickListener
的方式相同),但通过创建setOnItemClickListener
,您可以对其进行自定义。
public void setOnItemClickListener(onRecyclerViewItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
此函数需要传递给它的onRecyclerViewItemClickListener
变量,如MainActivity
中所示。 new RecyclerViewAdapter.onRecyclerViewItemClickListener()
在这种情况下,您之前使用内部方法创建的接口需要实现,因此
@Override
public void onItemClickListener(View view, int position) {
}
被调用。
此方案中的所有ViewHolder
都会将信息(其自身和位置的组件)传递到onItemClickListener
并附加了组件(onClick
内部function)完成实际的点击功能。
如果您希望我以任何方式更新说明,请告诉我。
答案 1 :(得分:1)
我认为你很难处理ReceylerView
上的多次点击,如果是这种情况,那么让我分享一下我项目中的代码片段。这就是我如何处理RecyclerView
public class ExploreItemAdapter extends RecyclerView.Adapter<ExploreItemAdapter.ViewHolder> {
private WSResponseDTO<Data> wsResponseDTO;
public ExploreItemAdapter(WSResponseDTO<Data> wsResponseDTO) {
this.wsResponseDTO = wsResponseDTO;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.consumer_dashboard_item, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.tvCompanyName.setText(wsResponseDTO.getData().getPosts().get(position).getStoreInfo().getStoreName());
holder.tvBranchName.setText("(" + wsResponseDTO.getData().getPosts().get(position).getStoreInfo().getBranchName() + ")");
holder.tvLikes.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getFavoriteCount() + "");
holder.tvShares.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getShareCount() + "");
holder.validity.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getValidFrom() + "-" +
wsResponseDTO.getData().getPosts().get(position).getPost().getValidTo());
holder.sTime.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getTime());
holder.tvTitle.setText(wsResponseDTO.getData().getPosts().get(position).getPost().getHeading());
holder.cardView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "card is touched", Toast.LENGTH_SHORT).show();
view.getContext().startActivity(new Intent(view.getContext(), ConsumerDetailOfferActivity.class).putExtra("post", wsResponseDTO.getData().getPosts().get(position)));
}
});
}
@Override
public int getItemCount() {
return wsResponseDTO.getData().getPosts().size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.card_explore)
CardView cardView;
@BindView(R.id.tv_company_name)
TextView tvCompanyName;
@BindView(R.id.tv_branch_name)
TextView tvBranchName;
@BindView(R.id.tv_title)
TextView tvTitle;
@BindView(R.id.tv_like_count)
TextView tvLikes;
@BindView(R.id.tv_share_count)
TextView tvShares;
@BindView(R.id.tv_validity)
TextView validity;
@BindView(R.id.tv_sTime)
TextView sTime;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}
您可以将click侦听器设置为bindViewHolder()中的任何项目,就像我为cardView
所做的那样。我希望这会对某些人有所帮助。