Android样式和主题(一):简介

96
08_carmelo
2017.05.04 20:15* 字数 628

前言

样式Style和主题Theme是Android中很重要两个概念,用的时候很容易弄混淆,此篇我准备从自定义属性到自定义样式,了解一下Android里属性,样式和主题的原理。

简介

  • Attr:属性,风格样式的最小单元;

  • Style:风格,它是一系列Attr的集合用以定义一个View的样式,比如height、width、padding等;

  • Theme:主题,它与Style作用一样,不同于Style作用于个一个单独View,而它是作用于Activity上或是整个应用。

View的Style(样式)

假设给自定义View:MyView设定了几个自定义属性:attr.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="dml">
        <attr name="circleColor" format="color|reference"/>
        <attr name="circleSize" format="integer"/>
    </declare-styleable>
</resources>

然后把这几个属性封装成一个Style:style.xml

<resources>
    <style name="editStyle">
        <item name="circleColor">#343434</item>
        <item name="circleSize">40</item>
    </style>
</resources>

在布局文件中给MyView设置style:

style="@style/editStyle"

在MyView的构造方法中获取这些属性:

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.dml);
        int color = ta.getInt(R.styleable.dml_circleColor,-1);
        int size = ta.getInt(R.styleable.dml_circleSize,-1);
        Log.d("dml","color = " + color + "-------size = " + size);
    }

看下效果:
05-02 21:18:08.626 31441-31441/com.example.app2 D/dml: color = -13355980-------size = 40

  • 其实在Android系统中,我们给View设置属性比如TextView设置android:textSize="23sp",在TextView的源码中也是这么在构造方法中获取的,然后在OnDrawI()中绘制,这就是Android的View属性和Style的工作原理。同样,我们在Allication节点设置android:theme属性那么在Activity源码中肯定有方法来获取这个style,这就是Theme的工作原理,下面会验证。
  • 我再自定义一个View比如OtherView extends View,那么还是得在OtherView的构造方法中再次获取这些属性值,所以说Style(样式)是对View有效果。

Activity/Application的Theme(主题)

还是用上面自定义的两个属性,封装一个style,这次由于是用于Activity,那么需要额外的系统自带属性不然Activity不能正常工作,会崩溃

    <style name="AppEditStyle" parent="android:Theme.Material.Light">
        <item name="circleColor">#343434</item>
        <item name="circleSize">40</item>
    </style>

在menifest.xml的application节点定义:

    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppEditStyle">
        <activity android:name=".StyleActivity">

然后在Activity中获取这两个属性:

public class StyleActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_style);
    }
    @Override
    protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
        super.onApplyThemeResource(theme, resid, first);
        TypedArray ta = theme.obtainStyledAttributes(R.styleable.dml);
        int color = ta.getInt(R.styleable.dml_circleColor,-1);
        int size = ta.getInt(R.styleable.dml_circleSize,-1);
        Log.d("dml","color = " + color + "-------size = " + size);
    }
}

看下效果:
05-02 21:38:15.285 19755-19755/com.example.app2 D/dml: color = -13355980-------size = 40

  • 同上面的Style一样,在Android系统中我们给Applciation节点设置了Theme,那么在Activity源码中也会相应获取这个主题,然后展示出默认的Activity风格,果然在Activity源码3711行有这个回调方法:
    @Override
    protected void onApplyThemeResource(Resources.Theme theme, @StyleRes int resid,
            boolean first) {
        if (mParent == null) {
            super.onApplyThemeResource(theme, resid, first);
        } else {
            try {
                theme.setTo(mParent.getTheme());
            } catch (Exception e) {
                // Empty
            }
            theme.applyStyle(resid, false);
        }

        // Get the primary color and update the TaskDescription for this activity
        if (theme != null) {
            TypedArray a = theme.obtainStyledAttributes(com.android.internal.R.styleable.Theme);
            int colorPrimary = a.getColor(com.android.internal.R.styleable.Theme_colorPrimary, 0);
            a.recycle();
            if (colorPrimary != 0) {
                ActivityManager.TaskDescription v = new ActivityManager.TaskDescription(null, null,
                        colorPrimary);
                setTaskDescription(v);
            }
        }
    }

下一篇:介绍下Android系统有哪些常见的主题

Android经验分享
Web note ad 1