Andriod中Style/Theme原理以及Activity界面文件选取过程浅析

从CAD图纸到GIS地图:手把手教你用Global Mapper处理DWG文件(含坐标配准) 本文详细介绍了如何使用Global Mapper将CAD图纸(DWG文件)转换为GIS地图,包括坐标配准、图层与属性转换等关键步骤。通过四参数变换和控制点匹配技术,确保数据精准转换,适用于测绘、城市规划等领域。文章还提供了高级处理技巧和质量控制流程,帮助用户高效完成GIS化工作。 阅读详情

                                                                

       

                                                                                          转载请注明出处:http://blog.youkuaiyun.com/qinjuning     



      通过对前面的一篇博文<从setContentView()谈起>的学习,我们掌握了Activity组件布局文件地创建过程以及

 其顶层控件DecorView,今天我们继续庖丁解牛---深入到其中的generateLayout()方法,步步为营掌握一下内容:

         1、Activity中Theme(主题)的系统定义以及使用之处;

         2、如何根据设置的Feature(属性)选择合适的布局文件。


 另外,对于下文中Theme和Style的概念进行一个简要说明:

      都是由<style />节点进行定义的。但应用在<application />和<activity />则为theme,应用在<View />则为style.


一、关于Theme主题的使用方法以及原理分析


    通常来说,可以直接使用系统定义好的Style/Theme,毕竟,系统为我们提供了丰富地选择。当然,你也可以

 自定义Theme,前提是该Theme必须继承与某个已经存在地Theme,否则编译器会提示错误的。

  1、 应用Theme属性两种方式

      ①、在AndroidManifest.xml文件中在<application/>或者<activity />节点设置android:theme属性.

      ②、直接在代码中调用方法setTheme()设置该Activity的主题,必须得在第一次调用setContentView()前设置,

  否则,也是没有效果的(具体原因可见后面分析)。

 

  2、原理分析

      Android的所有系统资源定义位置存放在 frameworks\base\core\res\ 路径下,编译时会形成apk文件,即

 framework-res.apk,所有应用程序共享。

     实际上任何Style/Theme也是一组自定义属性集合,其内置在Android系统资源中,如下所示:

            文件路径:frameworks\base\core\res\res\values\attrs.xml

  <!-- The set of attributes that describe a Windows's theme. -->
    <declare-styleable name="Window">
        <!-- 常见的Window属性  -->
        
        <attr name="windowBackground" />        //该界面所对应的背景图片, drawable / color
        <attr name="windowFrame" />             //该界面所对应的前景frontground图片, drawable / color
        <attr name="windowNoTitle" />           //是否带有title , boolean类型      
        <attr name="windowFullscreen" />        //是否全屏  ,  boolean类型      
        <attr name="windowIsFloating" />        //是否是悬浮窗类型 , boolean类型     
        <attr name="windowIsTranslucent" />     //是否透明 , boolean类型     
        <attr name="windowSoftInputMode" />     //设置键盘弹出来的样式 , 例如: adjustsize 等 ,其实也是int类型
        
        <!-- more 更多不常见地Window属性-->
        ...
      
    </declare-styleable>

      特殊的是如果某个自定义属性如果没有指名 format属性,那么该属性必须在当前已经定义,即该属性只是一个

  别名。

      大部分Android属性定义在 name = "Theme"的属性集合下(仅列出Window attrs):   

          文件路径:frameworks\base\core\res\res\values\attrs.xml

    <!-- These are the standard attributes that make up a complete theme. -->
    <declare-styleable name="Theme">
        <!-- Drawable to use as the overall window background.  There are a
             few special considerations you should use when settings this
             drawable:
        -->
        <attr name="windowBackground" format="reference" />
        <!-- Drawable to use as a frame around the window. -->
        <attr name="windowFrame" format="reference" />
        <!-- Flag indicating whether there should be no title on this window. -->
        <attr name="windowNoTitle" format="boolean" />
        <!-- Flag indicating whether this window should fill the entire screen. -->
        <attr name="windowFullscreen" format="boolean" />
        <!-- Flag indicating whether this is a floating window. -->
        <attr name="windowIsFloating" format="boolean" />
        <!-- Flag indicating whether this is a translucent window. -->
        <attr name="windowIsTranslucent" format="boolean" />
        <!-- Flag indicating that this window's background should be the
        	 user's current wallpaper. -->
        <attr name="windowShowWallpaper" format="boolean" />
        <!-- This Drawable is overlaid over the foreground of the Window's content area, usually
             to place a shadow below the title.  -->
        <!-- This Drawable is overlaid over the foreground of the Window's content area, usually
             to place a shadow below the title.  -->
        <attr name="windowContentOverlay" format="reference" />    
        <!--more -->     
     </declare-styleable>
   

     属性定义如上,Android系统中这些属性定义了很多Style/Theme ,常见的有如下 :

    android:theme="Theme"            //默认地Theme
    android:theme="Theme.Light"      //背景为白色  
    android:theme="Theme.Light.NoTitleBar"              //白色背景并无标题栏   
    android:theme="Theme.Light.NoTitleBar.Fullscreen"  //白色背景,无标题栏,全屏  
    android:theme="Theme.Black"                        //背景黑色  

     名称为"Theme"属性(系统默认的Theme)的定义为(仅copy部分关于Window属性的定义) : 

                  文件位于:frameworks\base\core\res\res\values\themes.xml

      <style name="Theme">
        <!-- Window attributes -->
        <item name="windowBackground">@android:drawable/screen_background_dark</item>
        <item name="windowFrame">@null</item>
        <item name="windowNoTitle">false</item>
        <item name="windowFullscreen">false</item>
        <item name="windowIsFloating">false</item>
        <item name="windowTitleSize">25dip</item>
        <item name="windowTitleBackgroundStyle">@android:style/WindowTitleBackground</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Activity</item>
        <item name="android:windowSoftInputMode">stateUnspecified|adjustUnspecified</item>    
     </style>

      该Theme作为一个超元素集,所有其他的Style/Theme则继承了它。例如:我们关于自定义的Theme必须显示从

  一个父Theme继承,如下:

   <!--自定义Theme 必须制定parent属性-->
   <style name="CustomTheme" parent="@android:style/Theme" >
      <item name="android:windowNoTitle">true</item>
      <item name="android:windowFrame">@drawable/icon</item>
      <item name="android:windowBackground">?android:windowFrame</item>
   </style>
         我们看看Android另外一个Theme.NoTitleBar属性定义,默认继承了 "Theme"集合。

 <!-- Variant of the default (dark) theme with no title bar -->
    <style name="Theme.NoTitleBar">
        <item name="android:windowNoTitle">true</item>
    </style>


    其实xml文件中声明的任何元素(包括属性),必须通过代码去获取他们的值,然后进行适当地逻辑运算。那么

 系统是在什么地方去解析这些Window属性,并且选择合适地布局文件?


二、Theme主题的解析以及布局文件的选取


      如果对setContentView()调用过程不太熟悉的朋友,可以先看看前面一篇博文<从setContentView()谈起>。

 今天我们深入到其中generateLayout()方法,该方法地主要作用就是解析这些Window属性,然后选择合适地

  布局文件作为我们地Activity或者Window界面地承载布局文件,即DecorView的直接子View。


    在进行具体分析之前,Android还提供了另外两种简单API让我们制定界面的风格,如下两个方法:
    
     1、requestFeature() 设定个该界面的风格Feature,例如,FEATURE_NO_TITLE(没有标题) 、 

       FEATURE_PROGRESS(标题栏带进度条) 。必须在setContentView()前调用,否则会报异常。 

            FEATURE属性定义在Window.java类
          
    2、getWindow().setFlags(),为当前的WindowManager.LayoutParams添加一些Flag。

            Flag标记定义在WindowManager.LayoutParams.java类。

      
   通过这两种方法隐藏状态栏和标题栏的例子为:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // hide titlebar of application
    // must be before setting the layout
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    // hide statusbar of Android
    // could also be done later
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.main);
}
    完整例子,可见于博文<Android隐藏状态栏和标题栏,相当于全屏效果>

      源码分析:

         这两个方法是在Window.java类实现的,如下:

public class Window {
	 /** Flag for the "options panel" feature.  This is enabled by default. */
    public static final int FEATURE_OPTIONS_PANEL = 0;
    /** Flag for the "no title" feature, turning off the title at the top
     *  of the screen. */
    public static final int FEATURE_NO_TITLE = 1;    
    /** Flag for the progress indicator feature */
    public static final int FEATURE_PROGRESS = 2;
    /** Flag for having an icon on the left side of the title bar */
    public static final int FEATURE_LEFT_ICON = 3;
    /** Flag for having an icon on the right side of the title bar */
    public static final int FEATURE_RIGHT_ICON = 4;
    /** Flag for indeterminate progress */
    public static final int FEATURE_INDETERMINATE_PROGRESS = 5;
    /** Flag for the context menu.  This is enabled by default. */
    public static final int FEATURE_CONTEXT_MENU = 6;      // 菜单
    /** Flag for custom title. You cannot combine this feature with other title features. */
    public static final int FEATURE_CUSTOM_TITLE = 7;
    
    //默认的FEATURES FEATURE_OPTIONS_PANEL & FEATURE_CONTEXT_MENU 
    protected static final int DEFAULT_FEATURES = (1 << FEATURE_OPTIONS_PANEL) |
            (1 << FEATURE_CONTEXT_MENU);
    //局部变量保存  保存设置的Feature ,按位操作。
    private int mFeatures = DEFAULT_FEATURES;
    
    //设置Feature , 按位操作添加进去
    public boolean requestFeature(int featureId) {
        final int flag = 1<<featureId;    
        mFeatures |= flag;  
        //当该Activity是否是某个Activity的子Activity,mContainer即代表父Activity的Window对象,一般为null
        mLocalFeatures |= mContainer != null ? (flag&~mContainer.mFeatures) : flag;
        return (mFeatures&flag) != 0;
    }
    
    public void addFlags(int flags) {
        setFlags(flags, flags);
    }
   
    /**
     * Set the flags of the window, as per the
     * {@link WindowManager.LayoutParams WindowManager.LayoutParams}
     * flags.
     * <p>Note that some flags must be set before the window decoration is
     * created .
     * These will be set for you based on the {@link android.R.attr#windowIsFloating}
     * attribute.
     * @param flags The new window flags (see WindowManager.LayoutParams).
     * @param mask Which of the window flag bits to modify.
     */
    //mask代表对应为的掩码,设置对应位时,需要先清空对应位的掩码,然后在进行或操作。类似的函数可以见于View.java类的setFlags()方法
    public void setFlags(int flags, int mask) {
        final WindowManager.LayoutParams attrs = getAttributes(); //当前的WindowManager.LayoutParams属性
        //将设置的flags添加至attrs属性中
        attrs.flags = (attrs.flags&~mask) | (flags&mask);  
        mForcedWindowFlags |= mask;
        if (mCallback != null) {    //Activity 和 Dialog 默认实现了Window.Callback接口
            mCallback.onWindowAttributesChanged(attrs);  //回调onWindowAttributesChanged()方法
        }
    }
    ...
}     

   其实也挺简单的,主要是逻辑运算符的操作。
          mFeatures  代表了当前Window的Feature值.
          flags           保存在当前WindowManager.LayoutParams.flag属性中。

 

  接下来具体分析generateLayout()方法.

        如果当前界面的DecorView对象为空(一般由setContentView()或者addContentView()调用),则会创建一个

   DecorView对象以及对应的装载xml布局的mContentParent对象。

 

    Step 1、创建DecorView对象

    private void installDecor() {
        if (mDecor == null) {
            mDecor = generateDecor();  //创建一个DecorView对象
            mDecor.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);  //设置焦点捕获动作
        }
        
        if (mContentParent == null) { //mContentParent作为我们自定义布局的Parent.
            mContentParent = generateLayout(mDecor);  //创建mContentParent。
            ...
        }
    }

       Step 2 、创建 mContentParent 对象

    protected ViewGroup generateLayout(DecorView decor) {
        // Apply data from current theme.
        TypedArray a = getWindowStyle();   //获得当前的Theme属性对应的TypedArray对象.
         
        //接下来都是对Attribute值的获取...,后续继续分析
        //是否是Dialog样式的界面 , android:windowIsFloating属性
        mIsFloating = a.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false);
        ...
    }

    首先获取系统自定义的Style对应的TypeArray对象,然后获取对应的属性值。我们继续分析getWindowStyle()

 方法。

      2.1、

    /**
     * Return the {@link android.R.styleable#Window} attributes from this
     * window's theme.
     */
    public final TypedArray getWindowStyle() {
        synchronized (this) {
            if (mWindowStyle == null) {
            	//调用Context类的相应方法,返回对应的TypedArray对象,参数为自定义属性集合  <declare-styleable name="Window">
                mWindowStyle = mContext.obtainStyledAttributes(com.android.internal.R.styleable.Window);
            }
            return mWindowStyle;
        }
    }
        调用Context类对应地obtainStyledAttributes()方法,参数传递的是 Window对应的自定义属性集合。

   2.2、

    /**
     * Retrieve styled attribute information in this Context's theme.  See
     * {@link Resources.Theme#obtainStyledAttributes(int[])}
     * for more information.
     *
     * @see Resources.Theme#obtainStyledAttributes(int[])
     */
    public final TypedArray obtainStyledAttributes(
            int[] attrs) {
    	//首先获取当前Theme对应的TypedArray对象
        return getTheme().obtainStyledAttributes(attrs);
    }
           由于Activity继承至ContextThemeWapprer类,ContextThemeWapprer重写了getTheme()方法。

     2.3

    @Override 
    public Resources.Theme getTheme() {
        if (mTheme != null) {              //第一次访问时,mTheme对象为null
            return mTheme;
        }
        // Theme 资源是否已经指定,没有选取默认Theme
        if (mThemeResource == 0) {        
            mThemeResource = com.android.internal.R.style.Theme;
        }
        initializeTheme();   //初始化Theme资源
        return mTheme;
    }
      首先,判断是否是第一次调用该方法,即是否创建了mTheme对象;

     其次,判断是否设置了该Theme所对应的资源ID,如果没有,则选取默认的theme style 

            即com.android.internal.R.style.Theme 。

      最后,初始化对应资源。

    /**
     * Called by {@link #setTheme} and {@link #getTheme} to apply a theme
     * resource to the current Theme object.  Can override to change the
     * default (simple) behavior.  This method will not be called in multiple
     * threads simultaneously.
     *
     * @param theme The Theme object being modified.
     * @param resid The theme style resource being applied to <var>theme</var>.
     * @param first Set to true if this is the first time a style is being
     *              applied to <var>theme</var>.
     */
    protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
        theme.applyStyle(resid, true);
    }

    private void initializeTheme() {
        final boolean first = mTheme == null;     //是否是第一次调用
        if (first) {
            mTheme = getResources().newTheme();   
            Resources.Theme theme = mBase.getTheme();  //调用ContextImpl类的getTheme(),获取默认的Theme
            if (theme != null) {
                mTheme.setTo(theme);   //将theme配置应用到mTheme属性中
            }
        }
        onApplyThemeResource(mTheme, mThemeResource, first);
    }

      如果没有手动设置mThemeResource,则选取系统中为我们提供的默认Theme。当然我们也可以手动设置Theme 

 Resource ,如开篇所述。

            方法一: Activity中调用setTheme()方法,该方法会实现在ContextThemeWrapper.java类中。

     @Override 
     public void setTheme(int resid) {
         mThemeResource = resid;    //设置mThemeResource
         initializeTheme();
     }

         方法二:在AndroidManifest文件中,为Activity节点配置android:theme属性. 当通过startActivity()启动一个

 Activity时,会调用setTheme()方法。文件路径:frameworks\base\core\java\android\app\ActivityThread.java

    private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        ...
        Activity activity = null;
        try {
        	//创建Activity实例
            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
        } 
        ...
        try {
        	...
            if (activity != null) {
            	//创建相应的信息.
                ContextImpl appContext = new ContextImpl();
                appContext.init(r.packageInfo, r.token, this);
                appContext.setOuterContext(activity);
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                ...   
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstance,
                        r.lastNonConfigurationChildInstances, config);
                ...
                //activityInfo相关信息是由ActivityManagerService通过IPC调用而来
                //可以参考Android SDK的ActivityInfo类 API。
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme); //调用setTheme()方法,参见方法1
                }
          ...
            }
        }
        ...  
        return activity;
    }

     总结: 如果没有为设置Theme Resource ,则会选取默认的Theme Style,否则选用我们设置的Theme。

         因为mTheme对象是相对统一的,只不过每次都通过apply一个新的Style ID,感觉Android 框架会为每个

  应用程序的资源形成一个统一的资源库,应用程序定义的所有Style都存在在该资源库中,可以通过通过Style 

  ID值显示获取对应值集合。 但由于对系统获取资源的过程不了解,目前还不清楚Android中是如何根据资源ID

  获取对应的资源甚至一组资源的。但可喜的是,老罗目前正在研究这块,希望能在老罗的文章中找到答案。

              具体可见 <

Android资源管理框架(Asset Manager)简要介绍和学习计划

>

  

     另外,Dialog的构造函数也有一定启发性,创建了一个指定Theme 的ContextThemeWapper对象,然后通过它创

  建对应的Window对象。 具体过程可以自行研究下。

    public Dialog(Context context, int theme) {
    	//创建一个ContextThemeWrapper对象,指定 Theme ID
        mContext = new ContextThemeWrapper(
            context, theme == 0 ? com.android.internal.R.style.Theme_Dialog : theme);
        mWindowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        //传递该ContextThemeWrapper对象,构造指定的ID.
        Window w = PolicyManager.makeNewWindow(mContext);
        ...
    }

    PS : Android 4.0 之后默认的属性为Theme_Holo,呵呵,Holo倒挺有意思的。调用相关函数时,会判断SDK 

版本,然后选取相应地Theme。相关函数如下:   @ Resources.java 

    /** @hide */
    public static int selectDefaultTheme(int curTheme, int targetSdkVersion) {
        return selectSystemTheme(curTheme, targetSdkVersion,
                com.android.internal.R.style.Theme,
                com.android.internal.R.style.Theme_Holo,
                com.android.internal.R.style.Theme_DeviceDefault);
    }
    /** @hide */
    public static int selectSystemTheme(int curTheme, int targetSdkVersion,
            int orig, int holo, int deviceDefault) {
    	//是否设置了Theme
        if (curTheme != 0) {
            return curTheme;
        }
        //判断版本号 , HONEYCOMB 代表 Android 3.0 , ICE_CREAM_SANDWICH 代表 Android 4.0 
        if (targetSdkVersion < Build.VERSION_CODES.HONEYCOMB) {
            return orig;
        }
        if (targetSdkVersion < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            return holo;
        }
        return deviceDefault;
    }



  Step 3、通过前面的分析,我们获取了Window属性对应的TypeArray对象,接下来就是获取对应的属性值。

 如下代码所示:

     
    protected ViewGroup generateLayout(DecorView decor) {
        // Apply data from current theme.
        TypedArray a = getWindowStyle();   //获得当前的Theme属性对应的TypedArray对象.
         
        //是否是Dialog样式的界面 , android:windowIsFloating属性
        mIsFloating = a.getBoolean(com.android.internal.R.styleable.Window_windowIsFloating, false);
        int flagsToUpdate = (FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR) 
            & (~getForcedWindowFlags());
        //如果是Dialog样式,则设置当前的WindowManager.LayoutParams的width和height值,代表该界面的大小由布局文件大小指定。
        // 因为默认的WindowManager.LayoutParams的width和height是MATCH_PARENT,即与屏幕大小一致.
        if (mIsFloating) { 
            setLayout(WRAP_CONTENT, WRAP_CONTENT); 
            setFlags(0, flagsToUpdate); //取消FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR 位标记
        } else {
            setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);
        }
        //是否是没有标题栏 , android:windowNoTitle属性
        if (a.getBoolean(com.android.internal.R.styleable.Window_windowNoTitle, false)) {
            requestFeature(FEATURE_NO_TITLE); //添加FEATURE_NO_TITLE
        }
        //是否是全屏, android:windowFullscreen属性
        if (a.getBoolean(com.android.internal.R.styleable.Window_windowFullscreen, false)) {
            setFlags(FLAG_FULLSCREEN, FLAG_FULLSCREEN&(~getForcedWindowFlags()));
        }
        //是否是显示墙纸, android:windowShowWallpaper属性
        if (a.getBoolean(com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
            setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags()));
        }
        WindowManager.LayoutParams params = getAttributes(); //当前的WindowManager.LayoutParams对象
        if (!hasSoftInputMode()) {  //是否已经设置了softInputMode模式,可显示通过#setSoftInputMode()方法设定
            params.softInputMode = a.getInt(
                    com.android.internal.R.styleable.Window_windowSoftInputMode,//android:windowSoftInputMode
                    params.softInputMode);  //可以由 WindowManager.LayoutParams指定
        }
        //是否是某个Activity的子Activity,一般不是,getContainer()返回  null.
        if (getContainer() == null) {  
            if (mBackgroundDrawable == null) {   //获得了指定的背景图片.
                if (mBackgroundResource == 0) {  //获得了指定的背景图片资源
                    mBackgroundResource = a.getResourceId(  //背景图片id ,  android:windowBackground
                            com.android.internal.R.styleable.Window_windowBackground, 0);
                }
            }
            ...
        }
        // Inflate the window decor.
        int layoutResource;
        int features = getLocalFeatures(); // 等同于mFeatures,由requestFeature()设定.
        if ((features & ((1 << FEATURE_LEFT_ICON) | (1 << FEATURE_RIGHT_ICON))) != 0) {
        	//1、判断是否为对话框样式
            if (mIsFloating) {
                layoutResource = com.android.internal.R.layout.dialog_title_icons;
            } else {
                layoutResource = com.android.internal.R.layout.screen_title_icons;
            }
        }  
        else if { //2、进度条样式  ;  //3、自定义Title}
        else if ((features & (1 << FEATURE_NO_TITLE)) == 0) {
        	//4、没有标题栏
            // If no other features and not embedded, only need a title.
            // If the window is floating, we need a dialog layout
            if (mIsFloating) {
                layoutResource = com.android.internal.R.layout.dialog_title;
            } else {
                layoutResource = com.android.internal.R.layout.screen_title;
            }
            // System.out.println("Title!");
        } else {
            layoutResource = com.android.internal.R.layout.screen_simple;
        }
        View in = mLayoutInflater.inflate(layoutResource, null);
        decor.addView(in, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
        ...
        if (getContainer() == null) {
            Drawable drawable = mBackgroundDrawable;   
            if (mBackgroundResource != 0) {        //获取背景图片资源
                drawable = getContext().getResources().getDrawable(mBackgroundResource);
            }
            mDecor.setWindowBackground(drawable); //为DecorView设置背景图片
            drawable = null;
            //判断是否需要设置WindowFrame图片,该资源代表一个前景foreground图片,相对于背景background图片,
            if (mFrameResource != 0) {        //默认为null ,<item name="windowFrame">@null</item>
                drawable = getContext().getResources().getDrawable(mFrameResource);
            }
            mDecor.setWindowFrame(drawable);
        }
        return contentParent;             
    }

       依次取出对应的属性值,然后根据这些值调用不同的函数,例如:requestFeature(),以及为

  WindowMamager.LayoutParams设置Flag标记(这个掩码实现按位操作倒挺麻烦的,部分理解,有知道的朋友

  可以给我指点下。)例如:如果是对话框窗口,则不设置FLAG_LAYOUT_IN_SCREEN |   FLAG_LAYOUT_INSET_DECOR

  位标记,因为该标记代表对应的是Activity窗口。

         1、  FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR   代表的是典型的Activity窗口
         2、 FLAG_LAYOUT_IN_SCREEN                                                             代表的是典型的全屏窗口

         3、 其他则代表其他对话框窗口。

      最后,根据相应的Feature值,加载不同的布局文件。


    PS : 前些日子在论坛中看到有网友说取消/隐藏ActionBar,Android 4.0中对一个支持ActionBar的资源文件

  定义如下:    文件路径  frameworks\base\core\res\res\layout\screen_action_bar.xml

<!--
This is an optimized layout for a screen with the Action Bar enabled.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:fitsSystemWindows="true">
    <!-- Action Bar 对应的 View文件 -->
    <com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:attr/actionBarStyle">
        <com.android.internal.widget.ActionBarView
            android:id="@+id/action_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            style="?android: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="?android:attr/actionModeStyle" />
    </com.android.internal.widget.ActionBarContainer>
    <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" />
    <com.android.internal.widget.ActionBarContainer android:id="@+id/split_action_bar"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  style="?android:attr/actionBarSplitStyle"
                  android:visibility="gone"
                  android:gravity="center"/>
</LinearLayout>

    具体分析依旧见于generateLayout @ PhoneWindow.java ,  4.0 的源码咯。直接设置为gone状态不知可行否?



    At  Last ,下一步希望能整明白Android中对资源的获取过程,期望老罗同志给力咯。

 


      

     欢迎加入 Android联盟QQ群:55945620 ~~~~  Best Regards 


     








PCIe-Orders set Blocks之symbol对齐 有序集的使用场合很多,如在链路link阶段,进入polling后,便开始有序集的发送。一个 Ordered Set Block 包含一个同步头,后跟一个有序集。多通道链路的所有 Lane 必须同时传输相同的有序集,而且有序集的第一个符号定义了有序集的类型。但在PCIE中,8GT/s及以上的速率,采用的是128b/130b编码。128-bit是想要传输的payload,实际会传输130-bit,多出来的2-bit就是sync header。Block有两种,通过Sync header区分:10b:表示data 阅读详情

相关推荐

SV fork join_none & for循环结合使用

fork join_none与循环联用常见问题解决方案

ZhangShuHuai11的博客 880

Android 隐式启动匹配原则

1、Intent中只能包含一个Action,可以包含多个Category; 2、清单文件中一个Activity可配置多个IntentFilter, 一个IntentFilter可包含多个Action,多个Category,但是只能包含一个data; 3、Intent若含有Action,IntentFilter中包含多个Action,只要Intent中的Action与IntentFilter中的

Henry_Alpha的博客 1756

基于8086微机原理数字钟计时器系统设计

*单片机设计介绍,基于8086微机原理数字钟计时器系统设计。

2201_75940997的博客 1279

Android中Theme主题和Style样式使用介绍总结

一,Theme主题 1.1,Theme主题作用范围 Theme主要是针对应用级别的或者说窗体级别,可以设置应用主题(应用换肤效果)或者Activity的主题;主题是不能应用在某一个单独的View中; 1.2,Theme主题的定义 在AS中res/values/style.xml中定义,例如新建项目AS自动创建的Theme,是系统提供; <!-- Base application ...

ezconn的博客 2万+

Dify 进阶指南 | 5步打造智能JSON转换器(Excel数据预处理神器)

本文详细介绍了如何利用Dify平台的Chatflow功能,通过5个步骤构建一个智能JSON转换器,专门用于Excel数据预处理。该工具能够根据用户指令自动解析Excel表格,执行数据清洗、聚合计算,并精准输出定制化的JSON格式,极大提升前端开发、数据分析与测试工作的效率。

weixin_28520495的博客 575

cesium 实时轨迹

运用cesium中model和polyline添加模型和轨迹线,用CallbackProperty方法来实时改变经纬度。

God's asylum的博客 1964

android_基础_常见主题theme风格详解

本文出自门心叼龙的博客,转载请注明出处: https://blog.youkuaiyun.com/geduo_83/article/details/86560896 目录 1. 什么是Style,什么是Theme? 2. 在定义Theme的时候@符号和?符号有何区别? 3. 怎么通过代码给一个Activity设置主题? 4. AppTheme主题颜色colorPrimary,colorPrimaryDark,colorAccent都是什么的颜色? ​​5.常见的主题风格都有哪些? 6.ThemeOverlay使用特点

写bug的蚊子的博客 3516

数据挖掘实战-基于LSTM时间序列模型的香烟销售预测分析

本文介绍了基于LSTM时间序列模型的香烟销售预测分析实验。实验背景为烟草市场竞争激烈,企业需提高销售预测准确性以优化生产、库存和营销策略。LSTM模型因其处理长序列数据的能力被选为预测工具。实验步骤包括数据准备、特征工程、模型构建、训练与评估及结果分析。数据集来自某市门店的销售数据,技术工具为Python 3.9和Jupyter Notebook。实验过程涵盖数据导入、预处理、产品销售与区域销售分析、销售预测(包括销售额、销量、利润及海通店销售额预测)。

m0_64336780的博客 8952

android布局界面theme,Andriod中Style/Theme原理以及Activity界面文件选取过程浅析

通过对前面的一篇博文的学习,我们掌握了Activity组件布局文件地创建过程以及其顶层控件DecorView,今天我们继续庖丁解牛---深入到其中的generateLayout()方法,步步为营掌握一下内容:1、Activity中Theme(主题)的系统定义以及使用之处;2、如何根据设置的Feature(属性)选择合适的布局文件。另外,对于下文中Theme和Style的概念进行一个简要说明:都是由...

weixin_30991277的博客 591

如何成为一名高级数字 IC 设计工程师(6-7)数字 IC 验证篇:DEBUG 技巧

不懂验证的设计不是好的设计;UVM 验证思维是指导缜密的芯片设计的导师;推荐书籍《芯片验证漫游指南》。

新芯设计的博客 1605

下载MNIST数据集并使用python将数据转换成NumPy数组(源码解析)

下载MNIST数据集并使用python将数据转换成NumPy数组首先来分析init_mnist函数接下来继续分析load_mnist函数实现数据集转换的python脚本的代码显示MNIST图像并确认数据 下载MNIST数据集并将数据转换成NumPy数组的Python脚本里面最重要的就是load_mnist函数,其他项目想要调用数据集的话,就可以调用load_mnist函数,得到一个字典类型的数据,字典的值是一个Numpy数组。 这些过程是如何实现的,现在开始逐字逐句分析源码: 在load_mnist函数中第

及时总结 4268

Android——Theme和Style-由浅入深,全面讲解

Theme和Style-由浅入深,全面讲解

6897

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

Android Theme和Style区别联系

sda

Caesardadi的专栏 4416

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

android 用自定义样式设计界面,Android Style开发之Theme

1概述Theme是针对窗体设计的,用以改变窗体样式;Style是针对窗体元素的,用以改变指定控件或layout的样式。Android系统的themes.xml和style.xml文件位于frameworks/base/core/res/res/values中。里面涉及到很多.9.png文件,路径位于frameworks/base/core/res/res/drawable-hdpi2 系统主题分类...

weixin_39875167的博客 555

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Android 风格与主题(style and theme)

1、什么是Style,什么是Theme?         Style 和 theme:是一个包含一种 或者 多种格式化 属性 的集合  ,并且 style和theme都是资源,存放在res/values 文件夹下 即可,android提供了很多这样的默认资源。你可以来使用它们。同时你也可以自己定义style和 theme,只需要在res/values/这个路径里面新建一个.xml文件,而且他的根

快乐&&平凡 1万+

android黑屏日志_Android Theme以及解决启动黑屏的方法详解

前言本文主要介绍了关于Android Theme及解决启动黑屏的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧1.修改AndroidManifest.xml 设置App的全局Theme或者Activity的界面Themeandroid:allowBackup="true"android:icon="@drawable/ipod_icon"android:label="@s...

weixin_39824033的博客 383

如何在android中利用Theme设置application 的所有listview的style?~

今天看VLC的源代码,发现一个很神奇的东西 所有listview的点击效果背景色都是橘黄色 花了点时间找了一下看看怎么实现的。 首先,定义一个<selector> like this: <selector>   <item android:state_pressed="true">           <shape android:...

aoshunjian2584的博客 283

Android中的style与theme

android UI进阶之style和theme的使用 今天来和大家分享一下android中UI设计里面常会用到的style和theme。 首先,style和theme都是资源,android提供了很多这样的默认资源。你可以来使用它们。同时你也可以自己定义style和theme。这非常的简单,只需要在res/values/这个路径里面新建一个.xml文件,而且他的根节点必须是<r...

weixin_30345577的博客 81
上一篇: 写给自己和程序员的一些话(12年末-13年初总结)
下一篇: 从源码角度简要分析ActionBar框架
qinjuning
博客等级 码龄18年 5288粉丝 43原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值