我的活动包含一个覆盖整个屏幕的ScrollView中的TextView集。 TextView中的内容通常是多个页面。
我正在尝试启用触摸控制,包括单击,双击,向左滑动,向右滑动和捏合,这些工作正常。 然而问题是用户难以向左或向右滑动而不小心向上或向下滚动ScrollView(因此取消了滑动检测)
这是我在TextView上使用的自定义OnTouchListener
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 :(得分:0)
事实证明,有时最简单的答案是最好的。 我将onTouchListener应用于scrollview而不是textview,这一切在世界上都很好。 :)