Android-处理listview项目上的单击和滑动

Android-处理listview项目上的单击和滑动,android,listview,android-listview,onclick,android-gesture,Android,Listview,Android Listview,Onclick,Android Gesture,我正在制作一个菜单,其中项目必须响应两种类型的事件: OnClick 如果用户单击该项,则应启动一项活动。每个按钮启动不同的活动 昂扬 当用户从右向左滑动项目时,应显示其名称。每个项目都有一个不同的名称,该名称将仅显示在屏幕上 在被刷卡的物品中 我尝试了很多不同的方法,在StackOverflow上搜索了很多教程和问题,但是我找不到合适的答案,我的实现仍然很差 我现在正在做的是为自定义适配器的getView方法中的每个项目设置OnClick句柄,在listView上设置一个gestureList

我正在制作一个菜单,其中项目必须响应两种类型的事件:

OnClick 如果用户单击该项,则应启动一项活动。每个按钮启动不同的活动

昂扬 当用户从右向左滑动项目时,应显示其名称。每个项目都有一个不同的名称,该名称将仅显示在屏幕上 在被刷卡的物品中

我尝试了很多不同的方法,在StackOverflow上搜索了很多教程和问题,但是我找不到合适的答案,我的实现仍然很差

我现在正在做的是为自定义适配器的getView方法中的每个项目设置OnClick句柄,在listView上设置一个gestureListener并处理onFling方法,但它并没有按预期的那样工作:大多数时候我尝试滑动,手势被处理为单击

我知道我可以使用像这样的实现,但我认为在这种情况下我不能使用onTouch事件技巧,因为我需要视图位置,以便我可以处理应该在Touch/click上启动哪些活动,或者哪个TextView应该可见

以下是我到目前为止的一些片段:

    final GestureDetector gestureDetector = new GestureDetector(
            new GestureListener());

    lvMenu.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(final View view, final MotionEvent event) {
            if (gestureDetector.onTouchEvent(event)) {
                return false;
            }

            return true;
        }
    });
内部类:

class GestureListener extends SimpleOnGestureListener {
    protected MotionEvent mLastOnDownEvent = null;

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

    @Override
    public boolean onFling(final MotionEvent e1, final MotionEvent e2,
            final float velocityX, final float velocityY) {
        Log.d("OnFling", "Called");
        final int SWIPE_MIN_DISTANCE = 20;
        final int SWIPE_MAX_OFF_PATH = 250;
        final int SWIPE_THRESHOLD_VELOCITY = 200;
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) {
                return false;
            }
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Log.i("A", "Right to Left");
            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                    && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                Log.i("B", "Left to Right");
            }
        } catch (final Exception e) {
            // nothing
        }
        return super.onFling(e1, e2, velocityX, velocityY);
    }
}
以及自定义适配器中的onClick方法:

public void onClick(final View v) {
                Intent i = null;
                switch (position) {
                case 0:
                    i = new Intent(parent.getContext(),
                            ProfileActivity.class);
                    break;
                case 1:
                    i = new Intent(parent.getContext(),
                            CatalogActivity.class);
                    break;
                case 2:
                    i = new Intent(parent.getContext(), GuideActivity.class);
                    break;
                case 3:
                    i = new Intent(parent.getContext(),
                            EventsActivity.class);
                    break;
                default:
                    Log.d("MenuActivity", "Switch default case.");
                    break;
                }
                if (i != null) {
                    parent.getContext().startActivity(i);
                }

            }
谢谢各位:

编辑1:现在我正在尝试为自定义适配器中的每个视图设置OnTouchListener。但它不起作用。。。我想不出原因

以下是我设置TouchListener的方式:

            convertView.setOnTouchListener(new MenuGestureHandler() {

            @Override
            public boolean onSwipeRight() {
                Log.d("Swipe Right", "OK!");
                return true;
            }

            @Override
            public void onClick() {
                Log.d("Click", "OK!");
            }

        });
这个类包含一些无用的代码,比如swipeUp、swipeDown:

public class MenuGestureHandler implements OnTouchListener {

GestureDetector gestureDetector = new GestureDetector(new GestureListener());

@Override
public boolean onTouch(final View v, final MotionEvent event) {
    return gestureDetector.onTouchEvent(event);
}

private final class GestureListener extends SimpleOnGestureListener {

    private static final int SWIPE_THRESHOLD = 100;
    private static final int SWIPE_VELOCITY_THRESHOLD = 100;

    @Override
    public boolean onSingleTapConfirmed(final MotionEvent e) {
        onClick(); // my method
        return super.onSingleTapConfirmed(e);
    }

    @Override
    public boolean onFling(final MotionEvent e1, final MotionEvent e2,
            final float velocityX, final float velocityY) {
        boolean result = false;
        try {
            final float diffY = e2.getY() - e1.getY();
            final float diffX = e2.getX() - e1.getX();
            if (Math.abs(diffX) > Math.abs(diffY)) {
                if (Math.abs(diffX) > SWIPE_THRESHOLD
                        && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffX > 0) {
                        result = onSwipeRight();
                    } else {
                        result = onSwipeLeft();
                    }
                }
            } else {
                if (Math.abs(diffY) > SWIPE_THRESHOLD
                        && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        result = onSwipeBottom();
                    } else {
                        result = onSwipeTop();
                    }
                }
            }
        } catch (final Exception exception) {
            exception.printStackTrace();
        }
        return result;
    }
}

public boolean onSwipeRight() {
    return false;
}

public boolean onSwipeLeft() {
    return false;
}

public void onClick() {
}

public boolean onSwipeTop() {
    return false;
}

public boolean onSwipeBottom() {
    return false;
}

编辑2我可以通过在我的GestureListener类中重写onDown方法并将其设置为始终返回true来使其工作。我真的不明白为什么我需要这样做,但它似乎现在正在工作

>P>这里可能有一些问题需要考虑,但首要的是触摸事件的层次。

根据我收集的信息,GestureDetector通过OnTouchListener连接到ListView,OnClickListener设置在ListView子视图的各个列表项上

这是一个问题,因为触摸处理顺序。ListView和任何ViewGroup都会首先将touch事件传递给其子视图,并且仅当且仅当没有子视图使用该事件时才直接处理该事件。具有OnClickListener的子视图将始终使用触摸事件,因为它正在跟踪触摸事件的点击事件…因此,现有的滑动检测器从未或很少看到任何事件

最简单的解决方案可能是避免在两个元素之间分离触摸处理。为每个列表项使用一个手势检测器,该列表项同时处理单击(即单次点击)和滑动,并确保已在项目本身上设置该手势检测器,而不是在父列表视图上设置该手势检测器


<>你也可以考虑看我的演讲,让你更详细地了解你正在处理的事情。

< P>我知道这是一个老问题,这里是未来搜索的答案:


好的,太好了。现在我明白了。。。但是我不能在每个项目上都附加一个OnTouchListener,我不知道为什么!它就是不起作用。。。你能帮我吗?我用最新的代码编辑了我的帖子。非常感谢你。