0

Here's the layout of a button selector I'm trying to build:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:state_enabled="true" android:state_pressed="true" android:drawable="@drawable/btt_down" />
    <item android:state_enabled="false" android:drawable="@drawable/btt_disabled" />
    <item android:drawable="@drawable/btt_normal"/>
</selector>

And here's the layout of the normal state button (btt_normal.xml).

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

    <solid android:color="@color/btt_normal"/>

    <corners
        android:radius="@dimen/rounded_rect_corner_radius"
        />

    <padding
        android:left="@dimen/rounded_rect_padding"
        android:top="@dimen/rounded_rect_padding"
        android:right="@dimen/rounded_rect_padding"
        android:bottom="@dimen/rounded_rect_padding"
        />

</shape>


The only diff between this layout and the layout of btt_down.xml and btt_disabled.xml is this line:

    <solid android:color="@color/..."/>

I would like to know if there's a way to defined a neutral (color free) rounded rectangle drawable resource, and to somehow (inheritance?) assign different colors to it and use them in the selector?

I understand that I can cut down on resources by defining all the rounded rects as part of the selector, but for maintenance sake, I would very much like to avoid copy/pasting the same code lines over and over again with just one color line differentiating between them.

Thank you.

AVIDeveloper
  • 2,954
  • 1
  • 25
  • 32

2 Answers2

0

You can define an xml like

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
 <item android:state_pressed="true"
       android:color="#000000" /> <!-- pressed -->
 <item android:state_focused="true"
       android:color="#000000" /> <!-- focused -->
 <item android:color="#FFFFFF" /> <!-- default -->
</selector>

in your res/color folder and use it as color in your drawable layout.

AnswerBot
  • 447
  • 2
  • 7
  • I like the idea of creating a color folder with specific resources (wasn't aware of that), however, I don't see the magic happening. Here's what I did: 1. Added your suggested XML as `res/color/btt_bg.xml`, 2. Assigned it to my btt_normal.xml's solid using ``, 3. Created a Button resource in my main fragment's layout and assigned btt_normal.xml as it's background (not using the selector or the other btt_disabled and btt_pressed resources from my question's description). Am I missing something? – AVIDeveloper Mar 20 '14 at 23:34
  • I thought it would work but after reading this http://stackoverflow.com/questions/8169257/color-state-list-not-recognized-in-shape-drawable/8169581#8169581 it seems color selector does not work for shapes – AnswerBot Mar 21 '14 at 03:13
0

To answer my own question, I couldn't find a way to avoid redefining the rectangle. So instead of having a file for each state (normal, pressed, focused, disabled) plus a selector file, I ended up putting all the states in a single selector file with just the color differentiating between the states. The foreground color is also a selector, and the colors and rectangle dimensions are retrieved from value resource files.

Here's the directory outline of all participating files:

project
  +-color
    + btt_fg_selector.xml
  +-drawable
    + btt_bg_selector.xml
  +-res
    +-colors.xml
    +-dimens.xml

Following are the selector files with pressed and normal states, and for the sake of a complete answer - value resource files as well:

btt_bg_selector.xml

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

    <!-- pressed -->
    <item android:state_pressed="true">
    <shape>
        <solid android:color="@color/btt_bg_pressed" /> 
        <corners android:radius="@dimen/btt_rr_radius" /> 
        <padding android:left="@dimen/btt_rr_padding" android:top="@dimen/btt_rr_padding" android:right="@dimen/btt_rr_padding" android:bottom="@dimen/btt_rr_padding" /> 
    </shape>
    </item>

    <!-- normal/default -->
    <item>
    <shape>
        <solid android:color="@color/btt_bg_normal" /> 
        <corners android:radius="@dimen/btt_rr_radius" /> 
        <padding android:left="@dimen/btt_rr_padding" android:top="@dimen/btt_rr_padding" android:right="@dimen/btt_rr_padding" android:bottom="@dimen/btt_rr_padding" /> 
    </shape>
    </item>

</selector>

btt_fg_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="@color/btt_fg_pressed" /> <!-- pressed -->
    <item android:color="@color/btt_fg_normal" /> <!-- normal/default -->
</selector>

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="btt_bg_normal">#0000ff</color>
    <color name="btt_bg_pressed">#ffff00</color>

    <color name="btt_fg_normal">#ffff00</color>
    <color name="btt_fg_pressed">#ff0000</color>
</resources>

dimens.xml

<resources>
    <!-- Round rect values -->
    <dimen name="btt_rr_radius">15dp</dimen>
    <dimen name="btt_rr_padding">10dp</dimen>
</resources>
AVIDeveloper
  • 2,954
  • 1
  • 25
  • 32