2017-09-20 2 views
0

Meine Aktivität enthält ein TextView-Set in einer ScrollView, die den gesamten Bildschirm abdeckt. Der Inhalt in der Textansicht ist normalerweise mehrere Seiten lang.Probleme beim Wischen und normales Scrollen

Ich versuche Touch-Controls zu aktivieren, die aus einem Tippen, Doppeltippen, Streichen nach links, Streichen nach rechts und Kneifen bestehen und diese funktionieren gut. Das Problem jedoch ist die Schwierigkeit für den Benutzer mit zufällig nach links oder rechts bewegen, um die Scroll nach oben oder unten (und somit Aufheben der Swipe-Erkennung) Scrollen

Hier ist meine Gewohnheit OnTouchListener, dass auf meinem Textview verwendet wird

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) 
{ 

} 

}

Um klar zu sein. Der obige Code funktioniert, aber es ist schwierig für den Benutzer, eine Bewegung nach links oder rechts zu aktivieren, da die ScrollView nach oben oder unten scrollen möchte. Ich brauche einen Weg, um das Wischen nach links und rechts für den Benutzer einfacher zu machen. Irgendwelche Ideen?

Antwort

0

Stellt sich heraus, dass manchmal die einfachste Antwort die beste ist. Ich habe den onTouchListener auf die Scrollview und nicht auf die Textansicht angewendet und alles ist gut in der Welt. :)

Verwandte Themen