有没有办法在onClickListener
上设置RecyclerView
?
我有一个RecyclerView
,其中包含一些孩子,并在父OnClickListener
上设置了RecyclerView
。但是,单击该视图时onClick
不会触发。请参阅下面的示例代码 - 我们希望获得对父级的点击,不这些子级。在这种情况下,我们不关心项目的点击次数。
我尝试对孩子们进行setFocusable(false)
,setClickable(false)
和setOnClickListener(null)
无济于事。在任何情况下,我都认为孩子们没有从父母那里窃取点击,因为当我点击没有孩子的区域时,点击也不会注册。
package com.formagrid.hellotest;
import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.Arrays;
import java.util.List;
public class HelloActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hello);
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new RecyclerAdapter(Arrays.asList("hi", "this", "is", "some", "text"));
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("patricia", view.toString());
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
}
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.Holder> {
public class Holder extends RecyclerView.ViewHolder {
protected TextView textView;
public Holder(TextView itemView) {
super(itemView);
this.textView = itemView;
}
}
private List<String> contents;
public RecyclerAdapter(List<String> contents) {
this.contents = contents;
}
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
return new Holder(new TextView(parent.getContext()));
}
@Override
public void onBindViewHolder(Holder holder, int position) {
holder.textView.setText(contents.get(position));
}
@Override
public int getItemCount() {
return contents.size();
}
}
}
答案 0 :(得分:4)
有没有办法在
onClickListener
上设置RecyclerView
?
没有。也就是说,可以设置OnClickListener
,但RecyclerView
永远不会调用它。 RecyclerView
拦截所有触摸事件,但从不调用performClick()
,这是View
调用其侦听器的方式。
但是,您可以使用OnClickListener
和OnTouchListener
来模拟GestureDetector
。对于GestureDetector
的监听器,我们可以使用SimpleOnGestureListener
,仅使用onSingleTapUp()
方法。
class ClickListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
Toast.makeText(HelloActivity.this, "Clicked", 0).show();
return true;
}
};
然后我们只需要从GestureDetector
提供MotionEvent
OnTouchListener
s,然后检查返回以决定是否使用该事件,以免干扰滚动,拖动等等。
final GestureDetector detector = new GestureDetector(HelloActivity.this, new ClickListener());
mRecyclerView.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(detector.onTouchEvent(event)) {
return true;
}
return false;
}
}
);
请注意,上述解决方案几乎只适用于简单的&#34; RecyclerView
,就像问题中描述和给出的那样。如果您正在使用更多涉及的项目处理,例如拖放或滑动,我们需要在触摸事件链稍微进一步处理我们的手势检测。
为此,我们可以继承RecyclerView
并在dispatchTouchEvent()
方法中执行检测。如果检测到单击,我们只需拨打performClick()
即可点击RecyclerView
OnClickListener
。
public class ClickableRecyclerView extends RecyclerView {
private final GestureDetectorCompat detector;
public ClickableRecyclerView(Context context) {
this(context, null);
}
public ClickableRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
detector = new GestureDetectorCompat(context, new ClickListener());
}
private class ClickListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onSingleTapUp(MotionEvent e) {
performClick();
return true;
}
};
@Override
public boolean dispatchTouchEvent(MotionEvent e) {
detector.onTouchEvent(e);
return super.dispatchTouchEvent(e);
}
}
只需使用此子类代替常规RecyclerView
,并像往常一样在其上设置OnClickListener
。可能需要其他构造函数,具体取决于您如何实例化它。
答案 1 :(得分:1)
尝试在recyclayout或linearlayout或FrameLayout中包装您的recyclerview,然后将click监听器设置为relativelayout / linearlayout / framelayout。
<RelativeLayout
android:id="@+id/myLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
现在:
RelativeLayout rl = (RelativeLayout) findViewById(R.id.myLayout);
rl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.d("patricia", view.toString());
}
});
答案 2 :(得分:1)
这就是我用科特林风格所做的
fun RecyclerView.enableClickListener(){
val gesture = object : GestureDetector.SimpleOnGestureListener(){
override fun onSingleTapConfirmed(e: MotionEvent?): Boolean {
this@enableClickListener.performClick()
return super.onSingleTapConfirmed(e)
}
}
val detector = GestureDetector(this.context, gesture)
this.setOnTouchListener { v, event -> detector.onTouchEvent(event) }
}
这是使用方法
yourRecyclerView.apply {
enableClickListener()
setOnClickListener {
// Do what you want ...
}
}
享受:)
答案 3 :(得分:0)
这是个把戏,欢迎大家发表评论。
FrameLayout
中可以有2个子项。第一个是RecyclerView
,第二个是View
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<View
android:id="@+id/over_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</FrameLayout>
由于它是FrameLayout
,所以View
将位于RecyclerView
的上方,并且您可以将onClickListener
设置为View
,其行为将如果是点击的RecyclerView
over_view.setOnClickListener {
.....
}
答案 4 :(得分:-1)
RecycleView上的点击事件?试试这样:
Dialog