Android的View事件分发机制

Posted 呼啸

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android的View事件分发机制相关的知识,希望对你有一定的参考价值。

在了解View的事件分发机制前,需要先了解Activity的构成,然后从源码的角度来分析View的事件分发机制。

1.源码解析Activity的构成

点就事件用MotionEvent来表示。当一个点击事件产生后,事件最先传递给Activity,所以我们需要先了解一下Activity的构成。当我们写Activity时候会调用setContentView方法来加载布局。我们先来看下setContentView方法:

@Override
    public void setContentView(@LayoutRes int layoutResID) 
       getWindow().setContentView(layoutResID)
       initWindowDecorActionBar();
    

这里的getWindow()会得到什么呢?接着往下看。getWindow()返回mWindow:


    /**
     * Retrieve the current @link android.view.Window for the activity.
     * This can be used to directly access parts of the Window API that
     * are not available through Activity/Screen.
     *
     * @return Window The current window, or null if the activity is not
     *         visual.
     */
    public Window getWindow() 
        return mWindow;
    

这里的mWindow就是当前的winow。我们看下mWindow是怎么获取的:

final void attach(Context context, ActivityThread aThread,
            Instrumentation instr, IBinder token, int ident,
            Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            NonConfigurationInstances lastNonConfigurationInstances,
            Configuration config, String referrer, IVoiceInteractor voiceInteractor,
            Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken,
            IBinder shareableActivityToken) 
        attachBaseContext(context);

        mFragments.attachHost(null /*parent*/);

        mWindow = new PhoneWindow(this, window, activityConfigCallback);

在attach方法里,可以看到mWindow是创建的phoneWindow.所以上面的getWindow().setContentView()方法,实际调用的是phoneWindow的setContentView方法。在这个方法中,这样一句代码:

if (mContentParent == null)
	
		installDecor();
	

紧接着,我们看installDecorf()方法源码:

private void installDecor()
	if (mDecor == null)
	
		mDecor = generatorDecor();
		mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
		mDecor.setIsRootNamespace(true);
		if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0)
		
			mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
		
	
	if (mContentParent == null)
	
		mContentParent = generateLayout(mDecor);
	
	...

我们在installDecor()方法里,发现了这样一句代码:

if (mDecor == null)

	mDecor = generateDecor();

接着我们看下generateDecor()方法:

protected DecorView generateDecor()
	return new DecorView()

这里创建了一个DecorView。这个DecorView就是Activity中的根View。接着查看DecorView的源码。发现DecorView是PhoneWindow类的内部类。并且继承了FrameLayout。

在installDecor中,不仅有generatorDecor方法,还有另外一个重要的方法:getnerateLayout(DecorView drcor)

这个方法的主要内容就是根据不同的情况给layoutResource加载不同的布局。大家知道一个Activity包含一个Window对象,该对象是由PhoneWindow来实现的。PhoneWindow将DecorView作为整个应用窗口的根View,这个DecorView又将屏幕划分为两个区域:一个区域是TitlerView,另一个区域是ContentView。我们平常做应用所写的布局正是展示在ContentView中。

以上是关于Android的View事件分发机制的主要内容,如果未能解决你的问题,请参考以下文章

Android中View的事件分发机制

Android 源码解析View的touch事件分发机制

Android View体系从源码解析View的事件分发机制

Android事件分发机制总结

Android查缺补漏(View篇)--事件分发机制源码分析

android基础 -View的事件分发机制