我想在Recycler View中处理事件 -
class RecyclerTouchListener implements RecyclerView.OnItemTouchListener {
private ClickListener clickListener;
private GestureDetector gestureDetector;
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));
Log.i("TAG", "Radhe handling LongPress ");
}
}
});
}
@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 static interface ClickListener{
public void onClick(View view, int position);
public void onLongClick(View view, int position);
}
此外,我还有以下代码 -
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawerList);
filterAdapter = new FilterAdapter(getActivity(), getData());
recyclerView.setAdapter(filterAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
Log.i("TAG", "Radhe child Clicked ");
Toast.makeText(getActivity(),"CLick",Toast.LENGTH_SHORT).show();
}
@Override
public void onLongClick(View view, int position) {
Log.i("TAG", "Radhe child Long Clicked ");
Toast.makeText(getActivity(),"Long CLick",Toast.LENGTH_SHORT).show();
}
}));
return layout;
}
现在当我运行它时: - 和
有人能说出为什么会这样吗?我不知道它的原因。提前谢谢。
答案 0 :(得分:5)
当您从onClick
致电onInterceptTouchEvent
时,您需要return true
来表明该事件已被消耗,而不是继续为其发起事件。
addOnItemTouchListener
的Javadoc说:
一旦监听器从中返回true RecyclerView.OnItemTouchListener.onInterceptTouchEvent(RecyclerView, 它的动作 RecyclerView.OnItemTouchListener.onTouchEvent(RecyclerView, 将为每个传入的MotionEvent调用MotionEvent方法,直到 手势的结束。
和来自onInterceptTouchEvent
的错误表示
继续目前的行为并继续观察未来 手势中的事件。
只是为了澄清您现有的代码(但是我不确定您尝试使用if语句中的gestureDetector.onTouchEvent(e)实现了什么,请确保您不会意外地使用滚动事件):
@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 true;
}
return false;
}
答案 1 :(得分:3)
我通常在适配器中处理点击事件,并通过类似下面的界面与片段/活动进行交互。
在适配器的 onBindViewHolder ;
中viewHolder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mListener.onItemClicked(holder.aValue);
}
});
而mListener是一个带
的界面public interface IclickListener<T> {
void onItemClicked(T object);
}
答案 2 :(得分:0)
我的解决方案
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
if(e.getAction()==MotionEvent.ACTION_DOWN) return this.mGestureDetector.onTouchEvent(e);
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && this.mListener != null && this.mGestureDetector.onTouchEvent(e)) {
this.mListener.onItemClick(childView, view.getChildAdapterPosition(childView));
return true;
}
return false;
}
答案 3 :(得分:0)
我们可以利用Kotlin Extension Functions
用法
myView.setDebounceOnClickListener {
// your code
}
扩展功能
fun View.setDebounceOnClickListener(onDebounceClick: (View) -> Unit) {
val debounceClickListener = DebounceClickListener {
onDebounceClick(it)
}
setOnClickListener(debounceClickListener)
}
使用
/**
* Solves multiple click issue on view
*
* @param debounceDelayMillis delay millis which limits the rate at which a function gets invoked
* @param onDebounceCLick a lambda block which gonna run if the interval between clicks is greater than provided delay millis
*
*/
class DebounceClickListener(
private var debounceDelayMillis: Int = 1000,
private val onDebounceCLick: (View) -> Unit
) : View.OnClickListener {
private var lastTimeClicked: Long = 0L
override fun onClick(v: View) {
if (SystemClock.elapsedRealtime() - lastTimeClicked < debounceDelayMillis) {
return
}
lastTimeClicked = SystemClock.elapsedRealtime()
onDebounceCLick(v)
}
}
答案 4 :(得分:-1)
这应该解决它:
@Override
public boolean onSingleTapUp(MotionEvent e) {
if(e.getAction()==MotionEvent.ACTION_UP)
{
//do something
}
return true;
}
答案 5 :(得分:-1)
我注意到,如果您在recyclerview中有“ n”个项目,它将循环“ n”次。 最好只将侦听器放在项目上。但是,
“返回真”使它循环两次。放置一个标志以避免循环(不推荐)
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
if(counter[0] ==1) {
// code
counter[0]=0;
}
else counter[0] +=1;
return true;
}