39

私は のViewPager中に を持っていScrollViewます。垂直方向だけでなく水平方向にもスクロールできる必要があります。これを達成するためには、横にスクロールできるように、ViewPagerタッチするたびに垂直スクロールを無効にする必要がありました ( )。v.getParent().requestDisallowInterceptTouchEvent(true);

しかし同時に、viewPager をクリックして全画面モードで開くことができるようにする必要があります。

問題は、onClick の前に onTouch が呼び出され、私の OnClick が呼び出されないことです。

オンタッチとオンクリックの両方を実装するにはどうすればよいですか?

viewPager.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        System.out.println("TOUCHED ");
        if(event.getAction() == MotionEvent.???){
            //open fullscreen activity
        }
        v.getParent().requestDisallowInterceptTouchEvent(true); //This cannot be removed
        return false;
    }
});

viewPager.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        System.out.println("CLICKED ");
        Intent fullPhotoIntent = new Intent(context, FullPhotoActivity.class);
        fullPhotoIntent.putStringArrayListExtra("imageUrls", imageUrls);
        startActivity(fullPhotoIntent);
    }
});
4

12 に答える 12

37

ユーザーが画面に触れる時間を確認することで、非常に簡単なことをしました。

private static int CLICK_THRESHOLD = 100;

@Override
public boolean onTouch(View v, MotionEvent event) {
    long duration = event.getEventTime() - event.getDownTime();

    if (event.getAction() == MotionEvent.ACTION_UP && duration < CLICK_THRESHOLD) {
        Log.w("bla", "you clicked!");
    }

    return false;
}

また、GestureDetectorにはこのような機能が組み込まれていることにも注意してください。onSingleTapUp を見てください

于 2015-06-10T08:40:19.767 に答える
10

両方を開発するのは間違った考えです。ユーザーが画面に触れることでさまざまなことを行う場合、ユーザーの目的を理解することは少し気の利いたものであり、そのためのコードを開発する必要があります。

2 つのソリューション:

1-(より良いアイデア) onTouch イベントでモーションがあるかどうかを確認します。次を使用して動きがあるかどうかを確認することで実行できます。

ACTION_UP
ACTION_DOWN
ACTION_MOVE

このようにしてください

if(event.getAction() != MotionEvent.ACTION_MOVE)

画面上のユーザーの指の動きの距離をチェックして、クリック中に偶発的な動きではなく動きが発生したことを確認することもできます. 次のようにします。

switch(event.getAction())
 {
     case MotionEvent.ACTION_DOWN:
              if(isDown == false)
              {
                     startX = event.getX();
                     startY = event.getY();
                     isDown = true;
              }
              Break;
        case MotionEvent.ACTION_UP
              {
                     endX = event.getX();
                     endY = event.getY();
                     break;
          }
}

上記のいずれも起こらなかった場合はクリックと見なし、クリックでやりたいことを行います。

2) UI に合う場合は、ボタンや画像ボタンなど、フル スクリーニング用の何かを作成し、onClick を設定します。

幸運を

于 2013-07-24T11:07:36.357 に答える
5

ユーザーのクリックとロングクリックを区別する必要がある場合があります。そうしないと、両方を同じものとして検出します。それを可能にするためにこれを行いました:

@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        startX = event.getX();
        startY = event.getY();

        bClick = true;
        tmrClick = new Timer();
        tmrClick.schedule(new TimerTask() {
            public void run() {
                if (bClick == true) {
                    bClick = false;
                    Log.d(LOG_TAG, "Hey, a long press event!");
                    //Handle the longpress event.
                }
            }
        }, 500); //500ms is the standard longpress response time. Adjust as you see fit.

        return true;
    case MotionEvent.ACTION_UP:
        endX = event.getX();
        endY = event.getY();

        diffX = Math.abs(startX - endX);
        diffY = Math.abs(startY - endY);

        if (diffX <= 5 && diffY <= 5 && bClick == true) {
            Log.d(LOG_TAG, "A click event!");
            bClick = false;
        }
        return true;
    default:
        return false;
    }
}
于 2014-12-15T23:32:09.173 に答える