Android的clickable与事件分发关系详解
Posted 怪兽N
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android的clickable与事件分发关系详解相关的知识,希望对你有一定的参考价值。
android的clickable与事件分发关系详解
简介
Android里的View都可以通过clickable设置是否可以点击,对于点击及Android事件分发及处理理解有非常重要的作用。长话短说,开始吧。
设置影响
clickable是用于设置是否允许view的点击事件的配置标识,如果clickable=true那么"pressed"状态会被触发。如果需要显示点击效果,那么要设置clickable=true。这就是为什么像对TextView或LinearLayout等等这些View设置水纹点击效果时,需要添加clickable=true的原因。
/**
* Enables or disables click events for this view. When a view
* is clickable it will change its state to "pressed" on every click.
* Subclasses should set the view clickable to visually react to
* user's clicks.
*
* @param clickable true to make the view clickable, false otherwise
*
* @see #isClickable()
* @attr ref android.R.styleable#View_clickable
*/
public void setClickable(boolean clickable) {
setFlags(clickable ? CLICKABLE : 0, CLICKABLE);
}
当然我们也可以看到setOnClickListener也会将setClickable(true)
public void setOnClickListener(@Nullable OnClickListener l) {
if (!isClickable()) {
setClickable(true);
}
getListenerInfo().mOnClickListener = l;
}
设置Clickable与onTouchEvent(MotionEvent event)的关系
首先要也要留意下Enabled,设置View是否可用,注意可不可用都是可见的,比如Button设置不可用时Button是点击不了了,但是还是可见的呢。
/**
* Set the enabled state of this view. The interpretation of the enabled
* state varies by subclass.
*
* @param enabled True if this view is enabled, false otherwise.
*/
@RemotableViewMethod
public void setEnabled(boolean enabled) {
.....
}
下面看看onTouchEvent是怎么处理点击事件
public boolean onTouchEvent(MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
final int viewFlags = mViewFlags;
final int action = event.getAction();
//是否可以点击的判断 包括点击 长按
final boolean clickable = ((viewFlags & CLICKABLE) == CLICKABLE
|| (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)
|| (viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE;
if ((viewFlags & ENABLED_MASK) == DISABLED) {
if (action == MotionEvent.ACTION_UP && (mPrivateFlags & PFLAG_PRESSED) != 0) {
setPressed(false);
}
mPrivateFlags3 &= ~PFLAG3_FINGER_DOWN;
// A disabled view that is clickable still consumes the touch
// events, it just doesn't respond to them.
//不可用还是根据clickable确定是否会处理触摸事件
return clickable;
}
if (mTouchDelegate != null) {
if (mTouchDelegate.onTouchEvent(event)) {
return true;
}
}
//是否可点击或设置了提示文本, 如果符合这两个条件,最后一定返回true,则会处理处理事件
if (clickable || (viewFlags & TOOLTIP) == TOOLTIP) {
switch (action) {
case MotionEvent.ACTION_UP:
.....
break;
case MotionEvent.ACTION_DOWN:
....
break;
case MotionEvent.ACTION_CANCEL:
.....
break;
case MotionEvent.ACTION_MOVE:
.....
break;
}
return true;
}
//默认返回false
return false;
}
通过分析onTouchEvent(MotionEvent event)可以得到下面几点信息:
1 可以通过setClickable或者setOnClickableListener使View是否可以点击
2 要显示点击效果,那么要clickable=true
3 enable=false,clickable也生效
4 clickable=true那么会在onTouchEvent返回True,那么点击事件将被消费
总结
clickable的设置影响onTouchEvent的返回值,及press状态,对事件分发的处理有重大的影响。
以上是关于Android的clickable与事件分发关系详解的主要内容,如果未能解决你的问题,请参考以下文章