美文网首页
Window初步认识

Window初步认识

作者: pphdsny | 来源:发表于2018-01-04 15:29 被阅读49次

Window

该类是一个抽象类,提供了绘制窗口的一组通用API。

PhoneWindow

该类继承于Window类,是Window类的具体实现,即我们可以通过该类具体去绘制窗口。并且,该类内部包含了 一个DecorView对象,该DectorView对象是所有应用窗口(Activity界面)的根View。

DecorView

该类是一个FrameLayout的子类,并且是PhoneWindow的内部变量,该类就是对普通的FrameLayout进行功能的扩展,更确切点可以说是修饰(Decor的英文全称是Decoration,即“修饰”的意思),比如说添加TitleBar(标题栏),以及TitleBar上的滚动条等 。最重要的一点是,它是所有应用窗口的根View 。

包含ContentView和其他(StatusBar,ActionBar、ToolBar等)

ContentView

真正包含我们写的Layout的父布局,是DecorView的一个子类,可以通过findViewById(com.android.internal.R.id.content)拿到该对象。

生成ContentView的源码参考

//generateLayout
protected ViewGroup generateLayout(DecorView decor) {
  ...
    int layoutResource;
    int features = getLocalFeatures();
    // System.out.println("Features: 0x" + Integer.toHexString(features));
    if ((features & (1 << FEATURE_SWIPE_TO_DISMISS)) != 0) {
      layoutResource = R.layout.screen_swipe_dismiss;
    } else if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
      if (mIsFloating) {
        TypedValue res = new TypedValue();
        getContext().getTheme().resolveAttribute(
          R.attr.dialogTitleIconsDecorLayout, res, true);
        layoutResource = res.resourceId;
      } else {
        layoutResource = R.layout.screen_title_icons;
      }
      // XXX Remove this once action bar supports these features.
      removeFeature(FEATURE_ACTION_BAR);
      // System.out.println("Title Icons!");
    } else if ((features & ((1 << FEATURE_PROGRESS) | (1 << FEATURE_INDETERMINATE_PROGRESS))) != 0
               && (features & (1 << FEATURE_ACTION_BAR)) == 0) {
      // Special case for a window with only a progress bar (and title).
      // XXX Need to have a no-title version of embedded windows.
      layoutResource = R.layout.screen_progress;
      // System.out.println("Progress!");
    } else if ((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) {
      // Special case for a window with a custom title.
      // If the window is floating, we need a dialog layout
      if (mIsFloating) {
        TypedValue res = new TypedValue();
        getContext().getTheme().resolveAttribute(
          R.attr.dialogCustomTitleDecorLayout, res, true);
        layoutResource = res.resourceId;
      } else {
        layoutResource = R.layout.screen_custom_title;
      }
      // XXX Remove this once action bar supports these features.
      removeFeature(FEATURE_ACTION_BAR);
    } else if ((features & (1 << FEATURE_NO_TITLE)) == 0) {
      // If no other features and not embedded, only need a title.
      // If the window is floating, we need a dialog layout
      if (mIsFloating) {
        TypedValue res = new TypedValue();
        getContext().getTheme().resolveAttribute(
          R.attr.dialogTitleDecorLayout, res, true);
        layoutResource = res.resourceId;
      } else if ((features & (1 << FEATURE_ACTION_BAR)) != 0) {
        layoutResource = a.getResourceId(
          R.styleable.Window_windowActionBarFullscreenDecorLayout,
          R.layout.screen_action_bar);
      } else {
        layoutResource = R.layout.screen_title;
      }
      // System.out.println("Title!");
    } else if ((features & (1 << FEATURE_ACTION_MODE_OVERLAY)) != 0) {
      layoutResource = R.layout.screen_simple_overlay_action_mode;
    } else {
      // Embedded, so no decoration is needed.
      layoutResource = R.layout.screen_simple;
      // System.out.println("Simple!");
    }

    mDecor.startChanging();
    mDecor.onResourcesLoaded(mLayoutInflater, layoutResource);

    ViewGroup contentParent = (ViewGroup)findViewById(ID_ANDROID_CONTENT);
    //ID_ANDROID_CONTENT = com.android.internal.R.id.conten
  ...
}

通过源码会发现会根据设置主题的不同,ContentView的具体实现layout会不一样!举例说明screen_action_bar.xml(有actionBar)和screen_custom_title.xml(无actionBar)

  • screen_action_bar.xml
<com.android.internal.widget.ActionBarOverlayLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/decor_content_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:splitMotionEvents="false"
    android:theme="?attr/actionBarTheme">
    <FrameLayout android:id="@android:id/content"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent" />
    <com.android.internal.widget.ActionBarContainer
        android:id="@+id/action_bar_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        style="?attr/actionBarStyle"
        android:transitionName="android:action_bar"
        android:touchscreenBlocksFocus="true"
        android:gravity="top">
        <com.android.internal.widget.ActionBarView
            android:id="@+id/action_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="?attr/actionBarStyle" />
        <com.android.internal.widget.ActionBarContextView
            android:id="@+id/action_context_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"
            style="?attr/actionModeStyle" />
    </com.android.internal.widget.ActionBarContainer>
    <com.android.internal.widget.ActionBarContainer android:id="@+id/split_action_bar"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  style="?attr/actionBarSplitStyle"
                  android:visibility="gone"
                  android:touchscreenBlocksFocus="true"
                  android:gravity="center"/>
</com.android.internal.widget.ActionBarOverlayLayout>
  • screen_custom_title.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:fitsSystemWindows="true">
    <!-- Popout bar for action modes -->
    <ViewStub android:id="@+id/action_mode_bar_stub"
              android:inflatedId="@+id/action_mode_bar"
              android:layout="@layout/action_mode_bar"
              android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:theme="?attr/actionBarTheme" />

    <FrameLayout android:id="@android:id/title_container" 
        android:layout_width="match_parent" 
        android:layout_height="?android:attr/windowTitleSize"
        android:transitionName="android:title"
        style="?android:attr/windowTitleBackgroundStyle">
    </FrameLayout>
    <FrameLayout android:id="@android:id/content"
        android:layout_width="match_parent" 
        android:layout_height="0dip"
        android:layout_weight="1"
        android:foregroundGravity="fill_horizontal|top"
        android:foreground="?android:attr/windowContentOverlay" />
</LinearLayout>

setContentView()

Activity的setContetnView()最后会调用PhoneWindow的setContentView();


    @Override
    public void setContentView(int layoutResID) {
        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
        // decor, when theme attributes and the like are crystalized. Do not check the feature
        // before this happens.
        if (mContentParent == null) {
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            //如已经存在,会将之前的View都全部移除掉,所以setContentView可以反复调用
            mContentParent.removeAllViews();
        }

        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,
                    getContext());
            transitionTo(newScene);
        } else {
            mLayoutInflater.inflate(layoutResID, mContentParent);
        }
        mContentParent.requestApplyInsets();
        ...
    }

DectorView是在首次setContentView的时候才进行初始化的

    private void installDecor() {
        mForceDecorInstall = false;
        if (mDecor == null) {
            mDecor = generateDecor(-1);
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            mDecor.setIsRootNamespace(true);
            if (!mInvalidatePanelMenuPosted && mInvalidatePanelMenuFeatures != 0) {
                mDecor.postOnAnimation(mInvalidatePanelMenuRunnable);
            }
        } else {
            mDecor.setWindow(this);
        }
        if (mContentParent == null) {
            mContentParent = generateLayout(mDecor);
        }
        ...
    }

参考 http://blog.csdn.net/qinjuning/article/details/7226787

相关文章

  • Window初步认识

    Window 该类是一个抽象类,提供了绘制窗口的一组通用API。 PhoneWindow 该类继承于Window类...

  • 深入理解 WindowManagerService

    在上篇文章中 初步理解 Window 体系,我们初步分析了 Window 的体系,这篇文章我们分析一下 Windo...

  • 初步认识

    初识C语言 开始 我从高三毕业假期开始涉及C语言学习,经过了九个月左右的学习,初步认识了这种语言的语法和具体特质。...

  • 初步理解 Window 体系

    Android 中的 Window,是一个比较抽象的概念,总有一种说不清道不明的感觉,但是又非常重要。Activi...

  • 初步理解Window体系

    本文转载:https://www.jianshu.com/p/c5c3ef2b1b03 一、Window类型 An...

  • Java-GUI

    初步: AWT(Abstract Window Toolkit)包括了很多类和接口,用于Java Applicat...

  • BOM初步认识

    什么是BOM BOM:Browser Object Model 浏览器对象模型BOM是JavaScript组成之一...

  • 初步认识zookeeper

    什么是zookeeper zookeeper 是一个开源的分布式协调服务,由雅虎公司创建,是google chub...

  • [ZooKeeper]初步认识

    前言在学习任何技术知识的时候,一定要思考他的本质!3w原则想必都听过:why、what、how。大why,小wha...

  • 初步认识TCGA

    转自生信笔记http://www.bioinfo-scrounger.com/archives/271 肿瘤基因组...

网友评论

      本文标题:Window初步认识

      本文链接:https://www.haomeiwen.com/subject/rhvrnxtx.html