Пользовательский (градиентный) фон ActionBar Compat

Я использую Action Bar Compat, чтобы моя панель действий с навигационным ящиком была обратно совместима до уровня API 9, и я хочу изменить фон панели действий.

Я скопировал код с сайта Android Developers:

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- the theme applied to the application or activity -->
<style name="CustomActionBarTheme"
       parent="@style/Theme.AppCompat.Light.DarkActionBar">
    <item name="android:actionBarStyle">@style/MyActionBar</item>

    <!-- Support library compatibility -->
    <item name="actionBarStyle">@style/MyActionBar</item>
</style>

<!-- ActionBar styles -->
<style name="MyActionBar"
       parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
    <item name="android:background">@drawable/actionbar_background</item>

    <!-- Support library compatibility -->
    <item name="background">@drawable/actionbar_background</item>
</style>
</resources>

И тут возникает проблема.

Когда я помещаю изображение или цвет в качестве фона, он отлично работает. Однако я хочу определить фон как форму градиента, поэтому мой actionbar_background выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line">
<gradient
        android:startColor="@color/ac_bg_start"
        android:endColor="@color/ac_bg_end"
        android:type="linear"/>
<size
        android:width="1dp"
        android:height="48dp"/>
</shape>

Я хочу, чтобы это повторялось по горизонтали, но даже это приводит к ошибке, на самом деле очень интересной ошибке. Тестовое устройство и даже эмулятор перезапускаются, когда я пытаюсь запустить приложение. Я смог поймать DeadObjectException перед перезапуском.

Как должен выглядеть фоновый рисунок?


person Marcel Bro    schedule 26.08.2013    source источник


Ответы (4)


Я сейчас работаю над той же задачей.

Вот мой файл action_bar_bg.xml, в котором я определяю градиент для панели действий.

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:angle="90"
        android:centerColor="@color/turquoise_action_bar"
        android:endColor="@color/dark_turquoise"
        android:startColor="@color/dark_turquoise" />
</shape>

Исключение DeadObject

android:shape="line" нельзя использовать, если внутри есть градиент. Я проверил это; мой Samsung Galaxy Note 10.1 N8000 перезапустился, и появилось DeadObjectException.

Тип шаблона градиента linear является значением по умолчанию. Таким образом, вам не нужно объявлять это явно.

Вот мой styles.xml в папке values.

<resources>

    <!-- Base application theme. -->
    <style name="AppThemeBase" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="android:actionBarStyle">@style/PeopleCanAct</item>
        <!-- Support library compatibility -->
        <item name="actionBarStyle">@style/MyActionBar</item>
    </style>

    <style name="AppTheme" parent="AppThemeBase">
        <!-- All the customizations that are NOT specific to a particular API level can go here -->
    </style>

    <!-- ActionBar styles -->
    <style name="MyActionBar" parent="@style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
        <item name="android:background">@drawable/action_bar_bg</item>
        <!-- Support library compatibility -->
        <item name="background">@drawable/action_bar_bg</item>
    </style>

</resources>

Градиент Drawable

person Maksim Dmitriev    schedule 02.01.2014
comment
‹item name=android:actionBarStyle›@style/PeopleCanAct‹/item› следует изменить на ‹item name=android:actionBarStyle›@style/MyActionBar‹/item›, вы получите ошибку компиляции как есть - person Vincent D.; 31.05.2016
comment
Это работает, хотя я не понимаю часть DeadObjectException, когда устройство получит это исключение? - person Bruce; 27.09.2016

Другой подход без изменения styles.xml:

Вот наш пример GradientDrawable в res/drawable/ab_gradient.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle"
    android:useLevel="false" >

    <gradient
        android:angle="90"
        android:startColor="#000000"
        android:endColor="#FFFFFF"
        android:type="linear" />

</shape>

Вы можете установить его на панель действий в своей деятельности onCreate():

ActionBar actionBar = getActionBar();    
actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.action_bar_gradient_shape));

Если вы используете библиотеку поддержки v7 (ваш случай):

// make sure to import android.support.v7.app.ActionBar
ActionBar actionBar = getSupportActionBar();        
actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.action_bar_gradient_shape));

Или, если вы используете ActionBarSherlock:

// make sure to import com.actionbarsherlock.app.ActionBar
ActionBar actionBar = getSherlock().getActionBar();     
actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.action_bar_gradient_shape));
person Max77    schedule 22.03.2014
comment
Это, по-видимому, тоже работает, но я принял другой ответ, потому что он объясняет, что не так с моим кодом. - person Marcel Bro; 21.10.2014
comment
@ Max77 .getDrawable устарел. Какой новый код заменит устаревший метод? - person iOSAndroidWindowsMobileAppsDev; 20.06.2016
comment
@JqueryNinja проверьте этот хороший ответ: stackoverflow.com /вопросы/29041027/ - person Max77; 20.06.2016

Это пример для панели действий xml:

<?xml version="1.0" encoding="utf-8"?>
 <shape xmlns:android="http://schemas.android.com/apk/res/android">
    <gradient
        android:angle="180"
        android:endColor="#BF797777"
        android:startColor="#A4231E35"
        android:type="linear" />
</shape> 

Вместо использования android:shape="line" , чтобы избежать DeadObjectException , вы можете установить для android:angle значение 180 или 0 - эффект будет тот же, то есть градиент горизонтальной линии.

person JJ McKool    schedule 25.01.2020

Я также использую этот образец кода от Android Developer и использую градиентный XML, как и ваш.

<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="line">

Я обнаружил, что разница в этом файле между вашим и моим — android:shape="line"/android:shape="rectangle".

Поэтому я пытаюсь изменить свой прямоугольник на линию. В моем приложении также возникает такое же исключение, и ОС перезагружается. Может быть, форма является ключевым моментом.

person OsterHuang    schedule 21.10.2014
comment
Это на самом деле не отвечает на вопрос. Если у вас есть другой вопрос, вы можете задать его, нажав Задать вопрос. Вы также можете добавить награду, чтобы привлечь больше внимания к этому вопросу, как только у вас будет достаточно репутация. - person maszter; 21.10.2014