【问题标题】:Custom (gradient) background of ActionBar CompatActionBar Compat 的自定义(渐变)背景
【发布时间】:2013-08-26 08:37:39
【问题描述】:

我正在使用 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

背景可绘制对象应该是什么样子?

【问题讨论】:

    标签: android background android-actionbar-compat shapedrawable


    【解决方案1】:

    我目前正在做同样的任务。

    这是我的 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>
    

    DeadObjectException

    android:shape="line"如果里面有渐变就不能用了。我测试了它;我的三星 Galaxy Note 10.1 N8000 重启了,出现了DeadObjectException

    linear 类型的渐变图案是 默认 值。所以你不必显式声明它。

    这是我在 values 文件夹中的styles.xml

    <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>
    

    Gradient Drawable

    【讨论】:

    • @style/PeopleCanAct 应该改为 @style/MyActionBar 你会按原样得到一个编译错误
    • 这行得通,虽然我不明白 DeadObjectException 部分,设备什么时候会得到那个异常?
    【解决方案2】:

    另一种方法,不修改styles.xml

    这是我们在res/drawable/ab_gradient.xml 中的 GradientDrawable 示例

    <?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>
    

    您可以在 Activity 的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));
    

    【讨论】:

    • 这显然也有效,但我接受了另一个答案,因为它解释了我的代码出了什么问题。
    • @Max77 .getDrawable 现在已弃用。替换不推荐使用的方法的新代码是什么?
    • @JqueryNinja 检查这个好答案:stackoverflow.com/questions/29041027/…
    【解决方案3】:

    这是操作栏 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 - 效果会一样,即水平线条渐变。

    【讨论】:

      【解决方案4】:

      我还使用 Android Developer 的示例代码,并像您一样使用渐变 XML。

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

      我发现你和我的这个文件不同的是android:shape="line" / android:shape="rectangle"

      所以我尝试将矩形更改为直线。我的应用程序也发生了同样的异常,操作系统重新启动。也许形状是关键点。

      【讨论】:

      • 这并不能真正回答问题。如果您有其他问题,可以点击 提问。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-14
      相关资源
      最近更新 更多