具有自定义基于视图的类的手势检测器
我希望您能帮助我弄清楚为什么我的 CustomView 类中定义的 OnSwipe、OnDoubleTap 和 onSingTapConfirmed 方法(使用以下行从活动 onCreate 实例化)
CustomView customView = new CustomView(this);
没有被调用。 CustomView 扩展了 View 并实现了 MyGestureListener 接口。请参阅下面的代码。
public class CustomView extends View implements MyGestureListener {
private MyGestureDetector mGestureDetector;
public CustomView(Context context) {
super(context);
mGestureDetector = new MyGestureDetector(context, this);
}
@Override
public boolean dispatchTouchEvent(MotionEvent me){
this.mGestureDetector.onTouchEvent(me);
return super.dispatchTouchEvent(me);
}
@Override
public void onSwipe(int direction) {
String str = "";
switch (direction) {
case MyGestureDetector.SWIPE_RIGHT :
str = "Swipe Right";
break;
case MyGestureDetector.SWIPE_LEFT :
str = "Swipe Left";
break;
case MyGestureDetector.SWIPE_DOWN :
str = "Swipe Down";
break;
case MyGestureDetector.SWIPE_UP :
str = "Swipe Up";
break;
}
Toast.makeText(getContext(), str, Toast.LENGTH_SHORT).show();
}
@Override
public void onDoubleTap() {
Toast.makeText(getContext(), "Double Tap", Toast.LENGTH_SHORT).show();
}
@Override
public void onSingleTapConfirmed() {
Toast.makeText(getContext(), "Single Tap", Toast.LENGTH_SHORT).show();
}
}
public class MyGestureDetector extends GestureDetector.SimpleOnGestureListener{
public final static int SWIPE_UP = 1;
public final static int SWIPE_DOWN = 2;
public final static int SWIPE_LEFT = 3;
public final static int SWIPE_RIGHT = 4;
public final static int MODE_TRANSPARENT = 0;
public final static int MODE_SOLID = 1;
public final static int MODE_DYNAMIC = 2;
private final static int ACTION_FAKE = -13;
private int swipe_Min_Distance = 100;
private int swipe_Max_Distance = 350;
private int swipe_Min_Velocity = 100;
private int mode = MODE_TRANSPARENT;
private boolean running = true;
private boolean tapIndicator = false;
private Context context;
private GestureDetector detector;
private MyGestureListener listener;
public MyGestureDetector(Context context, MyGestureListener sgl) {
this.context = context;
this.detector = new GestureDetector(context, this);
this.listener = sgl;
}
public void onTouchEvent(MotionEvent event){
if(!this.running)
return;
boolean result = this.detector.onTouchEvent(event);
if(this.mode == MODE_SOLID)
event.setAction(MotionEvent.ACTION_CANCEL);
else if (this.mode == MODE_DYNAMIC) {
if(event.getAction() == ACTION_FAKE)
event.setAction(MotionEvent.ACTION_UP);
else if (result)
event.setAction(MotionEvent.ACTION_CANCEL);
else if(this.tapIndicator){
event.setAction(MotionEvent.ACTION_DOWN);
this.tapIndicator = false;
}
}
//else just do nothing, it's Transparent
}
public void setMode(int m){
this.mode = m;
}
public int getMode(){
return this.mode;
}
public void setEnabled(boolean status){
this.running = status;
}
public void setSwipeMaxDistance(int distance){
this.swipe_Max_Distance = distance;
}
public void setSwipeMinDistance(int distance){
this.swipe_Min_Distance = distance;
}
public void setSwipeMinVelocity(int distance){
this.swipe_Min_Velocity = distance;
}
public int getSwipeMaxDistance(){
return this.swipe_Max_Distance;
}
public int getSwipeMinDistance(){
return this.swipe_Min_Distance;
}
public int getSwipeMinVelocity(){
return this.swipe_Min_Velocity;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
final float xDistance = Math.abs(e1.getX() - e2.getX());
final float yDistance = Math.abs(e1.getY() - e2.getY());
if(xDistance > this.swipe_Max_Distance || yDistance > this.swipe_Max_Distance)
return false;
velocityX = Math.abs(velocityX);
velocityY = Math.abs(velocityY);
boolean result = false;
if(velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance){
if(e1.getX() > e2.getX()) // right to left
this.listener.onSwipe(SWIPE_LEFT);
else
this.listener.onSwipe(SWIPE_RIGHT);
result = true;
}
else if(velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance){
if(e1.getY() > e2.getY()) // bottom to up
this.listener.onSwipe(SWIPE_UP);
else
this.listener.onSwipe(SWIPE_DOWN);
result = true;
}
return result;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
this.tapIndicator = true;
return false;
}
@Override
public boolean onDoubleTap(MotionEvent arg0) {
this.listener.onDoubleTap();
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent arg0) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent arg0) {;
this.listener.onSingleTapConfirmed();
return true;
}
static interface MyGestureListener{
void onSwipe(int direction);
void onDoubleTap();
void onSingleTapConfirmed();
}
}
I hope you can help me figure out why the OnSwipe, OnDoubleTap, and onSingTapConfirmed methods defined in my CustomView class which is instantiated from an activity onCreate using the following line -
CustomView customView = new CustomView(this);
are not getting called. The CustomView extends a View and implements MyGestureListener interface. See code below.
public class CustomView extends View implements MyGestureListener {
private MyGestureDetector mGestureDetector;
public CustomView(Context context) {
super(context);
mGestureDetector = new MyGestureDetector(context, this);
}
@Override
public boolean dispatchTouchEvent(MotionEvent me){
this.mGestureDetector.onTouchEvent(me);
return super.dispatchTouchEvent(me);
}
@Override
public void onSwipe(int direction) {
String str = "";
switch (direction) {
case MyGestureDetector.SWIPE_RIGHT :
str = "Swipe Right";
break;
case MyGestureDetector.SWIPE_LEFT :
str = "Swipe Left";
break;
case MyGestureDetector.SWIPE_DOWN :
str = "Swipe Down";
break;
case MyGestureDetector.SWIPE_UP :
str = "Swipe Up";
break;
}
Toast.makeText(getContext(), str, Toast.LENGTH_SHORT).show();
}
@Override
public void onDoubleTap() {
Toast.makeText(getContext(), "Double Tap", Toast.LENGTH_SHORT).show();
}
@Override
public void onSingleTapConfirmed() {
Toast.makeText(getContext(), "Single Tap", Toast.LENGTH_SHORT).show();
}
}
public class MyGestureDetector extends GestureDetector.SimpleOnGestureListener{
public final static int SWIPE_UP = 1;
public final static int SWIPE_DOWN = 2;
public final static int SWIPE_LEFT = 3;
public final static int SWIPE_RIGHT = 4;
public final static int MODE_TRANSPARENT = 0;
public final static int MODE_SOLID = 1;
public final static int MODE_DYNAMIC = 2;
private final static int ACTION_FAKE = -13;
private int swipe_Min_Distance = 100;
private int swipe_Max_Distance = 350;
private int swipe_Min_Velocity = 100;
private int mode = MODE_TRANSPARENT;
private boolean running = true;
private boolean tapIndicator = false;
private Context context;
private GestureDetector detector;
private MyGestureListener listener;
public MyGestureDetector(Context context, MyGestureListener sgl) {
this.context = context;
this.detector = new GestureDetector(context, this);
this.listener = sgl;
}
public void onTouchEvent(MotionEvent event){
if(!this.running)
return;
boolean result = this.detector.onTouchEvent(event);
if(this.mode == MODE_SOLID)
event.setAction(MotionEvent.ACTION_CANCEL);
else if (this.mode == MODE_DYNAMIC) {
if(event.getAction() == ACTION_FAKE)
event.setAction(MotionEvent.ACTION_UP);
else if (result)
event.setAction(MotionEvent.ACTION_CANCEL);
else if(this.tapIndicator){
event.setAction(MotionEvent.ACTION_DOWN);
this.tapIndicator = false;
}
}
//else just do nothing, it's Transparent
}
public void setMode(int m){
this.mode = m;
}
public int getMode(){
return this.mode;
}
public void setEnabled(boolean status){
this.running = status;
}
public void setSwipeMaxDistance(int distance){
this.swipe_Max_Distance = distance;
}
public void setSwipeMinDistance(int distance){
this.swipe_Min_Distance = distance;
}
public void setSwipeMinVelocity(int distance){
this.swipe_Min_Velocity = distance;
}
public int getSwipeMaxDistance(){
return this.swipe_Max_Distance;
}
public int getSwipeMinDistance(){
return this.swipe_Min_Distance;
}
public int getSwipeMinVelocity(){
return this.swipe_Min_Velocity;
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
final float xDistance = Math.abs(e1.getX() - e2.getX());
final float yDistance = Math.abs(e1.getY() - e2.getY());
if(xDistance > this.swipe_Max_Distance || yDistance > this.swipe_Max_Distance)
return false;
velocityX = Math.abs(velocityX);
velocityY = Math.abs(velocityY);
boolean result = false;
if(velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance){
if(e1.getX() > e2.getX()) // right to left
this.listener.onSwipe(SWIPE_LEFT);
else
this.listener.onSwipe(SWIPE_RIGHT);
result = true;
}
else if(velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance){
if(e1.getY() > e2.getY()) // bottom to up
this.listener.onSwipe(SWIPE_UP);
else
this.listener.onSwipe(SWIPE_DOWN);
result = true;
}
return result;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
this.tapIndicator = true;
return false;
}
@Override
public boolean onDoubleTap(MotionEvent arg0) {
this.listener.onDoubleTap();
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent arg0) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent arg0) {;
this.listener.onSingleTapConfirmed();
return true;
}
static interface MyGestureListener{
void onSwipe(int direction);
void onDoubleTap();
void onSingleTapConfirmed();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您应该在向下操作中返回 true ...否则永远不会调用其他回调操作...如 Android 文档
You should return true in down action ... otherwise the other callbacks action will never be called ...as explained in android doc