检测一般的手势Detecting Common Gestures——翻译自developer.android.com Training

当你把一个或者过个手指放在屏幕上的时候就会产生一个触摸手势,你的应用会会把你的触摸的模式翻译成一个特别的手势。下面手势检测中的两个相应的阶段:

1.搜集触摸事件的数据。

2.翻译这个数据,来查看是否符合app支持的某个手势的类别。

支持的库类

这个案例中使用的类是GestureDetectorCopat和MotionEventCompa类。这些类都是在支持库当中的。如果你要兼容android1.6以上的设备,你需要使用兼容包。要注意MotionEventComat不是MotionEvent的替代类。而是它提供了一要接受想要的和事件相关的动作,二讲MotionEvent对象传递进去的那些个方法。

搜集数据

当用户把一个或者多个手指放在屏幕上的时候,view的回调函数onTouchEvent()就会被触发。对于每一个系列的触摸事件(位置,压力,大小,其他手指的附加信息)都会最终被定义为一个手势,onTouchEvent()会被调用很多次。

从用户的手指解除屏幕的时候一个手势就会开始,系统会追踪用户的手指们的位置,并捕获用户手指最终离开屏幕的最终事件。在整个交互过程中,MotionEvent会多次传递给onTouchEvent方法中,提供每一交互的细节。你的app通过MotionEvent中提供的数据来判断是不是一个它关注的事件发生了。


捕获一个Activity或者view的触摸事件

想要拦截在Activity或者View中的触摸事件,你要重写onTouchEvent回调方法。

下面的代码片使用getActionMasked()来从event参数中提取用户的行为。这给了你判断你关注的手势是否发生的毛数据。

public class MainActivity extends Activity {
...
// This example shows an Activity, but you would use the same approach if
// you were subclassing a View.
@Override
public boolean onTouchEvent(MotionEvent event){ 
        
    int action = MotionEventCompat.getActionMasked(event);
        
    switch(action) {
        case (MotionEvent.ACTION_DOWN) :
            Log.d(DEBUG_TAG,"Action was DOWN");
            return true;
        case (MotionEvent.ACTION_MOVE) :
            Log.d(DEBUG_TAG,"Action was MOVE");
            return true;
        case (MotionEvent.ACTION_UP) :
            Log.d(DEBUG_TAG,"Action was UP");
            return true;
        case (MotionEvent.ACTION_CANCEL) :
            Log.d(DEBUG_TAG,"Action was CANCEL");
            return true;
        case (MotionEvent.ACTION_OUTSIDE) :
            Log.d(DEBUG_TAG,"Movement occurred outside bounds " +
                    "of current screen element");
            return true;      
        default : 
            return super.onTouchEvent(event);
    }      
}
你可以通过自己的程序来处理这些事件来判断是一个手势。如果是一个典型的手势的话,你可能会这么做。但是如果你的app使用例如双击,长安,滑动或者类似的手势,你可以使用一个高级类,GestureDetector类。GestureDetector可以让你不用自己去处理每一个时间,来探测一些通常的手势。在下面的文章Detect Gestures中有详细的讨论。


捕获一个单独的View的触摸事件

一种使用onTouchEvent()的方法是,你可以使用setOnTouchListener的方法来附加一个View.OnTouchListener对象到View对象当中。这使得你可你不用拓展一个view类就可以监听一个触摸事件。例如:

View myView = findViewById(R.id.my_view); 
myView.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
        // ... Respond to touch events       
        return true;
    }
});
要当心如果创建了一个对于ACTION_DOWN事件返回一个false值的listener。如果你这样做的话,那么后续的ACTION_MOVE和ACTION_UP的一连串事件你都不会再被调用了。这是因为ACTION_DOWM是所有触摸事件的起始事件。

如果你创建了一个自定义的view,你可以如同上面那样重写onTouchEvent方法。


检测手势

android提供了GestureDetector类来检测一般的手势。它支持的手势包括onDown,onLongPress,onFling等等。你可以使用GestureDetector类,和上面的onTouchEvent方法相结合。

检测所有的支持的手势


当你实例化一个GestureDetector对象的时候,你需要传递一个GestureDetector.OnGestureListener接口。GestureDetector.OnGestureListener在特定的触摸事件发生的时候回通知用户。要做到让GestureDetector对象接收事件,你需要重写View或者Activity的onTouchEvent方法,病传输所有的观察到的事件到detetor实例当中。


下面的代码片,在一个onTouchEvent方法中返回了true,只是了你处理了这个触摸事件。如果返回值为false,那么这个事件就会被向下一直传递,直到在view栈当中被成功的处理了。


运行下面的代码来感受一下你在屏幕的触摸是如果触发动作的,以及每一个触摸动作产生的MotionEvent包含的内容。你可以看到每一个简单的交互产生了多少的数据。


public class MainActivity extends Activity implements 
        GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener{
    
    private static final String DEBUG_TAG = "Gestures";
    private GestureDetectorCompat mDetector; 

    // Called when the activity is first created. 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Instantiate the gesture detector with the
        // application context and an implementation of
        // GestureDetector.OnGestureListener
        mDetector = new GestureDetectorCompat(this,this);
        // Set the gesture detector as the double tap
        // listener.
        mDetector.setOnDoubleTapListener(this);
    }

    @Override 
    public boolean onTouchEvent(MotionEvent event){ 
        this.mDetector.onTouchEvent(event);
        // Be sure to call the superclass implementation
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onDown(MotionEvent event) { 
        Log.d(DEBUG_TAG,"onDown: " + event.toString()); 
        return true;
    }

    @Override
    public boolean onFling(MotionEvent event1, MotionEvent event2, 
            float velocityX, float velocityY) {
        Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
        return true;
    }

    @Override
    public void onLongPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onLongPress: " + event.toString()); 
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
            float distanceY) {
        Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());
        return true;
    }

    @Override
    public void onShowPress(MotionEvent event) {
        Log.d(DEBUG_TAG, "onShowPress: " + event.toString());
    }

    @Override
    public boolean onSingleTapUp(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTap(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent event) {
        Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent event) {
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());
        return true;
    }
}

检测一个支持的手势的子集

如果你想检测而几个手势,你可以继承GestureDetector.SimpleOnGesureListener,来替代GestureDetector.OnGestureListener接口。


GestureDetector.SimpleOnGestureListener提供一个所有的on<Touch>方法实现,每一个中的返回值都是false。这样你可以只重写你关心的方法。例如,下面的代码片创建了一个继承于Gesture.SimpleOnGestureListener,并重写了onFling()和onDown()方法。

无论你是否使用了GestureDetecor.OnGestureListener类,实现一个onDown方法并返回true都是最好的做法。这是因为所有的手势都是以一个onDown消息开始的。如果你在onDown中返回了false,那么按照GestrueDitector.SimpleOnGestureDetector的默认情况,系统会认为你想要忽略其他的手势,二其他的GestureDetector.OnGestureListener的方法就不再会被调用。这可以在你app中一起一个潜在的意外问题。为你你想要在onDown中返回false的情况就是你确定你想要忽略掉整个手势的时候。


public class MainActivity extends Activity { 
    
    private GestureDetectorCompat mDetector; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mDetector = new GestureDetectorCompat(this, new MyGestureListener());
    }

    @Override 
    public boolean onTouchEvent(MotionEvent event){ 
        this.mDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
    }
    
    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {
        private static final String DEBUG_TAG = "Gestures"; 
        
        @Override
        public boolean onDown(MotionEvent event) { 
            Log.d(DEBUG_TAG,"onDown: " + event.toString()); 
            return true;
        }

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2, 
                float velocityX, float velocityY) {
            Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());
            return true;
        }
    }
}




































  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值