Android Theme.AppCompat 中,你应该熟悉的颜色属性

dg0625 7年前
   <p>创建一个 Android 工程,第一步,也是必不可少的一步,就是定制 Application 主题样式。利用系统诸多属性定义 App 各种 View 的默认样式,能够减少 layout 文件中很多重复性的属性设置代码。在开发者官网 R.attr 栏目中,Google 列出了所有 Android SDK 中的系统级属性。如何取舍,如何区分,又有哪些常用的属性呢?本文就来列举颜色相关的一些属性介绍,以供参考。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/eac1efc1dee86afad32707af6c2a9bc9.png"></p>    <p>通常,在 res/values/styles.xml 文件中定义的 application 主题样式里,你可能见到的最常见的使用组合是这样:</p>    <pre>  <code class="language-java"><resources>        <!-- Base application theme. -->      <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">          <item name="colorPrimary">@color/colorPrimary</item>          <item name="colorPrimaryDark">@color/colorPrimaryDark</item>          <item name="colorAccent">@color/colorAccent</item>      </style>    </resources>  </code></pre>    <p>事实上,远不止这样…</p>    <h2><strong>Theme.AppCompat</strong></h2>    <p>自 Lollipop 开始,Android 系统引入 Material Design 风格,各个控件的呈现样式大有改变。为了在不同版本的系统中统一 UI 样式,设置自定义的 Application Theme 的 parent 样式为 Theme.AppCompat 系列即可。比如这里的 Theme.AppCompat.Light.NoActionBar 主题。</p>    <p>同时,由于部分属性的版本兼容问题,为了避免添加多个版本的 styles 文件,可以省略 android: 命名空间。</p>    <p><strong>colorPrimary</strong></p>    <p>App Bar 的背景色,即 ActionBar,通常也是一个 App 的主题色调。不过 ActionBar 已经退出历史舞台,由 Toolbar 代替使用,但是 Toolbar 需要在 layout 文件中单独使用 background 属性设置背景色,如:</p>    <pre>  <code class="language-java"><android.support.v7.widget.Toolbar    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:background="?attr/colorPrimary" />  </code></pre>    <p><strong>colorPrimaryDark</strong></p>    <p>status bar(状态栏)背景色。仅作用于 Lollipop 及更高版本。</p>    <p><strong>colorAccent</strong></p>    <p>许多控件在选中状态或获取焦点状态下使用这个颜色,常见有:</p>    <ul>     <li>CheckBox:checked 状态</li>     <li>RadioButton:checked 状态</li>     <li>SwitchCompat:checked 状态</li>     <li>EditText:获取焦点时的 underline 和 cursor 颜色</li>     <li>TextInputLayout:悬浮 label 字体颜色</li>     <li>等等</li>    </ul>    <p>除了这三种常见的控制颜色属性,事实上,还有一些颜色相关的属性也是非常实用的。</p>    <p><strong>android:navigationBarColor</strong></p>    <p>navigation bar 背景色。仅作用于 Lollipop 及更高版本。</p>    <p><strong>colorControlNormal</strong></p>    <p>某些 Views “normal” 状态下的颜色,常见如:unselected CheckBox 和 RadioButton,失去焦点时的 EditText,Toolbar 溢出按钮颜色,等等。</p>    <p><strong>colorControlActivated</strong></p>    <p>某种程度上,是 colorAccent 的替代者,比如对于 CheckBox 和 RadioButton 的 checked 状态,colorControlActivated 属性会覆盖 colorAccent 属性的对应颜色。</p>    <p><strong>colorControlHighlight</strong></p>    <p>所有可点击 Views 触摸状态下的 Ripple(涟漪)效果。仅作用于 Lollipop 及更高版本。</p>    <p><strong>colorButtonNormal</strong></p>    <p>Button normal 状态下的背景色。注意,这种设置与 Button 的 android:background 属性改变背景色不同的是,前者在 Lollipop 及更高版本上会让 Button 依旧保持阴影和 Ripple 触摸效果。</p>    <p><strong>android:windowBackground</strong></p>    <p>窗口背景色,诸如此类的还有: android:background , android:colorBackground 等。</p>    <p><strong>android:textColorPrimary</strong></p>    <p>EditText 的 text color,等等文本颜色。</p>    <p>诸如此类,还有很多颜色相关的系统属性。GitHubGist 上面有一份参考指南: Android Lollipop Widget Tinting Guide ,列举了常用控件的着色相关属性。</p>    <h2><strong>ThemeOverlay.AppCompat</strong></h2>    <p>作为 Application Theme 的 parent 主题,Theme.AppCompat 提供了诸多属性设置 App 全局 Views 样式。但是有时候,我们还是需要单独给某个或者某些 View 设置与全局样式不一样的样式。这种情况下,ThemeOverlay.AppCompat 就派上用场啦。</p>    <p>正如命名所表达的含义一般,ThemeOverlay.AppCompat 系列主题用于覆盖基本的 AppCompat.Theme 样式,按照需求仅仅改变部分属性的样式。这里列举一些常见用法:</p>    <p><strong>ThemeOverlay.AppCompat</strong></p>    <p>继承自 @style/Base.ThemeOverlay.AppCompat。这是一个空主题,但是却将 AppCompat 主题中的相关属性复制了一遍。这在给个别 View 单独设置部分样式时非常实用。举个例子:</p>    <pre>  <code class="language-java"><style name="AppTheme.Secondary" parent="ThemeOverlay.AppCompat">      <item name="colorAccent">@color/colorPrimary</item>  </style>  </code></pre>    <p>然后再借助 android:theme 属性使用在 layout 中的某个 View 上:</p>    <pre>  <code class="language-java">android:theme="@style/AppTheme.Secondary"  </code></pre>    <p>在这个例子中,重写了 colorAccent 属性,同时保证其他属性继续延用 parent 为 Theme.AppCompat 的 AppTheme 中的设置。从 ThemeOverlay.AppCompat 文档介绍中可以看出,比如 colorPrimary 属性是这样复制的:</p>    <p><strong>android:colorPrimary = ?attr/colorPrimary</strong></p>    <p>如果 parent 使用 Theme.AppCompat 或者其他主题就不行,相当于只设置 colorAccent 属性,其他属性使用默认样式。</p>    <p><strong>ThemeOverlay.AppCompat.Light(Dark)</strong></p>    <p>与 ThemeOverlay.AppCompat 不同的是,这个主题修改背景色、文本颜色、高亮状态颜色来匹配 Light(Dark)主题。比如 Light 样式下的白色背景里,显示黑色(Dark)文本;Dark 样式下的黑色背景里,显示白色(Light)文本。</p>    <p>这个主题的使用场景可以是这样,比如我们的全局主题是 Light,但是有一部分 UI 可能需要使用一个 Dark 样式的背景,这种情况下,每个 View 单独设置颜色就比较麻烦,可以在 ViewGroup 中统一设置,比如:</p>    <pre>  <code class="language-java"><FrameLayout      android:background=”@color/dark_background”      android:theme="@style/ThemeOverlay.AppCompat.Dark”>    <TextView />  </FrameLayout>  </code></pre>    <p><strong>ThemeOverlay.AppCompat.Dark.ActionBar</strong></p>    <p><strong>ThemeOverlay.AppCompat.Light.ActionBar</strong></p>    <p>相比而言,由于 Toolbar 的广泛使用,这对主题使用的就比较多啦。前面我们说过,colorControlNormal 和 textColorPrimary 属性都可以影响 Toolbar 或者 ActionBar 的溢出按钮颜色和溢出文本颜色,同时也改变着其他 View 的显示颜色。综合考虑下,我们不会使用在 Application Theme 使用这些属性控制 Toolbar 的内容颜色,而是使用这对主题单独设置给 Toolbar 的 theme 属性。</p>    <p>比如全局使用的是 Light 主题,Toolbar 的背景色是蓝色或者红色之类的颜色,要求溢出按钮的颜色是白色。如果没有特殊设置的话,默认情况下溢出按钮显示为黑色。此时,便可以用上这个主题:</p>    <pre>  <code class="language-java"><android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"      android:layout_width="match_parent"      android:layout_height="?android:attr/actionBarSize"      android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"      android:background="?attr/colorPrimary">    </android.support.v7.widget.Toolbar>  </code></pre>    <p> </p>    <p>来自:http://yifeng.studio/2017/04/18/android-theme-appcompat-color-attrs/</p>    <p> </p>