4

I'm trying to change the color of the divider bar at the bottom of the action bar programmatically. My strategy is to set the action bar background to a programmatically generated LayerDrawable containing ShapeDrawable rectangles, based on this XML:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Bottom Line -->
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/action_bar_line_color" />
        </shape>
    </item>

    <!-- Color of your action bar -->
    <item android:bottom="2dip">
        <shape android:shape="rectangle">
            <solid android:color="@color/action_bar_color" />
        </shape>
    </item>
</layer-list>

But I've hit a roadblock: I can't figure out how to apply an android:bottom property (as in <item android:bottom="2dip">) programmatically. Obviously android:bottom is a property of the item tag, to which (I think) there's no programmatic equivalent, and I haven't been able to find any methods/properties of ShapeDrawable that look appropriate.

Code so far:

public LayerDrawable createABBackground(String color) {
    ShapeDrawable rect = new ShapeDrawable(new RectShape());
    rect.getPaint().setColor(Color.parseColor("#000000"));
    ShapeDrawable rect2 = new ShapeDrawable(new RectShape());
    rect2.getPaint().setColor(Color.parseColor(color));
    ShapeDrawable[] layers = {rect, rect2};
    LayerDrawable background = new LayerDrawable(layers);
    return background;
}

Ideas? If it matters for alternative solutions, I'm using ActionBarSherlock.

EDIT:

setLayerInset, as suggested by MH, did what I wanted. Here's a modified version of the function using it:

public LayerDrawable createABBackground(String color) {
    ShapeDrawable rect = new ShapeDrawable(new RectShape());
    rect.getPaint().setColor(Color.parseColor(color));
    ShapeDrawable rect2 = new ShapeDrawable(new RectShape());
    rect2.getPaint().setColor(Color.parseColor("#000000"));
    ShapeDrawable[] layers = {rect, rect2};
    LayerDrawable background = new LayerDrawable(layers);
    background.setLayerInset(0, 0, 3, 0, 0);
    background.setLayerInset(1, 0, 0, 0, 3);
    return background;
}
Community
  • 1
  • 1
user460847
  • 1,578
  • 6
  • 25
  • 43
  • Did you give [`setLayerInset(int index, int l, int t, int r, int b)`](http://developer.android.com/reference/android/graphics/drawable/LayerDrawable.html#setLayerInset%28int,%20int,%20int,%20int,%20int%29) a try? The docs say: *"Specify modifiers to the bounds for the drawable[index]. left += l top += t; right -= r; bottom -= b;"* – MH. Jul 04 '13 at 19:32
  • That did it! Thanks a bunch--please put this comment as an answer so I can award you the bounty. – user460847 Jul 05 '13 at 22:08

4 Answers4

3

As per earlier comment:

Did you give setLayerInset(int index, int l, int t, int r, int b) a try? The docs say:

Specify modifiers to the bounds for the drawable[index]. left += l top += t; right -= r; bottom -= b;

MH.
  • 45,303
  • 10
  • 103
  • 116
1

Judging by the source code for LayerDrawable, the method which would allow you to do that is private. But you might be able to accomplish this with a LayerDrawable holding an InsetDrawable

Tavian Barnes
  • 12,477
  • 4
  • 45
  • 118
0

If you can elaborate as to what reason you are changing the color programmatically? It seems a little pointless to do this if you are not also controlling the background color. If you are controlling the background color then you are probably using styles in which case I can think of several methods of doing this.

Simon

Simon
  • 10,932
  • 50
  • 49
  • I want the divider bar color to change with the section the user is on, and the section colors are gotten from a web service at runtime. I will always want the background color of the action bar to be black, but NOT the divider bar color. – user460847 Jun 28 '13 at 20:08
0

This worked for me:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <item android:id="@+id/actionBarLineParent">
        <shape
            android:id="@+id/actionBarLine"
            android:shape="rectangle" >
            <solid android:color="@color/red_all_files" />
        </shape>
    </item>

    <item
        android:id="@+id/actionBarColourParent"
        android:bottom="2dip">
        <shape
            android:id="@+id/actionBarColour"
            android:shape="rectangle" >
            <solid android:color="@android:color/white" />
        </shape>
    </item>

</layer-list>

Then calling:

final LayerDrawable ld = (LayerDrawable) getResources().getDrawable(R.drawable.actionbar_background);
ld.setDrawableByLayerId(R.id.actionBarLineParent, new ColorDrawable(Color.BLUE));
getActionBar().setBackgroundDrawable(ld);

You need to make sure you set the android:id

brandall
  • 6,094
  • 4
  • 49
  • 103