26

ImageButton当用户单击我尝试创建一个实现两者 OnClickListener的静态类时,我需要做一些事情OnTouchListener

static class ClickListenerForScrolling implements OnClickListener, OnTouchListener 

具有以下方法:

@Override
public void onClick(View v)

@Override
public boolean onTouch(View arg0, MotionEvent arg1)

这背后的整个想法是ImageButton在用户触摸它时更改图像源,并在用户单击此按钮时执行任务。任何人都可以给我一个关于如何做到这一点的提示吗?

4

5 回答 5

36

由于这两个动作都包含“将手指放在屏幕上 - 将手指从屏幕上抬起”的手势,因此您无法确定它是触摸动作还是点击动作。因此,如果您在此图像按钮上实现两个侦听器,则触摸/单击将更改图片并按下按钮。不确定这些事件是否有确定的顺序......

但是,如果您想分离这些事件,您将需要为其中一个动作定义不同的手势(如擦除以更改图片),或者创建处理事件的不同区域,例如图像不适合整个按钮和空闲区域用作按钮单击区域。

高温高压

更新:

我发现, aTouchEvent比 a 更通用,ClickEvent因此首先调用它。

public abstract boolean onTouch (View v, MotionEvent event)

如果侦听器已经消费了事件,则返回 true,否则返回 false。所以你可以在你的实现中决定事件是否也应该由 OnClickListener 处理,然后只需 return false

于 2012-07-20T12:12:18.220 回答
13

onTouchListener能够处理这两种运动。

Switch之间的event.action()值来获得MotionEvent

case MotionEvent.ACTION_DOWN: 是第一个手指的影响。
case MotionEvent.ACTION_UP: 是手指离开的时候。

您必须将影响点设置在ACTION_DOWN.

TheImpactPoint=event.getX();

然后用ACTION_UP

float distance =TheImpactPoint-event.getX();

If distance = 0然后有一个点击,否则它会多于或少于零,具体取决于手势。

所以这是在没有真正的点击事件的情况下使用点击事件并且只使用onTouchListener.

希望会有用。

于 2013-03-05T22:14:30.260 回答
11

使用此代码:

public class GestureHelper implements OnTouchListener {

private final GestureDetector mGestureDetector;

public GestureHelper(Context context) {
    mGestureDetector = new GestureDetector(context, new GestureListener(this));
}

public void onSwipeRight() {
};

public void onSwipeLeft() {
};

public void onSwipeTop() {
};

public void onSwipeBottom() {
};

public void onDoubleTap() {
};

public void onClick() {
};

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

private static final class GestureListener extends SimpleOnGestureListener {

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

    public GestureListener(GestureHelper helper) {
        mHelper = helper;
    }

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

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        mHelper.onClick();
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        mHelper.onDoubleTap();
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        boolean result = false;
        try {
            float diffY = e2.getY() - e1.getY();
            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) {
                        mHelper.onSwipeRight();
                    } else {
                        mHelper.onSwipeLeft();
                    }
                }
            } else {
                if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
                    if (diffY > 0) {
                        mHelper.onSwipeBottom();
                    } else {
                        mHelper.onSwipeTop();
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }
}

}

扩展这个类并像这样使用......

view.setOnTouchListener(new SomeYourGestureHelper(context, someParameters));
于 2014-05-26T10:29:27.127 回答
6

使用return false代替return true

于 2015-07-13T09:03:51.740 回答
0

这个问题有很多解决方案,对我来说最好的一个是完全消除 setOnClickListener 并在 onTouchListener 内部检查动作是否为 ACTION_UP,然后在该内部检查之前的最后一个是否为 ACTION_DOWN:

case MotionEvent.ACTION_UP:
    if (lastAction == MotionEvent.ACTION_DOWN) {
        //code for click   
        .
        .
        lastAction = event.getAction();
    }

lastAction 是 int,我在每个 ACTION 结束时更新它

于 2018-10-21T01:37:25.803 回答