[我使用RecyclerView
适配器在活动内显示数据,我想在活动内实现onClickListener
,目前,我照常在适配器内设置onClickListener
,效果很好。
public void onBindViewHolder(MyHolder holder, final int position) {
final Listdata data = listdata.get(position);
holder.vname.setText(data.getName());
holder.vname.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
});
}
但是我想在活动中实现它,所以我可以更好地控制。这不符合我的目的。我认为这对我们很多人都是有用的。
您需要在此处检查this tutorial,以更好地了解如何实现所需的行为。
如果要处理活动中的onClickListener
,则需要基于带有接口的回调实现。将接口从活动传递到适配器,然后在单击某些项目时从适配器调用回调函数。
这里是本教程的示例实现。
让我们首先拥有界面。
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
您需要修改适配器以将侦听器作为参数,如下所述。
private final List<ContentItem> items;
private final OnItemClickListener listener;
public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
现在在onBindViewHolder
方法中,设置点击监听器。
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
...
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
现在在RecyclerView
中设置适配器。
recycler.setAdapter(new ContentAdapter(items, new ContentAdapter.OnItemClickListener() {
@Override public void onItemClick(ContentItem item) {
Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show();
}
}));
因此整个适配器代码如下所示。
public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(ContentItem item);
}
private final List<ContentItem> items;
private final OnItemClickListener listener;
public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) {
this.items = items;
this.listener = listener;
}
@Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false);
return new ViewHolder(v);
}
@Override public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(items.get(position), listener);
}
@Override public int getItemCount() {
return items.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
private TextView name;
private ImageView image;
public ViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.name);
image = (ImageView) itemView.findViewById(R.id.image);
}
public void bind(final ContentItem item, final OnItemClickListener listener) {
name.setText(item.name);
Picasso.with(itemView.getContext()).load(item.imageUrl).into(image);
itemView.setOnClickListener(new View.OnClickListener() {
@Override public void onClick(View v) {
listener.onItemClick(item);
}
});
}
}
}
非常简单和干净的解决方案是:
create a class with the name of RecyclerTouchListener:
public 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) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
public interface ClickListener {
void onClick(View view, int position);
void onLongClick(View view, int position);
}
}
在您的回收站视图活动中:
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), recyclerView, new RecyclerTouchListener.ClickListener() {
@Override
public void onClick(View view, int position) {
speech(countries_list_code[position]);
}
@Override
public void onLongClick(View view, int position) {
}
}));
您可以让您的Activity
实现View.OnClickListener
并将其传递给适配器。下面是一个示例。
class RAdapter extends RecyclerView.Adapter<>{
View.OnClickListener listner;
public RAdapter(View.OnClickListener listner) {
this.listner = listner;
}
public void onBindViewHolder(MyHolder holder, final int position) {
holder.vname.setOnClickListener(listner);
}
}
但是要处理Activity
中的点击,您将需要点击位置。您可以将其与adapter.getAdapterPosition()
一起使用以验证单击了哪个项目。
此外,如果您已经具有Activity
的引用,则可以在适配器内使用OnClick
并调用具有位置执行操作的Activity
的公共方法。
处理ViewHolder
中点击的更好方法。请参见下面的示例。
class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
Button button;
public Holder(View itemView) {
super(itemView);
button=itemView.findViewById(R.id.b1);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.b1){
int position=getAdapterPosition();
// Call a public method of Activity here
// with postion
}
}
}
我发现超级傻瓜简单的方法!我推荐这个]
示例代码:
public class ContentAdapter extends RecyclerView.Adapter<ContentAdapter.ViewHolder> { public interface OnItemClickListener { void onItemClick(ContentItem item); } private final List<ContentItem> items; private final OnItemClickListener listener; public ContentAdapter(List<ContentItem> items, OnItemClickListener listener) { this.items = items; this.listener = listener; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_item, parent, false); return new ViewHolder(v); } @Override public void onBindViewHolder(ViewHolder holder, int position) { holder.bind(items.get(position), listener); } @Override public int getItemCount() { return items.size(); } static class ViewHolder extends RecyclerView.ViewHolder { private TextView name; private ImageView image; public ViewHolder(View itemView) { super(itemView); name = (TextView) itemView.findViewById(R.id.name); image = (ImageView) itemView.findViewById(R.id.image); } public void bind(final ContentItem item, final OnItemClickListener listener) { name.setText(item.name); Picasso.with(itemView.getContext()).load(item.imageUrl).into(image); itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { listener.onItemClick(item); } }); } } }
并使用以下代码使用RecyclerView适配器:
recycler.setAdapter(new ContentAdapter(items, new ContentAdapter.OnItemClickListener() { @Override public void onItemClick(ContentItem item) { Toast.makeText(getContext(), "Item Clicked", Toast.LENGTH_LONG).show(); } }));
我从here找到了这个
希望它对您有所帮助。
如果我理解正确,则想在活动中设置点击逻辑。
为适配器类创建接口
我在项目中总是有一个通用适配器,以避免每次我使用Recyclerview时都创建一个Adapter类。这里有一些例子