[英]How to handle multiple layout clicks in recyclerView in Android
In our app we have list of messages. 在我们的应用程序中,我们有消息列表。 We are switching to
RecyclerView
. 我们将切换到
RecyclerView
。 Our messages can consist from texts, images. 我们的信息可以包括文字,图像。 Sample message can look like this.
示例消息可能如下所示。
To handle clicks use this class: 要处理点击,请使用此类:
public class RecyclerViewItemClickListener implement RecyclerView.OnItemTouchListener {
public static interface OnItemClickListener {
public void onItemClick(View view, int position);
public void onItemLongClick(View view, int position);
}
private OnItemClickListener mListener;
private GestureDetector mGestureDetector;
public RecyclerViewItemClickListener(Context context, final RecyclerView recyclerView, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
@Override
public void onLongPress(MotionEvent e)
{
View childView = recyclerView.findChildViewUnder(e.getX(), e.getY());
if(childView != null && mListener != null)
{
mListener.onItemLongClick(childView, recyclerView.getChildAdapterPosition(childView));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
}
and we implement this clicks in activity like this: 我们在以下活动中实现这种点击:
chatView.setLongClickable(true);
chatView.addOnItemTouchListener(
new RecyclerViewItemClickListener(this, chatView, new RecyclerViewItemClickListener.OnItemClickListener() {
@Override public void onItemClick(View view, int position) {
//handleSingleClick(view, position);
}
@Override
public void onItemLongClick(View view, int position)
{
handleLongPress(position);
}
})
);
Clicks for message is working, now I want also handle userAvatar
clicks from same GestureDetection
. 点击消息的工作正常,现在我也要处理来自同一
GestureDetection
userAvatar
点击。 Is it possible to detect which list item layout was clicked from GestureDetector
? 是否可以检测到从
GestureDetector
单击了哪个列表项布局?
In other words, can I get GestureDetecter
clicked child. 换句话说,我可以让
GestureDetecter
单击子级GestureDetecter
? In my case click is set to whole item(avatar, text message, image). 在我的情况下,点击设置为整个项目(头像,短信,图片)。 Can I detect which element inside this item was clicked(for example I want catch avatar click).
我可以检测一下该项目内的哪个元素被点击了(例如,我想捕捉头像点击)。
Handle the click in the adapter of your RecyclerView like below example: 处理您的RecyclerView适配器中的单击,如下例所示:
private class BookmarkViewHolder extends RecyclerView.ViewHolder {
protected ImageView thumbnailIcon;
protected TextView postTitle;
protected TextView postViewCount;
public BookmarkViewHolder(View v) {
super(v);
thumbnailIcon = (ImageView) v.findViewById(R.id.thumbnailIcon);
postTitle = (TextView) v.findViewById(R.id.postTitleTV);
postViewCount = (TextView) v.findViewById(R.id.viewCountTV);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
thumbnailIcon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
postTitle.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
}
You may try this code : 您可以尝试以下代码:
GestureDetector detector;
then: 然后:
detector = new GestureDetector(MainActivity.this, MainActivity.this);
avatar.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View view, MotionEvent e) {
detector.onTouchEvent(e);
return false;
}
});
You can set listener into the adapter class. 您可以将侦听器设置为适配器类。 Here is the code :
这是代码:
ViewHolder class inside adapter : 适配器内的ViewHolder类:
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView textViewFirstName;
ImageView imageViewProfile;
public MyViewHolder(View view) {
super(view);
textViewFirstName = (TextView) view.findViewById(R.id.txtName);
imageViewProfile = (ImageView) view.findViewById(R.id.imageViewProfile);
//setOnClick
view.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//check if the image you want to click should not invoke listener from activity/fragment
if (v.getId() != R.id.imageViewProfile) {
if (mItemClickListener != null) {
mItemClickListener.onItemClick(v, getPosition());
}
}
}
}
Set your imageView click in Adapter class onBindViewHolder : 设置您的imageView单击Adapter类onBindViewHolder:
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.textViewFirstName.setText(mArrayListTypeDetials.get(position).getFirstname());
//set imageView click here
holder.imageViewProfile.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//ImageView clicked
}
});
}
Creating interface inside Adapter class : 在Adapter类中创建接口:
//interface for recyclerView item click
public interface OnItemClickListener {
void onItemClick(View view, int position);
}
/*
method to set listener to the adapter ViewHolder item
*/
public void setOnItemClickListener(final OnItemClickListener mItemClickListener) {
this.mItemClickListener = mItemClickListener;
}
Setting interface from Activity/Fragment : 从Activity / Fragment设置界面:
mAdapter.setOnItemClickListener(new Adapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Intent intent = new Intent(getActivity(), ABC.class);
startActivity(intent);
}
});
//init listener
rVDevicesList.addOnItemTouchListener(new RecyclerItemClickListener(getContext(),
rVDevicesList,
this, R.id.tv_wonderful_item_share, R.id.tv_wonderful_item_delete));
public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
private int[] extraIds;
private Rect childRect = new Rect();
public interface OnItemClickListener {
void onItemClick(View view, int position);
void onLongItemClick(View view, int position);
}
private GestureDetector mGestureDetector;
/**
*
* @param context
* @param recyclerView
* @param listener
* @param ids: an alternative parameter
*/
public RecyclerItemClickListener(Context context,
final RecyclerView recyclerView,
OnItemClickListener listener, final int... ids) {
mListener = listener;
extraIds = ids;
mGestureDetector = 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 && mListener != null) {
mListener.onLongItemClick(child, recyclerView.getChildAdapterPosition(child));
}
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
final float x = e.getX();
final float y = e.getY();
Log.d("onInterceptTouchEvent", "onInterceptTouchEvent: " + x + " " + y);
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
final int position = view.getChildAdapterPosition(childView);
View target = getViewBy(childView, x, y, extraIds);
//if target is non-null,so you click the view.
mListener.onItemClick(target, position);
return true;
}
return false;
}
/**
* find the view ,which view_rect contains the {x,y} in the window.
* @param view: this view is item layout view,may be a viewGroup
* @param x
* @param y
* @param ids
* @return true: hit a view which id in ids.
*/
private View getViewBy(View view, float x, float y, int... ids) {
if (ids == null || ids.length == 0 || !(view instanceof ViewGroup))
return view;
for (int i : ids) {
View vChild = view.findViewById(i);
if (vChild == null) {
Log.d("onInterceptTouchEvent", "null");
} else {
int xy[] = new int[2];
vChild.getLocationOnScreen(xy);
childRect.left = xy[0];
childRect.top = xy[1];
childRect.right = xy[0] + vChild.getWidth();
childRect.bottom = xy[1] + vChild.getHeight();
boolean hit = childRect.contains((int) x, (int) y);
Log.d("onInterceptTouchEvent", "find view: " + hit);
if (hit)
return vChild;
}
}
return view;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
}
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
} }
I tried this same way like @user320676, But I tried to complete with a Listener: 我尝试了类似@ user320676的方式,但是尝试使用Listener来完成:
interface MultipleClickListener {
void onItemClickOne(int position, View v);
void onItemClickTwo(int position, View v);
void onItemClickThree(int position, View v);
}
then you can use the listener in a activity or fragment. 那么您可以在活动或片段中使用侦听器。 Here you can see my full Adapter:
在这里,您可以看到我的完整适配器:
public class MultipleClicksAdapter extends RecyclerView
.Adapter<MultipleClicksAdapter
.DataObjectHolder> {
private ArrayList<MultipleClickData> mDataset;
private static MultipleClickListener sClickListener;
static class DataObjectHolder extends RecyclerView.ViewHolder {
@BindView(R.id.multiple_clicks_one_textView)
TextView mOne;
@BindView(R.id.multiple_clicks_two_textView)
TextView mTwo;
@BindView(R.id.multiple_clicks_three_textView)
TextView mThree;
DataObjectHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
mOne.setOnClickListener((View v) ->
sClickListener.onItemClickOne(getAdapterPosition(), mOne));
mTwo.setOnClickListener((View v) ->
sClickListener.onItemClickTwo(getAdapterPosition(), mTwo));
mThree.setOnClickListener((View v) ->
sClickListener.onItemClickThree(getAdapterPosition(), mThree));
}
}
void setOnItemClickListener(MultipleClickListener myClickListener) {
this.sClickListener = myClickListener;
}
MultipleClicksAdapter(ArrayList<MultipleClickData> myDataset) {
mDataset = myDataset;
}
@Override
public MultipleClicksAdapter.DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.multiple_clicks_list_item, parent, false);
MultipleClicksAdapter.DataObjectHolder dataObjectHolder = new MultipleClicksAdapter.DataObjectHolder(view);
return dataObjectHolder;
}
@Override
public void onBindViewHolder(MultipleClicksAdapter.DataObjectHolder holder, int position) {
holder.mOne.setText(mDataset.get(position).getmTitle());
holder.mTwo.setText(mDataset.get(position).getmSubTitle());
holder.mThree.setText(mDataset.get(position).getmThirdTitle());
}
@Override
public int getItemCount() {
return mDataset.size();
}
interface MultipleClickListener {
void onItemClickOne(int position, View v);
void onItemClickTwo(int position, View v);
void onItemClickThree(int position, View v);
}
}
Also you can check the complete code in GitHub . 您也可以在GitHub中查看完整的代码 。
单击需要在RecyclerView的 Adapter中进行处理,请访问RecyclerView示例,类似于ListView的 onItemClickListener
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.