A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 大山哥哥 于 2017-4-30 23:39 编辑

上一篇我们分析了Android事件分发的最基本的传递过程。也就是每一层都不处理也不拦截的传递过程。接下来我们就一块来分析一下。如果其中某层有拦截或者有处理的时候,事件是如何传递的。
为了大家查看方便。我们还是先把自定义控件的代码放到这里。这次,我们把MyFrameLayout和MyLinearLayout的onInterceptTouchEvent中返回true。看一下事件是如何传递的。
[AppleScript] 纯文本查看 复制代码
package com.itheima.touchdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

public class MyFrameLayout extends FrameLayout {

        public MyFrameLayout(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
                // TODO Auto-generated constructor stub
        }

        public MyFrameLayout(Context context, AttributeSet attrs) {
                super(context, attrs);
                // TODO Auto-generated constructor stub
        }

        public MyFrameLayout(Context context) {
                super(context);
        }

        // 事件处理
        @Override
        public boolean onTouchEvent(MotionEvent event) {
                System.out.println("FrameLayout---->onTouchEvent---start");
                boolean b = super.onTouchEvent(event);
                System.out.println("FrameLayout---->onTouchEvent---end---" + b);
                return b;
        }

        // 事件拦截
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
                System.out.println("FrameLayout---->onInterceptTouchEvent---start");
                boolean b = true;
                System.out.println("FrameLayout---->onInterceptTouchEvent---end---" +b);
                return b;
        }

        // 事件分发
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
                
                System.out.println(ev.getX() + "----- " + ev.getY());
                
                System.out.println("FrameLayout---->dispatchTouchEvent---start");
                boolean b = super.dispatchTouchEvent(ev);
                System.out.println("FrameLayout---->dispatchTouchEvent---end--->" + b);
                return b;
        }

}


同理自定义MyLinearLayout,并重写三个方法便于观察你:
[AppleScript] 纯文本查看 复制代码
package com.itheima.touchdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.LinearLayout;

public class MyLinearLayout extends LinearLayout {


        public MyLinearLayout(Context context, AttributeSet attrs) {
                super(context, attrs);
                // TODO Auto-generated constructor stub
        }

        public MyLinearLayout(Context context) {
                super(context);
                // TODO Auto-generated constructor stub
        }

        // 事件处理
        @Override
        public boolean onTouchEvent(MotionEvent event) {
                System.out.println("LinearLayout---->onTouchEvent---start");
                boolean b = super.onTouchEvent(event);
                System.out.println("LinearLayout---->onTouchEvent---end---" + b);
                return b;
        }

                // 事件拦截
                @Override
                public boolean onInterceptTouchEvent(MotionEvent ev) {
                        System.out.println("LinearLayout---->onInterceptTouchEvent---start");
                        boolean b = true;
                        System.out.println("LinearLayout---->onInterceptTouchEvent---end---" +b);
                        return b;
                }
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
                System.out.println("LinearLayout---->dispatchTouchEvent---start");
                boolean b = super.dispatchTouchEvent(ev);
                System.out.println("LinearLayout---->dispatchTouchEvent---end--->" + b);
                return b;
        }
}


自定义MyView,重写dispatchTouchEvent,onTouchEvent两个方法,并添加日志便于观察:
[AppleScript] 纯文本查看 复制代码
package com.itheima.touchdemo;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View {

        public MyView(Context context, AttributeSet attrs, int defStyle) {
                super(context, attrs, defStyle);
                // TODO Auto-generated constructor stub
        }

        public MyView(Context context, AttributeSet attrs) {
                super(context, attrs);
                // TODO Auto-generated constructor stub
        }

        public MyView(Context context) {
                super(context);
                // TODO Auto-generated constructor stub
        }
        // 事件处理
        @Override
        public boolean onTouchEvent(MotionEvent event) {
                System.out.println("View---->onTouchEvent---start");
                boolean b = super.onTouchEvent(event);
                System.out.println("View---->onTouchEvent---end---" + b);
                return b;
        }
        @Override
        public boolean dispatchTouchEvent(MotionEvent ev) {
                System.out.println("View---->dispatchTouchEvent---start");
                boolean b = super.dispatchTouchEvent(ev);
                System.out.println("View---->dispatchTouchEvent---end--->" + b);
                return b;
        }
}


Activity中初始化view时,动态将三个View依次嵌套起来:
[AppleScript] 纯文本查看 复制代码
package com.itheima.touchdemo;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        View view = init_view();
        setContentView(view);
    }

    private View init_view() {

        MyFrameLayout myFrameLayout = new MyFrameLayout(this);

        myFrameLayout.setBackgroundColor(Color.RED);

        MyLinearLayout myLinearLayout = new MyLinearLayout(this);

        myLinearLayout.setBackgroundColor(Color.GREEN);

        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(200, 200);

        params.gravity = Gravity.CENTER;

        myFrameLayout.addView(myLinearLayout, params);

        MyView myView = new MyView(this);

        myView.setBackgroundColor(Color.GRAY);
        LinearLayout.LayoutParams params1 = new LinearLayout.LayoutParams(100, 100);
        params1.gravity = Gravity.CENTER_VERTICAL;
        myLinearLayout.setGravity(Gravity.CENTER);
        myLinearLayout.addView(myView,params1);
//        FrameLayout.LayoutParams params2 = new FrameLayout.LayoutParams(100,
//                100);

//        params2.gravity = Gravity.CENTER;
//        myFrameLayout.setGravity(Gravity.CENTER);
//        myFrameLayout.addView(myView, params2);

        return myFrameLayout;
    }
}



红色的是MyFrameLayout,绿色的是MyLInearLayout,灰色的是MyView。现在我将手指按在灰色的区域按下时,事件的传递过程是这样的:
[AppleScript] 纯文本查看 复制代码
I/System.out: FrameLayout---->dispatchTouchEvent---start
I/System.out: FrameLayout---->onInterceptTouchEvent---start
I/System.out: FrameLayout---->onInterceptTouchEvent---end---true
I/System.out: FrameLayout---->onTouchEvent---start
I/System.out: FrameLayout---->onTouchEvent---end---false
I/System.out: FrameLayout---->dispatchTouchEvent---end--->false


因为最外成的MyFrameLayout中的onInterceptTouchEvent中返回了true。所以事件被MyFrameLayout拦截。事件不会再往下传递。MyFrameLayout拦截之后,会问自己的onTouchEvent,看自己处理不处理。onTouchEvent中返回的是flase,不处理。所以up事件都不会传递到MyFrameLayout中。

如果我们只在MyFrameLayout和MyLinearLayoutdeonTouchEvent中返回true。事件又是如何传递的呢?
down事件的log:
[AppleScript] 纯文本查看 复制代码
04-30 15:36:16.075 2367-2367/com.itheima.touchdemo I/System.out: FrameLayout---->dispatchTouchEvent---start
04-30 15:36:16.075 2367-2367/com.itheima.touchdemo I/System.out: FrameLayout---->onInterceptTouchEvent---start
04-30 15:36:16.075 2367-2367/com.itheima.touchdemo I/System.out: FrameLayout---->onInterceptTouchEvent---end---false
04-30 15:36:16.075 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->dispatchTouchEvent---start
04-30 15:36:16.075 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->onInterceptTouchEvent---start
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->onInterceptTouchEvent---end---false
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: View---->dispatchTouchEvent---start
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: View---->onTouchEvent---start
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: View---->onTouchEvent---end---false
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: View---->dispatchTouchEvent---end--->false
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->onTouchEvent---start
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->onTouchEvent---end---true
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->dispatchTouchEvent---end--->true
04-30 15:36:16.076 2367-2367/com.itheima.touchdemo I/System.out: FrameLayout---->dispatchTouchEvent---end--->true


up事件log:
[AppleScript] 纯文本查看 复制代码
04-30 15:36:39.106 2367-2367/com.itheima.touchdemo I/System.out: FrameLayout---->dispatchTouchEvent---start
04-30 15:36:39.107 2367-2367/com.itheima.touchdemo I/System.out: FrameLayout---->onInterceptTouchEvent---start
04-30 15:36:39.107 2367-2367/com.itheima.touchdemo I/System.out: FrameLayout---->onInterceptTouchEvent---end---false
04-30 15:36:39.107 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->dispatchTouchEvent---start
04-30 15:36:39.107 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->onTouchEvent---start
04-30 15:36:39.107 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->onTouchEvent---end---true
04-30 15:36:39.107 2367-2367/com.itheima.touchdemo I/System.out: LinearLayout---->dispatchTouchEvent---end--->true
04-30 15:36:39.107 2367-2367/com.itheima.touchdemo I/System.out: FrameLayout---->dispatchTouchEvent---end--->true


总结一下:
如果同时在onInterceptTouchEvent中返回true。谁在最外层,谁先处理事件。如果同时在onTouchEvent中返回true。谁在最里层谁先处理事件。

1 个回复

正序浏览
多谢分享
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马