我使用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活动中:
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) {
}
}));
我找到了超级简单的方法!我推荐这个
示例代码:
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发现了这个
希望它能帮助你。
你可以让你的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
}
}
}
如果我理解正确,您需要在活动中设置on click逻辑。
您可以通过在Activity中设置OnClickListener并在Adapter构造函数中传递它来完成此操作。
MyAdapter myAdapter = new MyAdapter(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
}));
而你的MyAdapter构造函数将是:
final private OnClickListener onClickListener;
public MyAdapter(OnClickListener onClickListener) {
this.OnClickListener = OnClickListener;
}
所以你的新代码就是这样的
public void onBindViewHolder(MyHolder holder, final int position) {
final Listdata data = listdata.get(position);
holder.vname.setText(data.getName());
holder.vname.setOnClickListener(onClickListener);
}
为适配器类创建一个接口
private OnItemClickListener mListener;
public CustomAdapter(List<Listdata> listdata, OnItemClickListener listener) {
mListener = listener;
...
...
}
private class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
ViewHolder(View view) {
...
...
view.setOnClickLister(this);
}
@override
public void onClick(View v) {
mListener.onAdapterItemClick(getAdapterPosition())
}
}
interface OnItemClickListener {
void onAdapterItemClick(int position);
}
让活动实现接口
public class CustomListActivity extends AppCompatActivity implements OnItemClickListener {
...
...
@override
public void onAdapterItemClick(int position) {
Toast.makeText(activity, "clicked on " +position, Toast.LENGTH_SHORT).show();
}
还有另一种方法,请查看this实现
我的项目中总是有一个通用适配器,以避免每次使用Recyclerview时都生成一个Adapter类。这里有一些例子
public class AdapterRecyclerviewTextOnly extends RecyclerView.Adapter<AdapterRecyclerviewTextOnly.ViewHolder> {
private RecyclerView recyclerView;
private OnRecyclerviewListener onRecyclerviewListener;
public interface OnRecyclerviewListener {
void onRecyclerviewBind(RecyclerView recyclerView, AdapterRecyclerviewTextOnly.ViewHolder viewHolder, int position);
void onRecyclerviewClick(RecyclerView recyclerView, int position);
int onItemCount(RecyclerView recyclerView);
}
public void setOnRecyclerviewListener(OnRecyclerviewListener listener) { this.onRecyclerviewListener = listener; }
public AdapterRecyclerviewTextOnly(RecyclerView recyclerView) {
super();
this.recyclerView = recyclerView;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
RecyclerView recyclerView;
public TextView textView;
ViewHolder(RecyclerView recyclerView, View itemView) {
super(itemView);
this.recyclerView = recyclerView;
this.itemView.setOnClickListener(this);
this.textView = itemView.findViewById(R.id.textview_title);
}
void onBind(int position) { onRecyclerviewListener.onRecyclerviewBind(this.recyclerView, this, position); }
@Override
public void onClick(View v) {
onRecyclerviewListener.onRecyclerviewClick(this.recyclerView, getAdapterPosition());
}
}
@Override
public AdapterRecyclerviewTextOnly.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View inflatedView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_recyclerview_text_only, parent, false);
return new ViewHolder(this.recyclerView, inflatedView);
}
@Override
public void onBindViewHolder(AdapterRecyclerviewTextOnly.ViewHolder holder, int position) {
holder.onBind(position);
}
@Override
public int getItemCount() {
return onRecyclerviewListener.onItemCount(this.recyclerView);
}
}
然后在您的Activity类中,您可以使用此适配器:
this.recyclerView = findViewById(R.id.recyclerview);
this.recyclerView.setHasFixedSize(true);
this.recyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
AdapterRecyclerviewTextOnly recyclerViewAdapter = new AdapterRecyclerviewTextOnly(this.recyclerView);
this.recyclerView.setAdapter(this.recyclerViewAdapter);
this.recyclerViewAdapter.setOnRecyclerviewListener(new AdapterRecyclerviewTextOnly.OnRecyclerviewListener() {
@Override
public void onRecyclerviewBind(RecyclerView recyclerView, AdapterRecyclerviewTextOnly.ViewHolder viewHolder, int position) {
}
@Override
public void onRecyclerviewClick(RecyclerView recyclerView, int position) {
}
@Override
public int onItemCount(RecyclerView recyclerView) {
}
});
您也可以使用2或3个recyclerview重复使用它。首先,声明一个全球监听器private AdapterRecyclerviewTextOnly.OnRecyclerviewListener listener;
。
然后使用新对象初始化侦听器,然后使用侦听器设置每个recyclelerview。使用特定标识符:
if (recyclerView == recyclerViewA){ } else if (recyclerView == recyclerViewB) { }
管理适配器内的recyclerview。