java 将 MotionEvents 从 RecyclerView.OnItemTouchListener 传递给 GestureDetectorCompat

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26524003/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 10:04:51  来源:igfitidea点击:

Passing MotionEvents from RecyclerView.OnItemTouchListener to GestureDetectorCompat

javaandroidgestureandroid-recyclerview

提问by Binoy Babu

I have a Fragment that implemets RecyclerView.OnItemTouchListener. How do I pass click and long-click motion events onlyfrom the RecyclerView to the GestureDetectorCompat. That is I mean I only want to handle clicks and long-clicks, rest of the events should be handled by the RecyclerView as it would happen normally. How can I set this up?

我有一个实现 RecyclerView.OnItemTouchListener 的片段。如何单击和长按运动事件从 RecyclerView 传递到 GestureDetectorCompat。那就是我的意思是我只想处理点击和长按,其余的事件应该由 RecyclerView 处理,因为它会正常发生。我该如何设置?

public class MyFragment extends Fragment implements RecyclerView.OnItemTouchListener,
        GestureDetector.OnGestureListener {

    protected RecyclerView recyclerView;
    protected RecyclerView.Adapter adapter;
    protected LinearLayoutManager layoutManager;
    private GestureDetectorCompat detector;

    public MyFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.myfrag, container, false);

        recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview);

        layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.addOnItemTouchListener(this);

        adapter = new MyAdapter(myData));
        recyclerView.setAdapter(adapter);
        return rootView;
    }


    @Override
    public boolean onDown(MotionEvent e) {
        return false;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        return false;
    }

    @Override
    public boolean onInterceptTouchEvent(RecyclerView recyclerView, MotionEvent event) {
        return false;
    }

    @Override
    public void onTouchEvent(RecyclerView recyclerView, MotionEvent event) {

    }
}

回答by wpiwonski

You have to initialize GestureDetectorCompatin onCreateView()method:

您必须GestureDetectorCompatonCreateView()方法中初始化:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.myfrag, container, false);

    detector = new GestureDetectorCompat(getActivity(), new RecyclerViewOnGestureListener());

    recyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview);

    layoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.addOnItemTouchListener(this);

    adapter = new MyAdapter(myData));
    recyclerView.setAdapter(adapter);
    return rootView;
}

RecyclerViewOnGestureListeneris your own inner class extending SimpleOnGestureListener(that provides empty implementation of OnGestureListenermethods)

RecyclerViewOnGestureListener是您自己的内部类扩展SimpleOnGestureListener(提供OnGestureListener方法的空实现)

private class RecyclerViewOnGestureListener extends SimpleOnGestureListener {

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        View view = recyclerView.findChildViewUnder(e.getX(), e.getY());
        int position = recyclerView.getChildPosition(view);

        // handle single tap

        return super.onSingleTapConfirmed(e);
    }

    public void onLongPress(MotionEvent e) {
        View view = recyclerView.findChildViewUnder(e.getX(), e.getY());
        int position = recyclerView.getChildPosition(view);

        // handle long press

        super.onLongPress(e);
    }
}

Now look at line (from onCreateView()method):

现在看行(来自onCreateView()方法):

recyclerView.addOnItemTouchListener(this);

In our case 'this' is OnItemTouchListenercontaining two methods we need to implement:

在我们的例子中,'this'OnItemTouchListener包含两个我们需要实现的方法:

@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
    detector.onTouchEvent(e);
    return false;
}

@Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}

Here is an explanation what these methods mean: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.OnItemTouchListener.html

这里解释了这些方法的含义:https: //developer.android.com/reference/android/support/v7/widget/RecyclerView.OnItemTouchListener.html

It's all you need to handle single tap and long press events from RecyclerView.

这就是处理来自RecyclerView.

回答by Keshav

I might be late but for visual feedback add this to your list_item layout

我可能会迟到,但为了视觉反馈,将此添加到您的 list_item 布局

android:background="@drawable/tranparent_selector"
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"

Also, onSingleTapUp can be used instead of onSingleTapConfirmed as tapping is usually fast. So if you tap fast to other items you wont get it working. For fast tapping I prefer onSingleTapUp

此外,可以使用 onSingleTapUp 代替 onSingleTapConfirmed,因为点击通常很快。因此,如果您快速点击其他项目,您将无法使用它。为了快速点击,我更喜欢 onSingleTapUp