有人使用RecyclerView找到了一种方法来设置一个onClickListener的项目在RecyclerView? 我想设置一个监听器为每个项目的布局,但这似乎有点太麻烦了 我确信有一种方法让RecyclerView监听onClick事件,但我不能完全弄清楚。
当前回答
我是这样做的,没有不必要的类、检测器等。适配器中的简单代码。特别是针对longClick的更好解决方案。
public class PasswordAdapter extends RecyclerView.Adapter<PasswordAdapter.ViewHolder> {
private final ClickListener clickListener;
public PasswordAdapter(ClickListener clickListener) {
this.clickListener = clickListener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
TextView name;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
name = (TextView) itemView.findViewById(R.id.card_name);
}
@Override
public void onClick(View v) {
int position = getBindingAdapterPosition();
if (position >= 0) {
clickListener.onItemClick(position, v);
}
}
@Override
public boolean onLongClick(View v) {
int position = getBindingAdapterPosition();
if (position >= 0) {
clickListener.onItemLongClick(position, v);
return true;
}
return false;
}
}
public interface ClickListener {
void onItemClick(int position, View v);
void onItemLongClick(int position, View v);
}
}
然后在片段或活动中,点击:
PasswordAdapter mAdapter = new PasswordAdapter(
new PasswordAdapter.ClickListener() {
@Override
public void onItemClick(int position, View v) {
Log.d(TAG, "onItemClick position: " + position);
}
@Override
public void onItemLongClick(int position, View v) {
Log.d(TAG, "onItemLongClick pos = " + position);
}
}
);
其他回答
这是我所做的阅读更多和下载要点在这里
在这里添加相同的内容
CustomItemClickListener.java
public interface CustomItemClickListener {
public void onItemClick(View v, int position);
}
ItemsListAdapter.java
public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> {
ArrayList<ItemListSingleItem> data;
Context mContext;
CustomItemClickListener listener;
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
final ViewHolder mViewHolder = new ViewHolder(mView);
mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.onItemClick(v, mViewHolder.getAdapterPosition());
}
});
return mViewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.itemTitle.setText(Html.fromHtml(data.get(position).getTitle()));
if (!TextUtils.isEmpty(data.get(position).getThumbnailURL())) {
// I Love picasso library :) http://square.github.io/picasso/
Picasso.with(mContext).load(data.get(position).getThumbnailURL()).error(R.drawable.ic_no_image).
placeholder(R.drawable.ic_no_image).
transform(new RoundedCornersTransformation(5, 0)).
into(holder.thumbnailImage);
} else {
holder.thumbnailImage.setImageResource(R.drawable.ic_no_image);
}
}
@Override
public int getItemCount() {
return data.size();
}
public ItemsListAdapter(Context mContext, ArrayList<ItemsListSingleItem> data, CustomItemClickListener listener) {
this.data = data;
this.mContext = mContext;
this.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView itemTitle;
public ImageView thumbnailImage;
ViewHolder(View v) {
super(v);
itemTitle = (TextView) v
.findViewById(R.id.post_title);
thumbnailImage = (ImageView) v.findViewById(R.id.post_thumb_image);
}
}
}
到目前为止,所有的答案都是很好的解决方案,但是如果你不想处理太多的实现细节,只是想让它类似于ListView的工作方式,我建议使用twway - view,如下所示:
https://github.com/lucasr/twoway-view
请注意,这个实现还支持长按项目,以及支持按下状态(这是这个问题的其他解决方案所缺乏的重要内容)。
如果您不想使用整个库,请查看ClickItemTouchListener类,如果需要,可以将其作为独立的类使用。我发现它目前唯一的问题是长按+滚动,它似乎有不正确的行为。
将类标记为抽象并实现OnClick方法
public abstract class MainGridAdapter extends
RecyclerView.Adapter<MainGridAdapter.ViewHolder> {
private List<MainListItem> mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView txtHeader;
public TextView txtFooter;
public ViewHolder(View v) {
super(v);
txtHeader = (TextView) v.findViewById(R.id.firstLine);
txtFooter = (TextView) v.findViewById(R.id.secondLine);
}
}
public void add(int position, MainListItem item) {
mDataset.add(position, item);
notifyItemInserted(position);
}
public void remove(MainListItem item) {
int position = mDataset.indexOf(item);
mDataset.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public MainGridAdapter(List<MainListItem> myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
@Override
public MainGridAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_item_grid_line, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
OnClickListener clickListener = new OnClickListener() {
@Override
public void onClick(View v) {
onItemClicked(position);
}
};
holder.itemView.setOnClickListener(clickListener);
holder.txtHeader.setOnClickListener(clickListener);
holder.txtFooter.setOnClickListener(clickListener);
final MainListItem item = mDataset.get(position);
holder.txtHeader.setText(item.getTitle());
if (TextUtils.isEmpty(item.getDescription())) {
holder.txtFooter.setVisibility(View.GONE);
} else {
holder.txtFooter.setVisibility(View.VISIBLE);
holder.txtFooter.setText(item.getDescription());
}
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mDataset.size();
}
public abstract void onItemClicked(int position);
}
在绑定事件中实现单击处理程序,使其只有一个事件实现
执行此:
mAdapter = new MainGridAdapter(listItems) {
@Override
public void onItemClicked(int position) {
showToast("Item Clicked: " + position, ToastPlus.STYLE_INFO);
}
};
同样可以做长时间点击
以下是我所做的。这个解决方案同时支持onClick和onLongClick在两个RecyclerView项目和视图内的RecyclerView项目(内部视图)。
我在我选择的视图上标记viewHolder:
public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_item, null);
ViewHolder viewHolder = new ViewHolder(itemView);
itemView.setOnClickListener( this);
itemView.setOnLongClickListener(this);
viewHolder.imageIV.setOnClickListener(this);
viewHolder.imageIV.setOnLongClickListener(this);
viewHolder.imageIV.setTag(viewHolder);
itemView.setTag(viewHolder);
return viewHolder;
}
我使用holder.getPosition()在onClick()方法中检索位置(onLongClick类似):
public void onClick(View view) {
ViewHolder holder = (ViewHolder) view.getTag();
int position = holder.getPosition();
if (view.getId() == holder.imageIV.getId()){
Toast.makeText(context, "imageIV onClick at" + position, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "RecyclerView Item onClick at " + position, Toast.LENGTH_SHORT).show();
}
}
带有getChildPosition的变体也可以工作。请注意,对于内部视图,在onClick()中使用:
int position = recyclerView.getChildPosition((View)view.getParent());
在我看来,这个解决方案的优点是,当一个人点击图像,只有onclick()图像侦听器被调用,而当我结合Jacob的解决方案为一个RecyclerView项目视图和我的解决方案为内部视图的RecyclerView项目视图onclick()也被调用(当点击图像)。
这就是我最后需要的东西,以防有人发现它有用:
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View item) {
super(item);
item.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.d("RecyclerView", "onClick:" + getAdapterPosition());
}
});
}
}
来源:http://blog.csdn.net/jwzhangjie/article/details/36868515
推荐文章
- 在Java中从字符串中提取数字
- 在Android中,对话框被取消或被取消有什么区别?
- 套接字的连接超时和读超时之间的区别是什么?
- 在ScrollView触摸处理中的HorizontalScrollView
- Java整数到字节数组
- 如何设置Windows环境下Java的环境变量
- Java Swing revalidate() vs repaint()
- Java中文件中的行数
- 何时在Android中使用RxJava,何时使用Android架构组件中的LiveData ?
- 如何在Android项目中使用ThreeTenABP
- 指定的子节点已经有一个父节点。你必须先在子对象的父对象上调用removeView() (Android)
- 我的Android设备没有出现在adb设备列表中
- 在没有安装apk的情况下获取Android .apk文件的VersionName或VersionCode
- Fragment onResume() & onPause()不会在backstack上被调用
- 如何设置基线对齐为假提高性能在线性布局?