Android 主题设计全解析

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

                       

Android主题设计!有点乱?

初学Android的时候对Android的主题设计都是处在一种模糊的认知状态,为啥呢?

自定义时候的attr,普通view的style属性,activity以及application的theme属性,theme与style定义的一致性以及theme的众多可选性,系统预置的style属性的继承与使用等等……

OK,先不管这些乱七八糟的,如果你对Android的主题设计依旧存在某些疑问,请看完这篇文章。

Theme、Style、Attr的基本概念

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

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

Theme:主题,它与Style作用一样,不同于Style作用于个一个单独View,而它是作用于Activity上或是整个应用,并具有向下的覆盖特性


Theme

Theme的概念验证

好吧,为了清晰的验证上面的说法,我这里举个例子

新建一个moudle,在styles.xml中有如下内容

<resources>    <!-- Base application theme. -->    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>    </style></resources>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

可以看到该style定义了该主题下共享的三个颜色属性,以及继承了一个父主题
那么来看一下该主题应用的代码

    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

此时 ,这个默认主题应用在了Application下,我们启动模拟器观看主题效果
这里写图片描述

普普通通没啥特别的,我们为前面的主题添加两个属性

        <item name="windowActionBar">false</item>        <item name="windowNoTitle">true</item>
  
  
  • 1
  • 2

重新启动模拟器,你看到了什么

这里写图片描述

Activity的ActionBar被隐藏了,
是的,正如我前面所说,Theme一般应用于Application和Activity层级,并会继续向下覆盖,这里我们虽然只是设置了Application的theme属性,其下的所有Activity都会使用该主题。

Theme的定义

Theme的定义基本是一致的,主要是外部由一个一对style标签,内部通过item指明所定义的各个属性,下面的Theme就是一个标准的样例,

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>    </style>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Theme的继承

1)通过parent属性进行系统主题的继承

    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">        <!-- Customize your theme here. -->        <item name="colorPrimary">@color/colorPrimary</item>        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>        <item name="colorAccent">@color/colorAccent</item>    </style>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2)通过“.”进行自定义主题的继承

    <style name="AppTheme.NoActionbar">    <item name="windowActionBar">false</item>    <item name="windowNoTitle">true</item>    </style>
  
  
  • 1
  • 2
  • 3
  • 4

“.”前面是我们自定义的主题name,后面那就随意了,怎么写都可以了

style的继承与Theme一致,如果你原来不明白别人为何这样写,那么现在你肯定是知道了

Theme和Style的区别

  • 定义上的区别:无太大区别,主要是属性不同,写法上基本一致
  • 使用上的区别:
    对于单个控件通过style进行引入(此时style不会向下覆盖); 
    对于Activity、Application等窗口级向下应用的通过theme进行引入;

使用系统预置的style

<!-- 使用系统预制style --><activity android:theme="@android:style/Theme.Dialog"><!-- 使用系统预制但局部修改的style --><activity android:theme="@style/CustomTheme"><color name="custom_theme_color">#b0b0ff</color><style name="CustomTheme" parent="android:Theme.Light">    <item name="android:windowBackground">@color/custom_theme_color</item>    <item name="android:colorBackground">@color/custom_theme_color</item></style>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

使用Android系统内置的style,请务必加上“android:”

ThemeOverlays

在所有可用的主题中,我们可以发现一个名字带有 ThemeOverlay 的系列:
ThemeOverlay
ThemeOverlay.Light
ThemeOverlay.ActionBar.Light
ThemeOverlay.ActionBar.Dark
这些主题又是做什么的呢?答案是 仅用于为特定的用途定义必要的属性。

如果你不清楚,请看测试

我们首先创建两个toolbar的style

    <style name="AppTheme.AppBar1" parent="ThemeOverlay.AppCompat.Light"/>    <style name="AppTheme.AppBar2" parent="ThemeOverlay.AppCompat.Dark"/>
  
  
  • 1
  • 2

添加toolbar进行测试

    <android.support.v7.widget.Toolbar        android:id="@+id/toolbar"        android:layout_width="match_parent"        android:layout_height="?attr/actionBarSize"        app:theme="@style/AppTheme.AppBar1"        android:background="@color/colorPrimary"/>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里写图片描述

修改为第二个

这里写图片描述

通过改变主题我们可以很轻松的实现界面的View的样式变换,是不是会很方便。

Theme的选用

其是很简单,在MD设计(也就是5.0)被推出之后,google推出了几个material的主题,但你不必去使用这些主题,因为有更好的替代方案
Theme.AppCompat
Theme.AppCompat.Light,
Theme.AppCompat.NoActionBar等等
这些主题既保证了向下的兼容又兼顾了material的主题设计,并与materiial的各个主题一一对应,你在选择的时候使用以Theme.AppCompat开头的主题准是没错。

那就有人问了,为毛线这么干,其他乱七八糟的主题又是啥呢?

这里我强烈推荐你看一篇文章(译文):android-themes-an-in-depth-guide


Attr

首先以layout_width为例分析自定义属性

<declare-styleable name="ViewGroup_Layout">    <attr name="layout_width" format="dimension">        <enum name="fill_parent" value="-1" />        <enum name="match_parent" value="-1" />        <enum name="wrap_content" value="-2" />    </attr></declare-styleable>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

declare-styleable代表自定属性组,attr则是代表属性,name是属性的标识,format是该属性的值类型,内部为enum表示值是唯一的,只可选其一。

再来看一下text的style

<attr name="textStyle">    <flag name="normal" value="0" />    <flag name="bold" value="1" />    <flag name="italic" value="2" /></attr>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

此时attr的内部是flag,代指属性值是可叠加使用的,比如textStyle = bold|italic则是加粗和斜体的叠加。

format属性的可选值如下
这里写图片描述
其中,reference代表引用,我们常用的@drawable/myImage、@color/myColor等都是这么干的。

ok,attr内部也只有enum和flag两种类型的属性,看完这个相信你可以自行定义属性了。

 

特别注意,当你的format选择错误的时候,填入对应的值AS并不会报错,所以具体实践时请留心

Attr的获得方法

有些情况下,我们可能需要使用theme中的属性值,比如下面我们想让一个TextView直接显示dogName这个属性的内容,并且使用系统字体的颜色,则可以如下做:

<TextView    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:textColor="?android:textColorSecondary"    android:text="?attr/dogName"/>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5

获得一个Attr的方法,不同于普通资源使用@符号获得的方式,而是需要使用?符号来获得属性,整体的表达方式如下:

?[:][/]
如果是本应用中的attr使用,则可以省去<package_name>部分。

此处的textColor使用当前主题的android:textColorSecondary属性内容。因为资源工具知道此处是一个属性,所以省去了attr (完整写法:?android:attr/textColorSecondary)。

 

Attr的使用优先级:View的Style>Activity的Theme>Application的Theme,所以说你可以定义整个应用的总体风格,但局部风格你也可以做出自己的调整。


最近做了下反思,与其制造网络垃圾不如不去写文章,所以准备大幅度降低写作速度并致力于提升文章的质量,未来计划在自己进步的同时分享进步的干货并不断去删除原文,以保证整个博客的文章质量和可用性。

如果你对本文有什么问题和看法请及时告知,送人玫瑰手有余香,谢谢支持。

参考文章:
Attr、Style和Theme详解
Android开发之Theme、Style探索及源码浅析
ThemeOverlay
Android Themes — An in-depth guide

           

给我老师的人工智能教程打call!http://blog.csdn.net/jiangjunshow
这里写图片描述
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值