web-dev-qa-db-ja.com

ImageButtonのOnClickListenerとOnTouchListenerを組み合わせる方法

ユーザーがImageButtonをクリックしたときに何かする必要がありますbothOnClickListenerOnTouchListenerを実装する静的クラスを作成しようとしました

static class ClickListenerForScrolling implements OnClickListener, OnTouchListener 

次のメソッドがあります。

@Override
public void onClick(View v)

そして

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

この背後にある全体的なアイデアは、ユーザーが画像に触れたときにImageButtonの画像ソースを変更し、ユーザーがこのボタンをクリックしたときにタスクを実行することです。誰かがこれを行う方法についてのヒントを教えてもらえますか?

どちらの操作も「画面に指を置く-画面から指を離す」というジェスチャーで構成されているため、タッチ操作かクリック操作かを判断できません。したがって、この画像ボタンに両方のリスナーを実装すると、タッチ/クリックで画像が変化し、ボタンを押します。これらのイベントの決まった順序があるかどうかはわかりません...

ただし、これらのイベントを分離する場合は、アクションの1つに別のジェスチャーを定義する(ワイプして画像を変更するなど)か、イベントを処理する別の領域を作成する必要があります。たとえば、画像が収まらないボタン全体とフリーエリアはボタンクリックエリアとして機能します。

HTH

更新:

TouchEventClickEventよりも一般的であるため、最初に呼び出されることを理解しました。

public abstract boolean onTouch (View v, MotionEvent event)

リスナーがイベントを消費した場合はtrueを返し、そうでない場合はfalseを返します。したがって、イベントもOnClickListenerで処理する必要があるかどうかを実装で決定し、falseを返すだけです。

36
Sven Menschner

onTouchListenerは両方の動きを処理できます。

Switchevent.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のみを使用してクリックイベントを使用する方法です。

参考になれば幸いです。

12

このコードを使用してください:

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));
11
siarhei sin

使用する return false の代わりに return true

5
stannums

この問題には多くの解決策がありますが、私にとって最良の解決策は、setOnClickListenerを完全に排除することで、onTouchListener内でアクションがACTION_UPかどうかをチェックし、その内部で最後のアクションがACTION_DOWNかどうかをチェックします。

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

lastActionはintで、各ACTIONの最後に更新します

0
ArmaniDarknight