您的位置:首页 > 移动开发 > Android开发

Android View,ViewGroup 事件分发

2015-11-27 18:23 465 查看
虽然一直原来也有看过相关方面的资料,并且用到的也不少了, 但是还是记一记吧, 希望大家都能明白理解

View 继承

Drawable.Callback,

KeyEvent.Callback,

AccessibilityEventSource

ViewRootImpl

frameworks/base/core/java/android/view/ViewRootImpl.java

View

frameworks/base/core/java/android/view/View.java

事件的传递(是由最外层的view 最先获取到)

ViewGroup - ViewGroup - view

View中的方法

事件分发

public boolean dispatchTouchEvent(MotionEvent ev)


事件拦截(默认返回false)

public boolean onInterceptTouchEvent(MotionEvent ev)


事件处理(默认返回false)

public boolean onTouchEvent(MotionEvent ev)


* 默认的分发 和处理结合起来,就类似是个闭环*

1

1.1 进入 最顶层父View 的 dispatchTouchEvent 进行事件分发

true 交给本身处理(进入onTouchEvent)

false 进入(方法onInterceptTouchEvent) 看是否拦截事件

如果拦截 返回true - (进入本View onTouchEvent)

不拦截 返回false - (传给子View)

1.2 子View相同判断

1.3 如果View发现自己没有子View 时,则自己处理。

2

2.1 如果子View的 onTouchEvent

返回false (既不做处理) onTouchEvent 事件会向父View传递,并由父View的onTouchEvent 接受

返回true (做处理) 既交给自身的 onTouchEvent 处理

当某个view 拦截,并且处理onTouchEvent

1. 源码 View 是如何获得 事件消息的

1.1 view 的初始化

public class View implements Drawable.Callback, KeyEvent.Callback,
AccessibilityEventSource {

// 初始化
public View(Context context, AttributeSet attrs, int defStyle) {

//
View() {
mResources = null;
}


1.2 attachInfo 的获取

/**
* @param info the {@link android.view.View.AttachInfo} to associated with
*        this view
*/
void dispatchAttachedToWindow(AttachInfo info, int visibility) {
//System.out.println("Attached! " + this);
mAttachInfo = info;
mWindowAttachCount++;
// We will need to evaluate the drawable state at least once.
mPrivateFlags |= PFLAG_DRAWABLE_STATE_DIRTY;
if (mFloatingTreeObserver != null) {
info.mTreeObserver.merge(mFloatingTreeObserver);
mFloatingTreeObserver = null;
}
if ((mPrivateFlags&PFLAG_SCROLL_CONTAINER) != 0) {
mAttachInfo.mScrollContainers.add(this);
mPrivateFlags |= PFLAG_SCROLL_CONTAINER_ADDED;
}
performCollectViewAttributes(mAttachInfo, visibility);
onAttachedToWindow();

ListenerInfo li = mListenerInfo;
final CopyOnWriteArrayList<OnAttachStateChangeListener> listeners =
li != null ? li.mOnAttachStateChangeListeners : null;
if (listeners != null && listeners.size() > 0) {
// NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
// perform the dispatching. The iterator is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
for (OnAttachStateChangeListener listener : listeners) {
listener.onViewAttachedToWindow(this);
}
}

int vis = info.mWindowVisibility;
if (vis != GONE) {
onWindowVisibilityChanged(vis);
}
if ((mPrivateFlags&PFLAG_DRAWABLE_STATE_DIRTY) != 0) {
// If nobody has evaluated the drawable state yet, then do it now.
refreshDrawableState();
}
needGlobalAttributesUpdate(false);
}


1.3获得 ViewRootImpl

/**
* Gets the view root associated with the View.
* @return The view root, or null if none.
* @hide
*/
public ViewRootImpl getViewRootImpl() {
if (mAttachInfo != null) {
return mAttachInfo.mViewRootImpl;
}
return null;
}


1.4 View 的 dispatchPointerEvent (这个就是传进来的重点了),得到了 dispatchTouchEvent 获得 MotionEvent

public final boolean dispatchPointerEvent(MotionEvent event) {
if (event.isTouchEvent()) {
return dispatchTouchEvent(event);
} else {
return dispatchGenericMotionEvent(event);
}
}


1.5接下来 dispatchTouchEvent ,会陆续传给其他

public boolean dispatchTouchEvent(MotionEvent event) {
if (mInputEventConsistencyVerifier != null) {
//=======================================================            mInputEventConsistencyVerifier.onTouchEvent(event, 0);
}

if (onFilterTouchEventForSecurity(event)) {
//noinspection SimplifiableIfStatement
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;
}
}

if (mInputEventConsistencyVerifier != null) {
mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);
}
return false;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息