我使用以下代码来处理行点击。(来源)
static class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private GestureDetector gestureDetector;
private ClickListener clickListener;
public RecyclerTouchListener(Context context, final RecyclerView recyclerView, final ClickListener clickListener) {
this.clickListener = clickListener;
gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e) {
View child = recyclerView.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null) {
clickListener.onLongClick(child, recyclerView.getChildPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = rv.findChildViewUnder(e.getX(), e.getY());
if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) {
clickListener.onClick(child, rv.getChildPosition(child));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
}
然而,如果我想在每一行上都有一个删除按钮,这是可行的。我不知道如何用这个实现这一点。
我附加了OnClick侦听器来删除按钮,它可以工作(删除该行),但它也会在整行上触发onClick。
如果单击一个按钮,有谁能帮我避免整行单击吗。
谢谢。
我想要一个解决方案,该解决方案不创建任何额外的对象(即侦听器),这些对象稍后必须进行垃圾收集,并且不需要在适配器类中嵌套视图保持器。
在ViewHolder类中
private static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView ....// declare the fields in your view
private ClickHandler ClickHandler;
public MyHolder(final View itemView) {
super(itemView);
nameField = (TextView) itemView.findViewById(R.id.name);
//find other fields here...
Button myButton = (Button) itemView.findViewById(R.id.my_button);
myButton.setOnClickListener(this);
}
...
@Override
public void onClick(final View view) {
if (clickHandler != null) {
clickHandler.onMyButtonClicked(getAdapterPosition());
}
}
需要注意的是:定义了ClickHandler接口,但在这里没有初始化,因此在onClick方法中没有假设它曾经初始化过。
点击处理程序界面如下所示:
private interface ClickHandler {
void onMyButtonClicked(final int position);
}
在适配器中,在构造函数中设置“ClickHandler”的实例,并重写BindViewHolder,以初始化视图持有人上的“ClickHandler”:
private class MyAdapter extends ...{
private final ClickHandler clickHandler;
public MyAdapter(final ClickHandler clickHandler) {
super(...);
this.clickHandler = clickHandler;
}
@Override
public void onBindViewHolder(final MyViewHolder viewHolder, final int position) {
super.onBindViewHolder(viewHolder, position);
viewHolder.clickHandler = this.clickHandler;
}
注意:我知道那个viewHolder。clickHandler可能会使用完全相同的值多次设置,但这比检查null和分支要便宜,并且没有内存开销,只需要一条额外的指令。
最后,在创建适配器时,您必须将ClickHandler实例传递给构造函数,如下所示:
adapter = new MyAdapter(new ClickHandler() {
@Override
public void onMyButtonClicked(final int position) {
final MyModel model = adapter.getItem(position);
//do something with the model where the button was clicked
}
});
注意,适配器在这里是一个成员变量,而不是局部变量
我发现通常:
因此@mark keen的答案很好,但有一个界面提供了更大的灵活性:
public static class MyViewHolder extends RecyclerView.ViewHolder {
public ImageView iconImageView;
public TextView iconTextView;
public MyViewHolder(final View itemView) {
super(itemView);
iconImageView = (ImageView) itemView.findViewById(R.id.myRecyclerImageView);
iconTextView = (TextView) itemView.findViewById(R.id.myRecyclerTextView);
iconTextView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onClickListener.iconTextViewOnClick(v, getAdapterPosition());
}
});
iconImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onClickListener.iconImageViewOnClick(v, getAdapterPosition());
}
});
}
}
其中onClickListener在适配器中定义:
public MyAdapterListener onClickListener;
public interface MyAdapterListener {
void iconTextViewOnClick(View v, int position);
void iconImageViewOnClick(View v, int position);
}
可能是通过构造器设置的:
public MyAdapter(ArrayList<MyListItems> newRows, MyAdapterListener listener) {
rows = newRows;
onClickListener = listener;
}
然后,您可以处理活动中的事件或使用RecyclerView的任何地方:
mAdapter = new MyAdapter(mRows, new MyAdapter.MyAdapterListener() {
@Override
public void iconTextViewOnClick(View v, int position) {
Log.d(TAG, "iconTextViewOnClick at position "+position);
}
@Override
public void iconImageViewOnClick(View v, int position) {
Log.d(TAG, "iconImageViewOnClick at position "+position);
}
});
mRecycler.setAdapter(mAdapter);
这是我在recyclerView中处理多个onClick事件的方式:
编辑:已更新以包含回调(如其他评论中提到的)。我在ViewHolder
中使用了WeakResources
来消除潜在的内存泄漏。
定义接口:
public interface ClickListener {
void onPositionClicked(int position);
void onLongClicked(int position);
}
然后适配器:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private final ClickListener listener;
private final List<MyItems> itemsList;
public MyAdapter(List<MyItems> itemsList, ClickListener listener) {
this.listener = listener;
this.itemsList = itemsList;
}
@Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.my_row_layout), parent, false), listener);
}
@Override public void onBindViewHolder(MyViewHolder holder, int position) {
// bind layout and data etc..
}
@Override public int getItemCount() {
return itemsList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
private ImageView iconImageView;
private TextView iconTextView;
private WeakReference<ClickListener> listenerRef;
public MyViewHolder(final View itemView, ClickListener listener) {
super(itemView);
listenerRef = new WeakReference<>(listener);
iconImageView = (ImageView) itemView.findViewById(R.id.myRecyclerImageView);
iconTextView = (TextView) itemView.findViewById(R.id.myRecyclerTextView);
itemView.setOnClickListener(this);
iconTextView.setOnClickListener(this);
iconImageView.setOnLongClickListener(this);
}
// onClick Listener for view
@Override
public void onClick(View v) {
if (v.getId() == iconTextView.getId()) {
Toast.makeText(v.getContext(), "ITEM PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(v.getContext(), "ROW PRESSED = " + String.valueOf(getAdapterPosition()), Toast.LENGTH_SHORT).show();
}
listenerRef.get().onPositionClicked(getAdapterPosition());
}
//onLongClickListener for view
@Override
public boolean onLongClick(View v) {
final AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
builder.setTitle("Hello Dialog")
.setMessage("LONG CLICK DIALOG WINDOW FOR ICON " + String.valueOf(getAdapterPosition()))
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
listenerRef.get().onLongClicked(getAdapterPosition());
return true;
}
}
}
然后在您的活动/片段中-您可以实现的任何内容:Clicklistener
-或者匿名类,如果您愿意的话:
MyAdapter adapter = new MyAdapter(myItems, new ClickListener() {
@Override public void onPositionClicked(int position) {
// callback performed on click
}
@Override public void onLongClicked(int position) {
// callback performed on click
}
});
要获取单击的项目,请匹配视图id,即v.getId()==whateverItem。getId()
希望这种方法有帮助!
我有一个包含单选按钮的回收器视图。 现在我只想从列表中选择一个单选按钮并获得它的值 下面我附上了截图。 回收器视图的截图 下面是我到目前为止尝试的链接。 http://www.zoftino.com/android-recycerview-radiobutton 在回收视图中仅选择一个radiobutton 如何只选择一个RadioButton与RecolyerView Android? 从Rec
我正在使用RecycerView构建一个切换按钮列表(如numpad),我希望实现: 当用户通过单击某个按钮“打开”该按钮时,将“关闭”所有其他按钮 我尝试在视图holder类中添加,并调用,这样就可以调用,然后更改按钮的状态。 维埃霍尔德 我的adpater类中的onBindViewHolder()
请帮助如何使其工作
单击时的卡片视图正在工作。但回收器视图的区域不可单击。如何使其可点击,以便捕获卡片视图的事件。
如果用户点击一个,我希望它做一些事情,也为两个和三个。我如何实现这一点?
我正在使用网格布局管理器使用回收器视图。我想在点击按钮时滚动循环视图。(单击按钮时,我正在通过位置,我的项目将突出显示)。所以我想在顶部显示突出显示的项目。可能是项目位于不同的位置。 onViewCreated在我初始化的位置----- 接口抽象方法---从我想滚动我的回收器视图和位置是从适配器类传递的。