android中如何利用attrs和styles定义控件

一直有个问题就是,Android中是如何经过布局文件,就能实现控件效果的不一样呢?好比在布局文件中,我设置了一个TextView,给它设置了textColor,它就可以改变这个TextView的文本的颜色。这是如何作到的呢?咱们分3个部分来看这个问题1.attrs.xml  2.styles.xml  3.看组件的源码。 java

1.attrs.xml: android

 咱们知道Android的源码中有attrs.xml这个文件,这个文件实际上定义了全部的控件的属性,就是咱们在布局文件中设置的各种属性 git

你能够找到attrs.xml这个文件,打开它,全选,右键->Show In->OutLine。能够看到整个文件的解构 app

下面是两个截图: ide

 

 

咱们大概能够看出里面是Android中的各类属性的声明,好比textStyle这个属性是这样定义的: 布局

Java代码 复制代码  收藏代码
  1. <!-- Default text typeface style. -->   
  2.     <attr name="textStyle">   
  3.         <flag name="normal" value="0" />   
  4.         <flag name="bold" value="1" />   
  5.         <flag name="italic" value="2" />   
  6.     </attr>  
<!-- Default text typeface style. -->
    <attr name="textStyle">
        <flag name="normal" value="0" />
        <flag name="bold" value="1" />
        <flag name="italic" value="2" />
    </attr>

 那么如今你知道,咱们在写android:textStyle的时候为何会出现normal,bold和italic这3个东西了吧,就是定义在这个地方。 字体

再看看textColor: this

Java代码 复制代码  收藏代码
  1. <!-- Color of text (usually same as colorForeground). -->   
  2.     <attr name="textColor" format="reference|color" />  
<!-- Color of text (usually same as colorForeground). -->
    <attr name="textColor" format="reference|color" />

 format的意思是说:这个textColor能够以两种方式设置,要么是关联一个值,要么是直接设置一个颜色的RGB值,这个不难理解,由于咱们能够平时也这样作过。 spa

 

也就是说咱们平时在布局文件中所使用的各种控件的属性都定义在这里面,那么这个文件,除了定义这些属性外还定义了各类具体的组件,好比TextView,Button,SeekBar等所具备的各类特有的属性 .net

好比SeekBar:

 

Java代码 复制代码  收藏代码
  1. <declare-styleable name="SeekBar">   
  2.         <!-- Draws the thumb on a seekbar. -->   
  3.         <attr name="thumb" format="reference" />   
  4.         <!-- An offset for the thumb that allows it to extend out of the range of the track. -->   
  5.         <attr name="thumbOffset" format="dimension" />   
  6.     </declare-styleable>  
<declare-styleable name="SeekBar">
        <!-- Draws the thumb on a seekbar. -->
        <attr name="thumb" format="reference" />
        <!-- An offset for the thumb that allows it to extend out of the range of the track. -->
        <attr name="thumbOffset" format="dimension" />
    </declare-styleable>

也许你会问SeekBar的background,等属性怎么没有看到?这是由于Android中几乎全部的组件都是从View中继承下来的,SeekBar天然也不例外,而background这个属性几乎每一个控件都有,所以被定义到了View中,你能够在declare-styleable:View中找到它。 

 

总结下,也就是说attrs.xml这个文件定义了布局文件中的各类属性attr:***,以及每种控件特有的属性declare-styleable:***

 

2.styles.xml:

刚才的attrs.xml定义的是组件的属性,如今要说的style则是针对这些属性所设置的值,一些默认的值。

 

 

 

这个是SeekBar的样式,咱们能够看到,这里面设置了一个SeekBar的默认的样式,即为attrs.xml文件中的各类属性设置初始值

Java代码 复制代码  收藏代码
  1. <style name="Widget.SeekBar">   
  2.         <item name="android:indeterminateOnly">false</item>   
  3.         <item name="android:progressDrawable">@android :drawable/progress_horizontal</item>   
  4.         <item name="android:indeterminateDrawable">@android :drawable/progress_horizontal</item>   
  5.         <item name="android:minHeight">20dip</item>   
  6.         <item name="android:maxHeight">20dip</item>   
  7.         <item name="android:thumb">@android :drawable/seek_thumb</item>   
  8.         <item name="android:thumbOffset">8dip</item>   
  9.         <item name="android:focusable">true</item>   
  10.     </style>  
<style name="Widget.SeekBar">
        <item name="android:indeterminateOnly">false</item>
        <item name="android:progressDrawable">@android:drawable/progress_horizontal</item>
        <item name="android:indeterminateDrawable">@android:drawable/progress_horizontal</item>
        <item name="android:minHeight">20dip</item>
        <item name="android:maxHeight">20dip</item>
        <item name="android:thumb">@android:drawable/seek_thumb</item>
        <item name="android:thumbOffset">8dip</item>
        <item name="android:focusable">true</item>
    </style>

 这个是Button的样式:

Java代码 复制代码  收藏代码
  1. <style name="Widget.Button">   
  2.         <item name="android:background">@android :drawable/btn_default</item>   
  3.         <item name="android:focusable">true</item>   
  4.         <item name="android:clickable">true</item>   
  5.         <item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>   
  6.         <item name="android:textColor">@android :color/primary_text_light</item>   
  7.         <item name="android:gravity">center_vertical|center_horizontal</item>   
  8.     </style>  
<style name="Widget.Button">
        <item name="android:background">@android:drawable/btn_default</item>
        <item name="android:focusable">true</item>
        <item name="android:clickable">true</item>
        <item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>
        <item name="android:textColor">@android:color/primary_text_light</item>
        <item name="android:gravity">center_vertical|center_horizontal</item>
    </style>

 

有了属性和值,可是这些东西是如何关联到一块儿的呢?它们如何被android的framework层所识别呢?

 

3.组件的源码

咱们看下TextView的源码:

Java代码 复制代码  收藏代码
  1. public TextView(Context context) {   
  2.         this(context, null);   
  3.     }//这个构造器用来给用户调用,好比new TextView(this);   
  4.   
  5.     public TextView(Context context,   
  6.                     AttributeSet attrs) {   
  7.         this(context, attrs, com.android.internal.R.attr.textViewStyle);   
  8.     }   
  9.   
  10.     public TextView(Context context,   
  11.                     AttributeSet attrs,   
  12.                     int defStyle) {   
  13.         super(context, attrs, defStyle);//为用户自定义的TextView设置默认的style   
  14.         mText = "";   
  15.   
  16.         //设置画笔   
  17.         mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);   
  18.         mTextPaint.density = getResources().getDisplayMetrics().density;   
  19.         mTextPaint.setCompatibilityScaling(   
  20.                 getResources().getCompatibilityInfo().applicationScale);   
  21.           
  22.         mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);   
  23.         mHighlightPaint.setCompatibilityScaling(   
  24.                 getResources().getCompatibilityInfo().applicationScale);   
  25.   
  26.         mMovement = getDefaultMovementMethod();   
  27.         mTransformation = null;   
  28.   
  29.         //attrs中包含了这个TextView控件在布局文件中定义的属性,好比android:background,android:layout_width等   
  30.         //com.android.internal.R.styleable.TextView中包含了TextView中的针对attrs中的属性的默认的值   
  31.         //也就是说这个地方可以将布局文件中设置的属性获取出来,保存到一个TypeArray中,为这个控件初始化各个属性   
  32.         TypedArray a =   
  33.             context.obtainStyledAttributes(   
  34.                 attrs, com.android.internal.R.styleable.TextView, defStyle, 0);   
  35.   
  36.         int textColorHighlight = 0;   
  37.         ColorStateList textColor = null;   
  38.         ColorStateList textColorHint = null;   
  39.         ColorStateList textColorLink = null;   
  40.         int textSize = 15;   
  41.         int typefaceIndex = -1;   
  42.         int styleIndex = -1;   
  43.   
  44.         /*  
  45.          * Look the appearance up without checking first if it exists because  
  46.          * almost every TextView has one and it greatly simplifies the logic  
  47.          * to be able to parse the appearance first and then let specific tags  
  48.          * for this View override it.  
  49.          */  
  50.         TypedArray appearance = null;   
  51.         //TextView_textAppearance不太了解为何要这样作?难道是为了设置TextView的一些默认的属性?   
  52.         int ap = a.getResourceId(com.android.internal.R.styleable.TextView_textAppearance, -1);   
  53.         if (ap != -1) {   
  54.             appearance = context.obtainStyledAttributes(ap,   
  55.                                 com.android.internal.R.styleable.   
  56.                                 TextAppearance);   
  57.         }   
  58.         if (appearance != null) {   
  59.             int n = appearance.getIndexCount();   
  60.             for (int i = 0; i < n; i++) {   
  61.                 int attr = appearance.getIndex(i);   
  62.   
  63.                 switch (attr) {   
  64.                 case com.android.internal.R.styleable.TextAppearance_textColorHighlight:   
  65.                     textColorHighlight = appearance.getColor(attr, textColorHighlight);   
  66.                     break;   
  67.   
  68.                 case com.android.internal.R.styleable.TextAppearance_textColor:   
  69.                     textColor = appearance.getColorStateList(attr);   
  70.                     break;   
  71.   
  72.                 case com.android.internal.R.styleable.TextAppearance_textColorHint:   
  73.                     textColorHint = appearance.getColorStateList(attr);   
  74.                     break;   
  75.   
  76.                 case com.android.internal.R.styleable.TextAppearance_textColorLink:   
  77.                     textColorLink = appearance.getColorStateList(attr);   
  78.                     break;   
  79.   
  80.                 case com.android.internal.R.styleable.TextAppearance_textSize:   
  81.                     textSize = appearance.getDimensionPixelSize(attr, textSize);   
  82.                     break;   
  83.   
  84.                 case com.android.internal.R.styleable.TextAppearance_typeface:   
  85.                     typefaceIndex = appearance.getInt(attr, -1);   
  86.                     break;   
  87.   
  88.                 case com.android.internal.R.styleable.TextAppearance_textStyle:   
  89.                     styleIndex = appearance.getInt(attr, -1);   
  90.                     break;   
  91.                 }   
  92.             }   
  93.   
  94.             appearance.recycle();   
  95.         }   
  96.         //各种属性   
  97.  boolean editable = getDefaultEditable();   
  98.         CharSequence inputMethod = null;   
  99.         int numeric = 0;   
  100.         CharSequence digits = null;   
  101.         boolean phone = false;   
  102.         boolean autotext = false;   
  103.         int autocap = -1;   
  104.         int buffertype = 0;   
  105.         boolean selectallonfocus = false;   
  106.         Drawable drawableLeft = null, drawableTop = null, drawableRight = null,   
  107.             drawableBottom = null;   
  108.         int drawablePadding = 0;   
  109.         int ellipsize = -1;   
  110.         boolean singleLine = false;   
  111.         int maxlength = -1;   
  112.         CharSequence text = "";   
  113.         CharSequence hint = null;   
  114.         int shadowcolor = 0;   
  115.         float dx = 0, dy = 0, r = 0;   
  116.         boolean password = false;   
  117.         int inputType = EditorInfo.TYPE_NULL;   
  118.   
  119.         int n = a.getIndexCount();   
  120.         for (int i = 0; i < n; i++) {   
  121.             int attr = a.getIndex(i);   
  122.             //经过switch语句将用户设置的,以及默认的属性读取出来并初始化   
  123.             switch (attr) {   
  124.             case com.android.internal.R.styleable.TextView_editable:   
  125.                 editable = a.getBoolean(attr, editable);   
  126.                 break;   
  127.   
  128.             case com.android.internal.R.styleable.TextView_inputMethod:   
  129.                 inputMethod = a.getText(attr);   
  130.                 break;   
  131.   
  132.             case com.android.internal.R.styleable.TextView_numeric:   
  133.                 numeric = a.getInt(attr, numeric);   
  134.                 break;   
  135.   
  136.            //更多的case语句...   
  137.   
  138.            case com.android.internal.R.styleable.TextView_textSize:   
  139.                 textSize = a.getDimensionPixelSize(attr, textSize);//设置当前用户所设置的字体大小   
  140.                 break;   
  141.   
  142.             case com.android.internal.R.styleable.TextView_typeface:   
  143.                 typefaceIndex = a.getInt(attr, typefaceIndex);   
  144.                 break;   
  145.            //更多的case语句...   
  146. }  
public TextView(Context context) {
        this(context, null);
    }//这个构造器用来给用户调用,好比new TextView(this);

    public TextView(Context context,
                    AttributeSet attrs) {
        this(context, attrs, com.android.internal.R.attr.textViewStyle);
    }

    public TextView(Context context,
                    AttributeSet attrs,
                    int defStyle) {
        super(context, attrs, defStyle);//为用户自定义的TextView设置默认的style
        mText = "";

        //设置画笔
        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.density = getResources().getDisplayMetrics().density;
        mTextPaint.setCompatibilityScaling(
                getResources().getCompatibilityInfo().applicationScale);
       
        mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mHighlightPaint.setCompatibilityScaling(
                getResources().getCompatibilityInfo().applicationScale);

        mMovement = getDefaultMovementMethod();
        mTransformation = null;

        //attrs中包含了这个TextView控件在布局文件中定义的属性,好比android:background,android:layout_width等
        //com.android.internal.R.styleable.TextView中包含了TextView中的针对attrs中的属性的默认的值
        //也就是说这个地方可以将布局文件中设置的属性获取出来,保存到一个TypeArray中,为这个控件初始化各个属性
        TypedArray a =
            context.obtainStyledAttributes(
                attrs, com.android.internal.R.styleable.TextView, defStyle, 0);

        int textColorHighlight = 0;
        ColorStateList textColor = null;
        ColorStateList textColorHint = null;
        ColorStateList textColorLink = null;
        int textSize = 15;
        int typefaceIndex = -1;
        int styleIndex = -1;

        /*
         * Look the appearance up without checking first if it exists because
         * almost every TextView has one and it greatly simplifies the logic
         * to be able to parse the appearance first and then let specific tags
         * for this View override it.
         */
        TypedArray appearance = null;
        //TextView_textAppearance不太了解为何要这样作?难道是为了设置TextView的一些默认的属性?
        int ap = a.getResourceId(com.android.internal.R.styleable.TextView_textAppearance, -1);
        if (ap != -1) {
            appearance = context.obtainStyledAttributes(ap,
                                com.android.internal.R.styleable.
                                TextAppearance);
        }
        if (appearance != null) {
            int n = appearance.getIndexCount();
            for (int i = 0; i < n; i++) {
                int attr = appearance.getIndex(i);

                switch (attr) {
                case com.android.internal.R.styleable.TextAppearance_textColorHighlight:
                    textColorHighlight = appearance.getColor(attr, textColorHighlight);
                    break;

                case com.android.internal.R.styleable.TextAppearance_textColor:
                    textColor = appearance.getColorStateList(attr);
                    break;

                case com.android.internal.R.styleable.TextAppearance_textColorHint:
                    textColorHint = appearance.getColorStateList(attr);
                    break;

                case com.android.internal.R.styleable.TextAppearance_textColorLink:
                    textColorLink = appearance.getColorStateList(attr);
                    break;

                case com.android.internal.R.styleable.TextAppearance_textSize:
                    textSize = appearance.getDimensionPixelSize(attr, textSize);
                    break;

                case com.android.internal.R.styleable.TextAppearance_typeface:
                    typefaceIndex = appearance.getInt(attr, -1);
                    break;

                case com.android.internal.R.styleable.TextAppearance_textStyle:
                    styleIndex = appearance.getInt(attr, -1);
                    break;
                }
            }

            appearance.recycle();
        }
        //各种属性
 boolean editable = getDefaultEditable();
        CharSequence inputMethod = null;
        int numeric = 0;
        CharSequence digits = null;
        boolean phone = false;
        boolean autotext = false;
        int autocap = -1;
        int buffertype = 0;
        boolean selectallonfocus = false;
        Drawable drawableLeft = null, drawableTop = null, drawableRight = null,
            drawableBottom = null;
        int drawablePadding = 0;
        int ellipsize = -1;
        boolean singleLine = false;
        int maxlength = -1;
        CharSequence text = "";
        CharSequence hint = null;
        int shadowcolor = 0;
        float dx = 0, dy = 0, r = 0;
        boolean password = false;
        int inputType = EditorInfo.TYPE_NULL;

        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            //经过switch语句将用户设置的,以及默认的属性读取出来并初始化
            switch (attr) {
            case com.android.internal.R.styleable.TextView_editable:
                editable = a.getBoolean(attr, editable);
                break;

            case com.android.internal.R.styleable.TextView_inputMethod:
                inputMethod = a.getText(attr);
                break;

            case com.android.internal.R.styleable.TextView_numeric:
                numeric = a.getInt(attr, numeric);
                break;

           //更多的case语句...

           case com.android.internal.R.styleable.TextView_textSize:
                textSize = a.getDimensionPixelSize(attr, textSize);//设置当前用户所设置的字体大小
                break;

            case com.android.internal.R.styleable.TextView_typeface:
                typefaceIndex = a.getInt(attr, typefaceIndex);
                break;
           //更多的case语句...
}

 

经过上面的代码大概能够知道,每一个组件基本都有3个构造器,其中只传递一个Context上下文的那个构造器通常用来在java代码中实例化使用。

好比你能够

Java代码 复制代码  收藏代码
  1. TextView tv = new TextView(context);  
TextView tv = new TextView(context);

 来实例化一个组件。

 

最终调用的是第3个构造器

Java代码 复制代码  收藏代码
  1. public TextView(Context context,   
  2.                     AttributeSet attrs,   
  3.                     int defStyle)  
public TextView(Context context,
                    AttributeSet attrs,
                    int defStyle)

 

 在这个构造器中为你设置了默认的属性attrs和值styles。关键不在这里,而是后面经过使用下面的代码

Java代码 复制代码  收藏代码
  1. TypedArray a =   
  2.             context.obtainStyledAttributes(   
  3.                 attrs, com.android.internal.R.styleable.TextView, defStyle, 0);  
TypedArray a =
            context.obtainStyledAttributes(
                attrs, com.android.internal.R.styleable.TextView, defStyle, 0);

 来将属性和值获取出来,放到一个TypeArray中,而后再利用一个switch语句将里面的值取出来。再利用这些值来初始化各个属性。这个View最终利用这些属性将这个控件绘制出来。

若是你在布局文件中定义的一个View的话,那么你定义的值,会被传递给构造器中的attrs和styles。也是利用一样的方式来获取出你定义的值,并根据你定义的值来绘制你想要的控件。

再好比其实Button和EditText都是继承自TextView。看上去两个控件彷佛差别很大,其实否则。Button的源码其实相比TextView变化的只是style而已:

Java代码 复制代码  收藏代码
  1. public class Button extends TextView {   
  2.     public Button(Context context) {   
  3.         this(context, null);   
  4.     }   
  5.   
  6.     public Button(Context context, AttributeSet attrs) {   
  7.         this(context, attrs, com.android.internal.R.attr.buttonStyle);   
  8.     }   
  9.   
  10.     public Button(Context context, AttributeSet attrs, int defStyle) {   
  11.         super(context, attrs, defStyle);   
  12.     }   
  13. }  
public class Button extends TextView {
    public Button(Context context) {
        this(context, null);
    }

    public Button(Context context, AttributeSet attrs) {
        this(context, attrs, com.android.internal.R.attr.buttonStyle);
    }

    public Button(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
}

 再看看EditText:

Java代码 复制代码  收藏代码
  1. public class EditText extends TextView {   
  2.     public EditText(Context context) {   
  3.         this(context, null);   
  4.     }   
  5.   
  6.     public EditText(Context context, AttributeSet attrs) {   
  7.         this(context, attrs, com.android.internal.R.attr.editTextStyle);   
  8.     }   
  9.   
  10.     public EditText(Context context, AttributeSet attrs, int defStyle) {   
  11.         super(context, attrs, defStyle);   
  12.     }   
  13.   
  14.     @Override  
  15.     protected boolean getDefaultEditable() {   
  16.         return true;   
  17.     }   
  18.   
  19.     @Override  
  20.     protected MovementMethod getDefaultMovementMethod() {   
  21.         return ArrowKeyMovementMethod.getInstance();   
  22.     }   
  23.   
  24.     @Override  
  25.     public Editable getText() {   
  26.         return (Editable) super.getText();   
  27.     }   
  28.   
  29.     @Override  
  30.     public void setText(CharSequence text, BufferType type) {   
  31.         super.setText(text, BufferType.EDITABLE);   
  32.     }   
  33.   
  34.     /**  
  35.      * Convenience for {@link Selection#setSelection(Spannable, int, int)}.  
  36.      */  
  37.     public void setSelection(int start, int stop) {   
  38.         Selection.setSelection(getText(), start, stop);   
  39.     }   
  40.   
  41.     /**  
  42.      * Convenience for {@link Selection#setSelection(Spannable, int)}.  
  43.      */  
  44.     public void setSelection(int index) {   
  45.         Selection.setSelection(getText(), index);   
  46.     }   
  47.   
  48.     /**  
  49.      * Convenience for {@link Selection#selectAll}.  
  50.      */  
  51.     public void selectAll() {   
  52.         Selection.selectAll(getText());   
  53.     }   
  54.   
  55.     /**  
  56.      * Convenience for {@link Selection#extendSelection}.  
  57.      */  
  58.     public void extendSelection(int index) {   
  59.         Selection.extendSelection(getText(), index);   
  60.     }   
  61.   
  62.     @Override  
  63.     public void setEllipsize(TextUtils.TruncateAt ellipsis) {   
  64.         if (ellipsis == TextUtils.TruncateAt.MARQUEE) {   
  65.             throw new IllegalArgumentException("EditText cannot use the ellipsize mode "  
  66.                     + "TextUtils.TruncateAt.MARQUEE");   
  67.         }   
  68.         super.setEllipsize(ellipsis);   
  69.     }   
  70. }  
public class EditText extends TextView {
    public EditText(Context context) {
        this(context, null);
    }

    public EditText(Context context, AttributeSet attrs) {
        this(context, attrs, com.android.internal.R.attr.editTextStyle);
    }

    public EditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected boolean getDefaultEditable() {
        return true;
    }

    @Override
    protected MovementMethod getDefaultMovementMethod() {
        return ArrowKeyMovementMethod.getInstance();
    }

    @Override
    public Editable getText() {
        return (Editable) super.getText();
    }

    @Override
    public void setText(CharSequence text, BufferType type) {
        super.setText(text, BufferType.EDITABLE);
    }

    /**
     * Convenience for {@link Selection#setSelection(Spannable, int, int)}.
     */
    public void setSelection(int start, int stop) {
        Selection.setSelection(getText(), start, stop);
    }

    /**
     * Convenience for {@link Selection#setSelection(Spannable, int)}.
     */
    public void setSelection(int index) {
        Selection.setSelection(getText(), index);
    }

    /**
     * Convenience for {@link Selection#selectAll}.
     */
    public void selectAll() {
        Selection.selectAll(getText());
    }

    /**
     * Convenience for {@link Selection#extendSelection}.
     */
    public void extendSelection(int index) {
        Selection.extendSelection(getText(), index);
    }

    @Override
    public void setEllipsize(TextUtils.TruncateAt ellipsis) {
        if (ellipsis == TextUtils.TruncateAt.MARQUEE) {
            throw new IllegalArgumentException("EditText cannot use the ellipsize mode "
                    + "TextUtils.TruncateAt.MARQUEE");
        }
        super.setEllipsize(ellipsis);
    }
}

 不知道你是否是和我同样感到意外呢?

 

不得不说这种方式很是的好。最大程度地利用了继承,而且可让控件之间的属性能够很方便的被开发者使用。也利用之后的扩展,实际上,不一样的style就能够获得不一样的UI,这也是MVC的一种体现。

好比用户想自定义某个控件,只要覆盖父类的style就能够很轻松的实现,能够参考个人一篇博文,就是使用style自定义ProgressBar

Android中的主题theme也是使用的style。当用户在Activity中设置一个style的时候那么会影响到整个Activity,若是为Application设置style的话,则会影响全部的Activity,因此,若是你在开发一个应用的时候

能够考虑将应用的Activity的背景颜色等一类的属性放到一个style中去,在Application中调用,这种作法会比较方便。

themes.xml:

Java代码 复制代码  收藏代码
  1. <!-- Variant of the default (dark) theme with no title bar -->   
  2.     <style name="Theme.NoTitleBar">   
  3.         <item name="android:windowNoTitle">true</item>   
  4.     </style>   
  5.        
  6.     <!-- Variant of the default (dark) theme that has no title bar and   
  7.          fills the entire screen -->   
  8.     <style name="Theme.NoTitleBar.Fullscreen">   
  9.         <item name="android:windowFullscreen">true</item>   
  10.         <item name="android:windowContentOverlay">@null </item>   
  11.     </style>  
<!-- Variant of the default (dark) theme with no title bar -->
    <style name="Theme.NoTitleBar">
        <item name="android:windowNoTitle">true</item>
    </style>
    
    <!-- Variant of the default (dark) theme that has no title bar and
         fills the entire screen -->
    <style name="Theme.NoTitleBar.Fullscreen">
        <item name="android:windowFullscreen">true</item>
        <item name="android:windowContentOverlay">@null</item>
    </style>

 咱们平时使用的主题实际上就定义在这个文件中。也是一个style。

相关文章
相关标签/搜索