2017-09-20 3 views
0

내 액티비티에는 전체 화면을 다루는 ScrollView에 TextView 세트가 포함되어 있습니다. TextView의 내용은 일반적으로 길이가 여러 페이지입니다.스 와이프 및 일반 스크롤 관련 문제

단일 탭, 두 번 탭, 왼쪽 스 와이프, 오른쪽 스 와이프 및 핀치로 구성된 터치 컨트롤을 활성화하려고합니다. 문제는 그러나 실수로 그 OnTouchListener 내 사용자 지정 내 텍스트 뷰에 사용되는 위 또는 아래있는 ScrollView 스크롤 (따라서 슬쩍 감지 취소) 여기

를 함께 왼쪽으로 스 와이프 할 수있는 사용자에 대한 어려움이나 오른쪽입니다

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가 위로 또는 아래로 스크롤하려고하기 때문에 사용자가 왼쪽 또는 오른쪽으로 fling을 활성화하는 것이 어렵습니다. 사용자가 왼쪽 및 오른쪽으로 쉽게 스 와이프 할 수있는 방법이 필요합니다. 아이디어가 있으십니까?

답변

0

가끔 가장 쉬운 대답이 가장 좋은 것으로 나타났습니다. onTouchListener를 textview가 아닌 ​​scrollview에 적용 했으므로 모든 것이 좋습니다. :)

관련 문제