• 热门专题

AndroidTouch系统简介(二)实例详解onInterceptTouchEvent与onTouchEvent的调用过程

作者:  发布日期:2014-05-21 20:14:18
Tag标签:实例  过程  简介  
  • 上一篇文章主要讲述了Android的TouchEvent的分发过程,其中有两个重要的函数:onInterceptTouchEvent和onTouchEvent,这两个函数可被重装以完成特定的逻辑。onInterceptTouchEvent的定义为于ViewGroup中,默认返回值为false,表示不拦截TouchEvent。onTouchEvent的定义位于View中,当ViewGroup要调用onTouchEvent时,会利用super.onTouchEvent。ViewGroup调用onTouchEvent默认返回false,表示不消耗touch事件,View调用onTouchEvent默认返回true,表示消耗了touch事件。考虑到onInterceptTouchEvent与onTouchEven在写UI的时候经常会用到,下面以一个例子来讲解一下。

    先创建一个类MyView,继承自View

    public class MyView extends Button {
        private static final String TAG = MyView.class.getName();
    
        public MyView(Context context){
            super(context);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            Log.d(TAG, "onTouchEvent.");
            LogUtil.logAction(event, TAG);
            return super.onTouchEvent(event);
        }
    }

    创建类MyLayout,继承自ViewGroup

    public class MyLayout extends FrameLayout{
        private static final String TAG = MyLayout.class.getName();
    
        public MyLayout(Context context) {
            super(context);
        }
    
        public MyLayout(Context context, AttributeSet attributeSet) {
            super(context, attributeSet);
        }
    
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            Log.d(TAG, "onInterceptTouchEvent");
    
            return super.onInterceptTouchEvent(ev);
        }
    
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            Log.d(TAG, "onTouchEvent.");
            LogUtil.logAction(event, TAG);
            return super.onTouchEvent(event);
        }
    }
    LogUtil.logAction()函数是用来打印MotionEvent的动作类型,代码如下:

    public class LogUtil {
        public static void logAction(MotionEvent event, final String tag) {
            int action = event.getAction();
            switch(action) {
                case MotionEvent.ACTION_DOWN:
                    Log.d(tag, "action down");
                    break;
                case MotionEvent.ACTION_CANCEL:
                    Log.d(tag, "action cancel");
                    break;
                case MotionEvent.ACTION_UP:
                    Log.d(tag, "action up");
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d(tag, "action move");
                    break;
                default:
                    Log.d(tag, "unknow action");
            }
        }
    }

    布局文件main.xml将MyView嵌套在MyLayout中,代码如下:

    <view android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          class="com.example.AndroidTest.MyLayout" xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/view">
        <com.example.AndroidTest.MyView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="hello" />
        
    </view>
    MainActivity的代码如下:

    public class MainActivity extends Activity {
        public static final String TAG = "TouchDemoActivity";
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
        }
    
    }

    程序启动后,截图如下。

    下面分情况讨论程序的运行结果。

    1、MyLayout的onInterceptTouchEvent返回false,MyView的onTouchEvent返回true

    情况1:当点击蓝色框内的任意位置,只于喎"http://www.it165.net/pro/pkqt/" target="_blank" class="keylink">QTXlMYXlvdXS74b3TytXKwrz+o6zK5LP2tcRMb2fI58/Co7o8L3A+CjxwPjxpbWcgc3JjPQ=="http://www.it165.net/uploadfile/files/2014/0521/20140521192931294.jpg" alt="">
    可以看出,touch事件最后会被MyLayout的onTouchEvent接收到。

    情况2: 点击红色框内的黑色区域,由于onInterceptTouchEvent()返回false,故MyView也能接收到touchEvent事件,输出的Log如下:


    可以看出,由于MyView的onTOuchEvent默认返回True,消耗了touch事件,MyLayout中的onTOuchEvent将不会被调用。

    当我们的手指按下黑色区域,停留几秒再抬起,得到的Log如下图:


    可以看出,第一个事件的类型为action down,最后一个为action up,中间的都是action move的类型,这正好符合上一篇文章介绍的Android的手势定义。

    2、MyLayout的onInterceptTouchEvent返回false,MyView的onTouchEvent返回false

    改写MyView中onTouchEvent的代码,令其返回false

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            Log.d(TAG, "onTouchEvent.");
            LogUtil.logAction(event, TAG);
            return false;
        }

    由于MyView没有消耗touch事件,MyLayout的onTouchEvent将会被调用,打印的log如下:

    可以看出,touch的类型只为action down。

    3、MyLayout的onInterceptTouchEvent返回true

    改写MyLayout中的onInterceptTouchEvent代码,令其返回true

        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            Log.d(TAG, "onInterceptTouchEvent");
    
            return true;
        }
    由于MyLayout拦截了touch事件,MyView中的onTouchEvent将不会被调用,log如下:

    n峨䴕Z喎Android的onInterceptTouchEvent和onTouchEvent的描述若有不妥之处,欢迎指正。

    本文参考的代码出自:两分钟彻底让你明白Android中onInterceptTouchEvent与onTouchEvent(图文)!,感谢作者的无私分享。

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规