ユーザーがImageButton
をクリックしたときに何かする必要がありますbothOnClickListener
とOnTouchListener
を実装する静的クラスを作成しようとしました
static class ClickListenerForScrolling implements OnClickListener, OnTouchListener
次のメソッドがあります。
@Override
public void onClick(View v)
そして
@Override
public boolean onTouch(View arg0, MotionEvent arg1)
この背後にある全体的なアイデアは、ユーザーが画像に触れたときにImageButton
の画像ソースを変更し、ユーザーがこのボタンをクリックしたときにタスクを実行することです。誰かがこれを行う方法についてのヒントを教えてもらえますか?
どちらの操作も「画面に指を置く-画面から指を離す」というジェスチャーで構成されているため、タッチ操作かクリック操作かを判断できません。したがって、この画像ボタンに両方のリスナーを実装すると、タッチ/クリックで画像が変化し、ボタンを押します。これらのイベントの決まった順序があるかどうかはわかりません...
ただし、これらのイベントを分離する場合は、アクションの1つに別のジェスチャーを定義する(ワイプして画像を変更するなど)か、イベントを処理する別の領域を作成する必要があります。たとえば、画像が収まらないボタン全体とフリーエリアはボタンクリックエリアとして機能します。
HTH
更新:
TouchEvent
はClickEvent
よりも一般的であるため、最初に呼び出されることを理解しました。
public abstract boolean onTouch (View v, MotionEvent event)
リスナーがイベントを消費した場合はtrueを返し、そうでない場合はfalseを返します。したがって、イベントもOnClickListenerで処理する必要があるかどうかを実装で決定し、false
を返すだけです。
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
のみを使用してクリックイベントを使用する方法です。
参考になれば幸いです。
このコードを使用してください:
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));
使用する return false
の代わりに return true
この問題には多くの解決策がありますが、私にとって最良の解決策は、setOnClickListenerを完全に排除することで、onTouchListener内でアクションがACTION_UPかどうかをチェックし、その内部で最後のアクションがACTION_DOWNかどうかをチェックします。
case MotionEvent.ACTION_UP:
if (lastAction == MotionEvent.ACTION_DOWN) {
//code for click
.
.
lastAction = event.getAction();
}
lastActionはintで、各ACTIONの最後に更新します