わかりました。問題は「ロングクリックでトリガーできない、常にタッチリスナーが必要」ですが、これだけでは不十分です。詳細が必要です:
- ロングクリック、親ビュー、または子ビューのどのビューを処理することになっていますか?
- ロングクリックの処理に使用したリスナー、android.view.View.setOnLongClickListenerまたはandroid.view.GestureDetector?
実は先週同じ仕事をしました。私の経験は次のとおりです。android.view.View.setOnLongClickListenerもandroid.view.GestureDetectorも使用せず、親ビューのロングクリックを自分で処理します。View.javaは良い例です。
編集:
手元にコンパイラがないので、長押しを自分で処理する擬似コードを入力するだけです。実際のコードの場合、View.javaが最良の答えを提供します。
まず、アクションを実装するためのランナブルが必要です
class CheckForLongPress implements Runnable {
public void run() {
if (getParent() != null) {
// show toast
}
}
}
次に、onTouchEventを変更して長押しを検出します
boolean onTouchEvent(...) {
switch (event.getAction()) {
case MotionEvent.ACITON_DOWN:
// post a delayed runnable to detecting long press action.
// here mPendingCheckForLongPress is instance of CheckForLongPress
postDelayed(mPendingCheckForLongPress, ViewConfiguration.getLongPressTimeout());
...
break;
case MotionEvent.ACTION_MOVE:
// cancel long press action
if (distance(event, lastMotionEvent) > mTouchSlop) {
removeCallbacks(mPendingCheckForLongPress);
}
...
break;
case MotionEvent.ACTION_UP:
// cancel long press action
removeCallbacks(mPendingCheckForLongPress);
...
break;
もう一度編集:
以下は、疑似コードではなく実際のコードです。これは非常に単純で、View.onTouchEvent()で長押しを処理する方法を示しています。
public class ItemView extends View {
public ItemView(Context context) {
super(context);
}
public ItemView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ItemView(Context context, AttributeSet attrs) {
super(context, attrs);
}
Runnable mLongPressDetector = new Runnable() {
public void run() {
Toast.makeText(getContext(), "Hello long press", Toast.LENGTH_SHORT).show();
}
};
MotionEvent mLastEvent;
@Override
public boolean onTouchEvent(MotionEvent event) {
mLastEvent = MotionEvent.obtain(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
postDelayed(mLongPressDetector, ViewConfiguration.getLongPressTimeout());
break;
case MotionEvent.ACTION_MOVE:
final int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
if (Math.abs(mLastEvent.getX() - event.getX()) > slop ||
Math.abs(mLastEvent.getY() - event.getY()) > slop) {
removeCallbacks(mLongPressDetector);
}
break;
case MotionEvent.ACTION_UP:
removeCallbacks(mLongPressDetector);
break;
}
return true;
}
}