1. 程式人生 > >解決修改 Style Attributes 不起作用的問題

解決修改 Style Attributes 不起作用的問題

今天新建一個專案時遇到了一個問題,專案中大部分 Activity theme 需要顯示 ActionBar,個別頁面根據業務不需要顯示。
需求很簡單,直接定義 AppTheme 作為 Application 的基礎樣式,再定義一個子樣式 AppTheme.NoTitle,修改為無 ActionBar 即可。

問題程式碼
AndroidManifest.xml 部分程式碼:


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.coustom.coustom">
    
  <application
        android:theme="@style/AppTheme">
        
        <activity
            android:name=".CoustomActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoTitle" />
        
    </application>
</manifest>

values/styles.xml 部分程式碼:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/color_primary</item>
        <item name="colorPrimaryDark">@color/color_primary_dark</item>
        <item name="colorAccent">@color/color_accent</item>
        ...
    </style>
    <style name="AppTheme.NoTitle">
        <item name="android:windowActionBar">false</item>
        <item name="android:windowNoTitle">true</item>
    </style>
    
</resources>

執行結果依舊顯示 ActionBar,懷疑在 BaseActivity 中做了多餘的事情,但排查下來並沒有找,並且在以往的專案中也是可以成功Work的。

原因
再排除了一些列可能的原因後,終於找到了問題原因:

在修改 Style Resource 的屬性的格式為:

style_value
[package:] is the name of the package in which the resource is located (not required when referencing resources from your own package).
[package:] 用於指定屬性所在的包名,屬性在當前包下時則無需新增。

若新增在屬性名稱前新增 andoird: 時即指定屬性為 android 包下。

而專案的 Base Style AppTheme 繼承自 Theme.AppCompat,位於 appcompat-v7 library, 而不是 android 包下。
所以錯誤地使用 android:windowActionBar 和 android:windowNoTitle,應該使用 windowActionBar 和 windowNoTitle。將程式碼修改為:

修改後的程式碼
values/styles.xml 修改後的部分程式碼:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="colorPrimary">@color/color_primary</item>
        <item name="colorPrimaryDark">@color/color_primary_dark</item>
        <item name="colorAccent">@color/color_accent</item>
        ...
    </style>
    <style name="AppTheme.NoTitle">
        <!--<item name="android:windowActionBar">false</item>-->
        <!--<item name="android:windowNoTitle">true</item>-->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>
    
</resources>

在之前的專案中,Base Style 繼承自 @android:style/Theme.Holo.Light,故使用修改前的程式碼是沒有問題的。

總結
修改 Style attributes 時候

Parent Style 來自 @android:xxx 時,在屬性名前新增 android:
例如

<item name="android:windowActionBar">false</item>

Parent Style 不來自@android:xxx 時,無需在屬性名前新增 android:
例如

<item name="windowActionBar">false</item>