2017-09-20 7 views
0

私のアクティビティには、画面全体をカバーするScrollViewのTextViewセットが含まれています。 TextViewのコンテンツは、通常、複数ページの長さです。スワイプと通常のスクロールに関する問題

私はシングルタップ、ダブルタップ、左スワイプ、右スワイプ、ピンチで構成されるタッチコントロールを有効にしようとしていますが、これらはうまくいきます。 問題はしかし、誤って上下にScrollViewのスクロール(ひいてはスワイプ検出をキャンセル)を左または右にスワイプするユーザーのための難しさである

ここでは、そのOnTouchListener私のカスタムは私のTextView

public class OnSwipeTouchListener implements OnTouchListener { 

private final GestureDetector gestureDetector; 
private boolean mTapConsumed = false; 
private int mTapsDetected = 0; 
private boolean mEnableTap = true; 

public OnSwipeTouchListener (Context ctx){ 
    gestureDetector = new GestureDetector(ctx, new GestureListener()); 
} 

private double mPinchOriginalDistance = 0; 
private float mPinchLastScale = 1.0f;    //scale change for current pinch action 
private ScrollView mScrollView; 

@Override 
public boolean onTouch(View v, MotionEvent event) { 

    mScrollView = (ScrollView) v.getParent(); 
    if(event.getPointerCount() == 2) { 
     mScrollView.requestDisallowInterceptTouchEvent(true); 
     mTapConsumed = true; 
     mTapsDetected = 0; 
     switch(event.getAction() & MotionEvent.ACTION_MASK){ 

      case MotionEvent.ACTION_POINTER_DOWN: 
       //pinch mode 
       float distx, disty; 
       //Get the current distance 
       distx = event.getX(0) - event.getX(1); 
       disty = event.getY(0) - event.getY(1); 
       mPinchOriginalDistance = Math.sqrt(distx * distx + disty * disty); 
       break; 

      case MotionEvent.ACTION_MOVE: 
       //Get the current distance 
       distx = event.getX(0) - event.getX(1); 
       disty = event.getY(0) - event.getY(1); 
       double distance = Math.sqrt(distx * distx + disty * disty); 
       if(mPinchOriginalDistance == 0) 
        break; 
       float scale = (float)(distance/mPinchOriginalDistance); 
       mPinchLastScale = scale; 
       onPinchScaleChange(scale); 
       break; 

      case MotionEvent.ACTION_POINTER_UP: 
       onPinchFinal(mPinchLastScale); 
       mPinchOriginalDistance = 0; 
       mPinchLastScale = 1.0f; 
       break; 

      default: 
       break; 
     } 
     return true; 
    } 
    else 
     return gestureDetector.onTouchEvent(event); 

} 

private final class GestureListener extends SimpleOnGestureListener { 

    private static final int SWIPE_THRESHOLD = 80; 
    private static final int SWIPE_VELOCITY_THRESHOLD = 60; 
    private final static int GESTURE_TAP_DELAY = 300; 
    private final static int GESTURE_FLING_DELAY = 1000; 


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

    @Override 
    public boolean onSingleTapUp(MotionEvent e) { 
     if(!mEnableTap) 
      return true; 
     mTapConsumed = false; 
     mTapsDetected++; 
     if(mTapsDetected == 1) 
      handler.postDelayed(checkTap, GESTURE_TAP_DELAY); 
     return true; 
    } 

    @Override 
    public boolean onDoubleTap(MotionEvent e) { 
     if(!mEnableTap) 
      return true; 
     mTapConsumed = false; 
     mTapsDetected++; 
     return true; 
    } 

    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     mEnableTap = false; 
     mTapConsumed = true; 
     mTapsDetected = 0; 
     handler.removeCallbacks(postFling); 
     handler.postDelayed(postFling, GESTURE_FLING_DELAY); //dont allow a tap to be registered for a certain time 
     boolean result = false; 
     try { 
      float diffY = e2.getY() - e1.getY(); 
      float diffX = e2.getX() - e1.getX(); 
      flingData(diffX, diffY); 
      if (Math.abs(diffX) > Math.abs(diffY)) { 

       if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
        if (diffX > 0) { 
         onSwipeRight(); 
        } else { 
         onSwipeLeft(); 
        } 
        result = true; 
       } 
      } 

     } catch (Exception exception) { 
      exception.printStackTrace(); 
     } 
     return result; 
    } 
} 

//Prevents a single tap being detected as well as a double tap  
private Handler handler = new Handler(); 
private Runnable checkTap = new Runnable() { 

    public void run() { 
     try { 
      if(!mTapConsumed && mTapsDetected >= 1) { 
       if(mTapsDetected > 1) 
        onTapDouble(); 
       else 
        onTapSingle(); 
       mTapsDetected = 0; 
      } 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

}; 

//Prevents a tap from being detected for a short duration after a fling has occurred 
private Runnable postFling = new Runnable() { 

    public void run() { 
     try { 
      mEnableTap = true; 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 
}; 



public void onSwipeRight() { 
} 

public void onSwipeLeft() { 
} 

public void onPinchScaleChange(float scale) { 
} 

public void onPinchFinal(float scale) { 
} 

public void onTapSingle() { 
} 

public void onTapDouble() { 
} 

public void flingData(float diffX, float diffY) 
{ 

} 
で使用されています

}

明確になります。 上記のコードは機能しますが、ScrollViewを上下にスクロールしたいので、ユーザーが左右のフライを起動することは困難です。 私はユーザーに左右にスワイプを簡単にする方法が必要です。 アイデア

答えて

0

場合によっては、最も簡単な答えが最適な場合があります。 私はonTouchListenerをtextviewではなくscrollviewに適用しました。 :)

関連する問題