2

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>
Junior Mayhé
  • 16,144
  • 26
  • 115
  • 161
Regnodulous
  • 473
  • 7
  • 22
  • The solution I see is to save the color hexa into a database then each time you set the button, it uses that saved color – Sheychan Jul 22 '15 at 08:12
  • Thanks for all of the comments. By the sound of it there is no easy way to do this and creating a db just to allow button colour changes seems a bit overkill. Maybe I'm better off just creating a couple of themes or simply losing the pressed state colour if people really want to change the button colour. If anyone has any simpler solution then I'm all ears and thanks again everyone for looking. – Regnodulous Jul 22 '15 at 08:44

3 Answers3

2

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

Community
  • 1
  • 1
zmarkan
  • 605
  • 5
  • 13
1

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);`
justHooman
  • 3,044
  • 2
  • 17
  • 15
0

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);
yshahak
  • 4,996
  • 1
  • 31
  • 37
  • Thanks for the heads up. I did think about doing this but it really limits the number of colours to however many multiple selector-lists you/I can be bothered to create. What I'm really looking for is a way to allow the user to pick any colour they want. – Regnodulous Jul 22 '15 at 08:09
  • true, but what if he is using a color picker? He will make millions of selectors – Sheychan Jul 22 '15 at 08:09
  • If you don't want to limit user with color number, I edited my answer. Not sure it will work but maybe with some modifications (like create new StateListDrawable base on the 2 constant states and the one you defines by the user color that you convert to ColorDrawable) – yshahak Jul 22 '15 at 08:46
  • I tried the code above and although it compiled and ran it didn't;t seem to change anything. Thanks anyway! – Regnodulous Jul 24 '15 at 12:00