Regnodulous
Regnodulous

Reputation: 493

How to change button background colour without changing onclick/onpress colors

I'm wondering if this is even possible but hopefully someone will be able to confirm.

I've created a simple custom button layout in XML to handle the focused/pressed and dormant states. See code at bottom. This works fine when I use it to create a new button. However, I would like the user to be able to change the button colour via a colour picker if they don't like the default. However, the only way I know to change the button background colour programmatically is to use

mybutton.setBackgroundColor(someothercolor);

but if I do this it overwrites all the XML layout code and I lose the colour change when the button is pressed. I guess this is by design as I'm essentially overwriting the entire background style but what I really want to do is to allow the user to change the button colour when its not pressed to something custom but keep the style and layout of the other states the button could be in (i.e. what happens when its pressed).

Any ideas anyone?

Thank you in advance.

Nat

<?xml version="1.0" encoding="utf-8"?>


<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" android:drawable="@color/originalbuttoncolor" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@color/someotherbuttoncolor" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@color/someotherbuttoncolor" />
    <item android:drawable="@color/originalbuttoncolor" />
</selector>

Upvotes: 2

Views: 1208

Answers (3)

justHooman
justHooman

Reputation: 3054

You can try this:
1. remove the default color <item android:drawable="@color/originalbuttoncolor" />
2.Then:

`StateListDrawable ret = (StateListDrawable) res.getDrawable(R.drawable.btn_selector);
    ret.addState(new int[] {}, new ColorDrawable(your_desire_color));
    mybutton.setBackgroundDrawable(ret);`

Upvotes: 1

zmarkan
zmarkan

Reputation: 615

Maybe you can consider creating a ColorStateList programmatically, as described here: How do I create ColorStateList programmatically?

Upvotes: 2

yshahak
yshahak

Reputation: 5096

You can make multiple files of your selector-list, each one contain different color as the default color, and link those files to the color picker, so you save your logic of selector.

For example:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" android:drawable="@color/originalbuttoncolor" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@color/someotherbuttoncolor" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@color/someotherbuttoncolor" />
    <item android:drawable="@color/originalbuttoncolor" />
</selector>

And:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_focused="true" android:state_pressed="false" android:drawable="@color/yellowbuttoncolor" />
    <item android:state_focused="true" android:state_pressed="true" android:drawable="@color/someotherbuttoncolor" />
    <item android:state_focused="false" android:state_pressed="true" android:drawable="@color/someotherbuttoncolor" />
    <item android:drawable="@color/originalbuttoncolor" />
</selector>

Edit: if you want to take color from user, this may work, if the selector state will overrided by this code:

ColorDrawable cd = new ColorDrawable(); // initialize it from the color picker;
StateListDrawable states = (StateListDrawable) mybutton.getBackground();
states.addState(new int[] {-android.R.attr.state_pressed, android.R.attr.state_focused}, cd); // the minus means false value
mybutton.setBackground(states);

Upvotes: 0

Related Questions