2

I have a button in my project that works like this:

The button has 3 different designs for each state - disabled (state_enabled="false"), enabled, pressed.

This button remains disabled if no file is selected, and has a particular design for it. Although, when file is selected, this button becomes enabled and switches to a different design. And the button's highlight color is possible to see every time when the button is enabled and pressed.

What I have tried so far:

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

    <item android:drawable="@drawable/background_blue" android:state_enabled="true" />
    <item android:drawable="@drawable/background_blue_white" android:state_enabled="false" />
    <item android:drawable="@drawable/background_green" android:state_pressed="true" />

</selector>

What I want to have is:

  1. Disabled: Click here to see the disabled button - means I can't click on it unless I have a file selected.

  2. Enabled: Click here to see the enabled button] - means I have selected a file.

  3. Pressed: enter image description here - means if the button is enabled and I press on it.

state_enabled="false" and state_enabled="true" work just fine, whereas state_pressed="true" doesn't work at all. What do you think I am doing wrong?

Please, let me know if my explanations are complicated - I will do my best to describe the problem to make it be as understandable as possible. Thank you so much. Have a nice day!

Lilya
  • 495
  • 6
  • 20

3 Answers3

1

Maybe you should set a default color.

<item android:drawable="@drawable/background_blue" android:state_enabled="true" />
<item android:drawable="@drawable/background_blue_white" android:state_enabled="false" />
<item android:drawable="@drawable/background_green" android:state_pressed="true" />
<item android:drawable="@drawable/background_blue" />

The default color without any "pressed" and "enabled" drawable.

igarasi
  • 137
  • 7
  • or you set a "unpressed" drawable – igarasi May 27 '20 at 10:02
  • Hi Hikari! Thank you a lot of your answer. I have tried what you proposed and I have some little progress, thanks a lot. But disabled state of the button does not look like what I want so far. I added the screenshots for a better understanding. – Lilya May 27 '20 at 10:36
  • In your Kotlin file you need set your button “enabled =false”.the “android:state_enabled” drawable will work. “button.enabled=false” – igarasi May 27 '20 at 10:51
1

A selector will select the first item that matches the current state.

From the documentation:

Note: Remember that Android applies the first item in the state list that matches the current state of the object. So, if the first item in the list contains none of the state attributes above, then it is applied every time, which is why your default value should always be last (as demonstrated in the following example).

A pressed button is also enabled, so your selector still picks the 'enabled' state over the 'pressed' state because it was defined earlier.

You can try adjusting the ordering to fix your issue:

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

    <item android:drawable="@drawable/background_green" android:state_pressed="true" />  <!-- pressed -->
    <item android:drawable="@drawable/background_blue_white" android:state_enabled="false" />  <!-- disabled -->
    <item android:drawable="@drawable/background_blue" />  <!-- default -->

</selector>

To avoid confusion like this in the future a good approach is to be more specific such so that only one item matches at a time.
These items use the original order but only one will match at a time:

    <item android:drawable="@drawable/background_blue" android:state_enabled="true" android:state_pressed="false" />
    <item android:drawable="@drawable/background_blue_white" android:state_enabled="false" android:state_pressed="false"  />
    <item android:drawable="@drawable/background_green" android:state_enabled="true" android:state_pressed="true" />

(Note that it would be better to have a default at the bottom because now it would technically be possible that none match)

RobCo
  • 6,240
  • 2
  • 19
  • 26
  • Hi @RobCo ! Thank you a lot for such a nice explanation. I will take it into consideration from now on. :) – Lilya May 28 '20 at 08:12
0

You should make your button clickable for that.

You can make it with button.setClickable(true)(If you are using JAVA) or you can add in your .xml where you have android:clickable="true".

If you are using Kotlin then add button.clickable = true instead of the first solution with Java code.

Update: You should try a this thing as well. Follow this answer might be helpful. As per that answer, you should keep all states into proper order. I don't know why but I think it should help.

Try this and let me know if it will help you. Thanks & Happy coding..!

Pranav P
  • 1,755
  • 19
  • 39
  • Hi Pranav Patel! Thanks so much for your answer! The button's "clickable" attribute is set to "true" already. The two states (enabled true/false) are changing, but the pressed state doesn't show the needed color. – Lilya May 27 '20 at 09:44
  • Let me check if I will get something I will update my answer. Thanks for understanding. – Pranav P May 27 '20 at 10:12
  • If you can share your button tag from .xml then it would be good. – Pranav P May 27 '20 at 10:13
  • You can try one thing that change drawable with style. Add style into style.xml and use that for `android:state_pressed`. – Pranav P May 27 '20 at 10:20
  • Even, you should try to make `android:state_pressed="false"` initially. – Pranav P May 27 '20 at 10:28
  • Thanks for your comments, Pranav Patel! I am trying to follow every mentioned instruction. I added the screenshots of what I want to have eventually if that's easier. I also noticed that ```state_enabled="true"``` doesn't work with ```state_pressed="true"``` – Lilya May 27 '20 at 10:34