我应该将 setOnClickListener 放在 RecyclerView 适配器的什么位置
Where should I place setOnClickListener in a RecyclerView Adapter
在 Internet 上的教程中,他们在 RecyclerView 的适配器中设置了 OnClickListener,他们以两种方式定义它:在 ViewHolder 内部或在 BindViewHolder 内部。
我的问题是哪种方法更好,请推荐任何其他方法
1) ViewHolder 内部:
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
tvSrc = (TextView) itemView.findViewById(R.id.tvSrc);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "inside viewholder position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
}
2) 在 BindViewHolder 中
public void onBindViewHolder(DisplayTrainsAdapter.ViewHolder viewHolder, final int position) {
viewHolder.tvSrc.setText(mDataset.get(position).strSrc);
viewHolder.tvSrc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "position = " + getItemId(position), Toast.LENGTH_SHORT).show();
}
});
}
我猜 在 ViewHolder()
中,因为您定义了 view
的内容以及它的内部功能和其他功能。
但是onBindViewHolder()
你说在ViewHolder
中定义的view
会有这个文字,这个图片...
恕我直言:我喜欢数字 1。
自从您调用 new ViewHolder(View)
之后,您实际上是在实际显示您的内容之前设置了您的 onClickListener。这很好,因为在调用 onBindView 时,您的 onClickListener 已经在您的视图上设置。
我认为在构造函数中执行此操作的代码也更清晰 ViewHolder(View)
您的 1 号解决方案是您建议的最佳解决方案,因为在 notify..() 方法触发的每次无效时,不会在绑定中调用该分配。
我也知道其他解决方案,但您需要在 activity.
中实施 android.view.GestureDetector
如果您希望对适配器进行其他改进,请查看我的 FlexibleAdapter https://github.com/davideas/FlexibleAdapter 并随时在您的项目中实施。
两种选择各有利弊。
例如,如果单击一个按钮并且您想更改按钮的文本,那么您可能应该使用在 ViewHolder 中设置 onClick 侦听器的选项。除了这个原因,它也让你的代码看起来更干净。
但是,如果说,当单击按钮时,您想更改与单击的按钮相同的 index/position 中的 TextView 文本,则需要使用您设置的选项onBindViewHolder 方法中的 onClick 侦听器。
您应该始终检查 getAdapterPosition 是否 >= 0,因为在极少数情况下它可能为 -1 (NO_POSITION),这会导致您的应用崩溃。 https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder#getadapterposition
在 Internet 上的教程中,他们在 RecyclerView 的适配器中设置了 OnClickListener,他们以两种方式定义它:在 ViewHolder 内部或在 BindViewHolder 内部。
我的问题是哪种方法更好,请推荐任何其他方法
1) ViewHolder 内部:
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
tvSrc = (TextView) itemView.findViewById(R.id.tvSrc);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "inside viewholder position = " + getAdapterPosition(), Toast.LENGTH_SHORT).show();
}
});
}
2) 在 BindViewHolder 中
public void onBindViewHolder(DisplayTrainsAdapter.ViewHolder viewHolder, final int position) {
viewHolder.tvSrc.setText(mDataset.get(position).strSrc);
viewHolder.tvSrc.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "position = " + getItemId(position), Toast.LENGTH_SHORT).show();
}
});
}
在 ViewHolder()
中,因为您定义了 view
的内容以及它的内部功能和其他功能。
但是onBindViewHolder()
你说在ViewHolder
中定义的view
会有这个文字,这个图片...
恕我直言:我喜欢数字 1。
自从您调用 new ViewHolder(View)
之后,您实际上是在实际显示您的内容之前设置了您的 onClickListener。这很好,因为在调用 onBindView 时,您的 onClickListener 已经在您的视图上设置。
我认为在构造函数中执行此操作的代码也更清晰 ViewHolder(View)
您的 1 号解决方案是您建议的最佳解决方案,因为在 notify..() 方法触发的每次无效时,不会在绑定中调用该分配。 我也知道其他解决方案,但您需要在 activity.
中实施 android.view.GestureDetector如果您希望对适配器进行其他改进,请查看我的 FlexibleAdapter https://github.com/davideas/FlexibleAdapter 并随时在您的项目中实施。
两种选择各有利弊。
例如,如果单击一个按钮并且您想更改按钮的文本,那么您可能应该使用在 ViewHolder 中设置 onClick 侦听器的选项。除了这个原因,它也让你的代码看起来更干净。
但是,如果说,当单击按钮时,您想更改与单击的按钮相同的 index/position 中的 TextView 文本,则需要使用您设置的选项onBindViewHolder 方法中的 onClick 侦听器。
您应该始终检查 getAdapterPosition 是否 >= 0,因为在极少数情况下它可能为 -1 (NO_POSITION),这会导致您的应用崩溃。 https://developer.android.com/reference/android/support/v7/widget/RecyclerView.ViewHolder#getadapterposition