伴隨着Android的主題(
theme
)越來越多之後,記清如何使用以及怎麼使用、使用後的效果如何,並非一件短時間裏就能非常熟練的掌握好,那麼關於主題中的ActionBar
,今天這邊做一個曾遇到的衝突記錄
當我們選擇創建一個Empty Activity
的App項目時,默認生成的AndroidManifest.xml
內容如下
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="xxx.xxx.xxx">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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>
</manifest>
在這裏,我們應該注意到默認的App主題爲android:theme="@style/AppTheme"
那麼今天的問題來了!
回憶到曾經某個項目因爲嫌棄系統自帶的Actionbar不符合需求之後,那麼重定義就免不了了,在重定義使用Actionbar的時候,因使用了API接口setSupportActionBar(@Nullable Toolbar toolbar)
,導致引發異常崩潰
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.itsdf07.app.mvp, PID: 26401
"java.lang.RuntimeException: Unable to start activity ComponentInfo{com.itsdf07.app.mvp/com.itsdf07.app.mvp.main.MainActivity}: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead."
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3194)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
at android.app.ActivityThread.-wrap12(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
"Caused by: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead. "
at android.support.v7.app.AppCompatDelegateImplV9.setSupportActionBar(AppCompatDelegateImplV9.java:204)
at android.support.v7.app.AppCompatActivity.setSupportActionBar(AppCompatActivity.java:129)
at com.itsdf07.app.mvp.main.MainActivity.onCreate(MainActivity.java:26)
at android.app.Activity.performCreate(Activity.java:7372)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1218)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3147)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3302)
at android.app.ActivityThread.-wrap12(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1891)
at android.os.Handler.dispatchMessage(Handler.java:108)
at android.os.Looper.loop(Looper.java:166)
at android.app.ActivityThread.main(ActivityThread.java:7425)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)
什麼原因呢?啓動MainActivity界面失敗,原因是
This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
這個Activity(也就是要啓動的MainActivity)已經由 window decor提供了一個action bar,不需要重複請求 window的FEATURE_SUPPORT_ACTION_BAR,並且可以通過設置主題中的windowActionBar屬性爲false來代替它
爲什麼會這樣呢?程序不能只看表面,既然異常提到了theme
,那麼我們就需要進一步往parent主題來定位原因,總能發現原因的
<style name="Base.V7.Theme.AppCompat.Light" parent="Platform.AppCompat.Light">
<item name="windowNoTitle">false</item>
"<item name="windowActionBar">true</item>"
<item name="windowActionBarOverlay">false</item>
<item name="windowActionModeOverlay">false</item>
<item name="actionBarPopupTheme">@null</item>
......
</style>
當看到上面的設置時,我們發現了<item name="windowActionBar">true</item>
,也就是說當前所使用的主題其實是帶了一個ActionBar的,這麼一來,就好理解了,在已有ActionBar的基礎上在添加一個ActionBar,出現衝突了
,能排查出原因的問題,那就都不是問題。因爲下面這個主題,就可以解決這個衝突
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
沒帶ActionBar的主題,我們想怎麼添加新的ActionBar都可以!
當然,如果想要全局都使用自定義ActionBar,那麼就直接在AndroidManifest.xml
的application
下的theme
設置爲無ActionBar即可,如android:theme="@style/AppTheme.NoActionBar"
,如果只是針對某個視圖UI,那麼 就針對那個Activity進行設置即可