setClickable 和 setEnable 事件分发影响

1、setEnable:
findViewById(R.id.iv).setEnabled(false)方法源码:将View的flag打上了DISABLED,如下:

    @RemotableViewMethod
	public void setEnabled(boolean enabled) {
		if (enabled == isEnabled()) return;
 
		setFlags(enabled ? ENABLED : DISABLED, ENABLED_MASK);
 
		/*
		 * The View most likely has to change its appearance, so refresh
		 * the drawable state.
		 */
		refreshDrawableState();
 
		// Invalidate too, since the default behavior for views is to be
		// be drawn at 50% alpha rather than to change the drawable.
		invalidate(true);
 
		if (!enabled) {
			cancelPendingInputEvents();
		}
	}

2、setClickable:
findViewById(R.id.iv).setClickable(false)方法源码:将View的flag打上了0或者
CLICKABLE标签,如下:

public void setClickable(boolean clickable) {
     setFlags(clickable ? CLICKABLE : 0, CLICKABLE);
}

如果设置了setOnClickListener()方法之后,默认标签也为true。 

影响到事件分发流程,主要有以下两处: 

 1、源码View.onTouchEvent()方法,如下:

/**
  * 源码分析:View.onTouchEvent()
  */
  public boolean onTouchEvent(MotionEvent event) {  
    final int viewFlags = mViewFlags;  

    if ((viewFlags & ENABLED_MASK) == DISABLED) {  
         
        return (((viewFlags & CLICKABLE) == CLICKABLE ||  
                (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE));  
    }  
    if (mTouchDelegate != null) {  
        if (mTouchDelegate.onTouchEvent(event)) {  
            return true;  
        }  
    }  

    // 若该控件可点击,则进入switch判断中
    if (((viewFlags & CLICKABLE) == CLICKABLE ||  
            (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) {  

                switch (event.getAction()) { 

                    // a. 若当前的事件 = 抬起View(主要分析)
                    case MotionEvent.ACTION_UP:  
                        boolean prepressed = (mPrivateFlags & PREPRESSED) != 0;  

                            ...// 经过种种判断,此处省略

                            // 执行performClick() ->>分析1
                            performClick();  
                            break;  

2、源码View.dispatchTouchEvent()方法,如下:


  public boolean dispatchTouchEvent(MotionEvent event) {  

        if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&  
                mOnTouchListener.onTouch(this, event)) {  
            return true;  
        } 
        return onTouchEvent(event);  
  }
  // 说明:只有以下3个条件都为真,dispatchTouchEvent()才返回true;否则执行onTouchEvent()
  //     1. mOnTouchListener != null
  //     2. (mViewFlags & ENABLED_MASK) == ENABLED
  //     3. mOnTouchListener.onTouch(this, event)

 

以上代码也是近期看事件分发时,发现的小细节问题,所以就记录了一下,也供大家参考一下,有问题可以讨论

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值