View事件传递机制

view事件传递机制:
在安卓中的一些UI控件触摸(onTouch),点击(onClick)等事件并不是一触发就可以实现的,可是他们的可点击和可触摸等功能却可以实现,这是因为事件的响应先执行的是他们的父类View中dispatchTouchEvent方法,我们先看一个小Demo
        以ImageView为例:
1,只进行一个触摸的监听 OnTouchListener()
代码如下:
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView iv = (ImageView) findViewById(R.id.iv);
        iv.setOnTouchListener(new OnTouchListener() {            
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.e("iv_onTouch", event.getAction()+"");
                return false;
            }
        });
    }
}
触摸的响应事件常用的有三种:ACTION_DOWN=0; ACTION_UP=1; ACTION_MOVE=2
(1)当onTouch()方法返回false时
运行后的打印日志的结果为:0只执行按下的操作
(2)当onTouch()方法返回true时
运行后的打印日志的结果为:0,1,2三个行为都实现了
原因分析:通过看源码:
 public boolean dispatchTouchEvent(MotionEvent event) {
        if (mInputEventConsistencyVerifier != null) {
            mInputEventConsistencyVerifier.onTouchEvent(event, 0);
        }
       //不变,不用管
        if (onFilterTouchEventForSecurity(event)) {
            ListenerInfo li = mListenerInfo;
//只看这里的判断条件
            if (li != null && li.mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                return true;
            }
 if (onTouchEvent(event)) {
                return true;
            }
}


只有这个 li.mOnTouchListener != null条件是我们可以控制的,继续看源码,mOnTouchListener是在setOnTouchListener()方法中调用的,只要setOnTouchListener这个方法一创建,mOnTouchListener就被调用了,而我们已经在mainActivity中传递了这个方法,所以li.mOnTouchListener != null这个条件也是成立的,其他两个条件是恒成立的,因此整个条件是成立的,如果返回false的话,将会继续向下进行下面的条件判断onTouchEvent()
再看一下onTouchEvent()的源码,有一个条件语句
if(((viewFlags & CLICKABLE) == CLICKABLE ||
                    (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));
我们知道ImageView不具备可点击的属性,所以返回的就是false;
最后dispatchTouchEvent返回的就是false,不去效应事件
二。所以最终的结果是仅仅被按下。
  而当返回为true时,则会执行onTouch的三个方法ACTION_DOWN=0; ACTION_UP=1; ACTION_MOVE=2,所以会返回这三个结果
   
2,既执行触摸的监听OnTouchListener(),也执行点击的监听OnClickListener()

(1)前提是OnTouchEnevt
    返回false
    只有返回false dispatchTouchEvent才会
    进行下一次判断
代码如下:
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ImageView iv = (ImageView) findViewById(R.id.iv);
        iv.setOnTouchListener(new OnTouchListener() {            
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Log.e("iv_onTouch", event.getAction()+"");
                return false;
            }
        });
        iv.setOnClickListener(new OnClickListener() {            
            @Override
            public void onClick(View v) {
            Log.e("iv_onClick", "我被点击啦");                
            }
        });
    }
}
if           (onTouchEvent(event)) {
                return true;
            }
    在这个方法中会去判断一下
    这个控件是否具有可点击的属性
因为ImageView执行了setOnClickListener这个方法,通过这个方法ImageView就具备了可点击的功能了。
onTouchEvent(event)返回的就是true了,执行回掉的方法
执行的就是Action_Up 抬起的时候
执行了performClick
其实里面做的就是执行咱们onClick里面具体的逻辑实现。
当你不想让按钮执行OnClickListener这个方法,OnTouchEvent返回true就可以了。

阅读更多
个人分类: 安卓笔记 面试
上一篇Json解析的过程
下一篇安卓中的SuperNotCalledException
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭