Mon activité contient un ensemble TextView dans un ScrollView couvrant l'intégralité de l'écran. Le contenu de TextView est généralement composé de plusieurs pages.Problème avec le balayage et le défilement normal
J'essaie d'activer les commandes tactiles comprenant un seul robinet, double tap, balayez vers la gauche, balayez vers la droite et pincer et cela fonctionne bien. Le problème est cependant la difficulté pour l'utilisateur de glisser à gauche ou à droite avec le défilement accidentellement ScrollView vers le haut ou vers le bas (et l'annulation d'où la détection swipe)
Voici mon habitude OnTouchListener qui est utilisé sur mon 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)
{
}
}
Pour être clair. Le code ci-dessus fonctionne mais il est difficile pour l'utilisateur d'activer une touche gauche ou droite car le ScrollView veut faire défiler vers le haut ou vers le bas. J'ai besoin d'un moyen de faire glisser à gauche et à droite plus facile pour l'utilisateur. Des idées?