将RecycEViewView.OnItemTouchListener中的MotionEvent传递给GestureDetectorCompat

时间:2014-10-23 08:23:53

标签: java android gesture android-recyclerview

我有一个实现RecyclerView.OnItemTouchListener的Fragment。如何将单击和长按动作事件从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) {

    }
}

2 个答案:

答案 0 :(得分:25)

您必须在GestureDetectorCompat方法中初始化onCreateView()

@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;
}

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);
    }
}

现在看一下(来自onCreateView()方法):

recyclerView.addOnItemTouchListener(this);

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

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

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

以下是对这些方法的含义的解释: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.OnItemTouchListener.html

您需要处理来自RecyclerView的单击和长按事件。

答案 1 :(得分:2)

我可能会迟到但是为了获得视觉反馈,请将其添加到list_item布局

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

此外,可以使用onSingleTapUp而不是onSingleTapConfirmed,因为攻丝通常很快。因此,如果您快速点击其他项目,您将无法正常工作。 为了快速点击,我更喜欢onSingleTapUp