I am using drawables to nicely style my buttons, and that works fine, except for the text color in the button.
I have defined a state_enabled="false" item in a selector and using setEnabled gives me the right button styles, but I have to jump through quite some loops to get the text color different. This code for example doesn't work (it shows no, or black, text when disabled, and darkgray when enabled):
public void setButtonsEnabled(boolean enable) {
btnAccept.setEnabled(enable);
btnDecline.setEnabled(enable);
int color = R.color.White;
if (!enable) {
color = R.color.DarkGray;
}
btnAccept.setTextColor(color);
btnDecline.setTextColor(color);
}
I found the solution.
The key lies in also setting the TextColor to a selector in res/colors:
android:textColor="#color/button_text"
android:background="#drawable/button_selector"
For the background selector I used this:
<?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="false" android:drawable="#drawable/btn_buddy_enabled"></item>
<item android:state_enabled="false" android:drawable="#drawable/btn_buddy_disabled"></item>
<item android:state_enabled="true" android:state_pressed="true" android:drawable="#drawable/btn_buddy_clicked"></item>
</selector>
And the textColor selector is this:
<?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="false" android:color="#color/White"></item>
<item android:state_enabled="false" android:color="#color/Gray"></item>
<item android:state_enabled="true" android:state_pressed="true" android:color="#color/White"></item>
</selector>
Simply calling setEnabled() will make everything work fine.
You are using the wrong value for the color. R.color.White returns the resource ID of the value, not the value itself. Try Color.WHITE, or getResources().getColor(R.color.White)
Have you checked out ColorStateLists? They are pretty awesome. So basically apply all those ideas of Drawable selectors to a set of colors.
Make a folder called [Your Project]/res/colors/ and then put an xml file in there called, button_color.xml (or whatever).
button_color.xml
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android"
>
<!-- Any Enabled button, gets White Text -->
<item
android:color="#color/White"
android:state_enabled="true" />
<!-- Buttons with any other state, get DarkGray Text -->
<item
android:color="#color/DarkGray"/>
</selector>
And then for your TextView, you can just do something like, mTextView.setTextColor(R.color.button_color); At that point there is no need for that if/else type of logic, the selector will do it for you. The selector gets rolled up into the color resource but the class it actually generates is called a ColorStateList in case you find it referenced in other documentation.
Related
Following codes work because I added the tabSelectedTextColor attribute directly and selected text color will be white.
<android.support.design.widget.TabLayout
...
app:tabSelectedTextColor="#color/white"
app:tabTextColor="#color/tab_layout"/>
But following codes don't work and I don't know why, maybe it is a bug!
<android.support.design.widget.TabLayout
...
app:tabTextColor="#color/tab_layout"/>
#color/tab_layout
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Selected state defined so it's better to use it -->
<item android:color="#color/white" android:state_selected="true"/>
<item android:color="#color/white" android:state_focused="true"/>
<item android:color="#color/white" android:state_pressed="true"/>
<item android:color="#CCFFFFFF"/>
</selector>
Note: #CCFFFFFF color works so it means, the view gets the tabTextColor attribute value correctly but doesn't recognize the android:state_selected item. I tested all rational states but nothing worked.
TabLayout.class
Following codes copied from TabLayout.class and everything is clear. Don't you think getting selected text color from the selector is better way? If it is, please report it.
if(a.hasValue(styleable.TabLayout_tabSelectedTextColor)) {
int selected = a.getColor(styleable.TabLayout_tabSelectedTextColor, 0);
this.mTabTextColors = createColorStateList(this.mTabTextColors.getDefaultColor(), selected);
}
If you want to change the selected text color then use setTabTextColors methode of TabLayout class like this:
tabLayout.setTabTextColors(Color.parseColor("#ADABAE"), Color.parseColor("#FFFFFF"));
I've got a group of radio buttons, and I want to set the button's background to a solid color when checked. I created a drawable resource, using a selector and item def's like:
<item android:state_checked="true" android:state_pressed="false"
android:drawable="#color/app_tint"/>
with several variations while trying to get it to work. In the layout containing the buttons, I've tried setting both button and background properties (not at the same time, just one or the other in testing) like:
android1:background="#drawable/radio_state"
OR
android1:button="#drawable/radio_state"
I've read several posts, and I feel I'm close, just missing something to get it done. Thanks.
Here's one we did for an app:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_bcnav_ebilling_focus"
android:state_checked="true" />
<item android:drawable="#drawable/ic_bcnav_ebilling_focus"
android:state_selected="true" />
<item android:drawable="#drawable/ic_bcnav_ebilling_focus"
android:state_pressed="true" />
<item android:drawable="#drawable/ic_bcnav_ebilling_focus"
android:state_focused="true" />
<item android:drawable="#drawable/ic_bcnav_ebilling" />
</selector>
Each state has a different drawable, although in this example, we don't really care about all states being very different - just focus=true get a highlighted drawable (it has "..._focus")
I have Button and set background resource to it:
button1.setBackgroundResource(R.layout.color00);
color00:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#drawable/img00" />
<item
android:state_pressed="false"
android:drawable="#drawable/img00" />
</selector>
then I set alpha to this button
button1.getBackground().setAlpha(50);
and then I have problem. If I set this background resource to button2:
button2.setBackgroundResource(R.layout.color00);
So button1's alpha set to button2's alpha with this resource. How to fix it?
Use mutate:
http://developer.android.com/resources/articles/drawable-mutations.html
Drawables use the same state to all their references. User Mutate() for different states.
I try to switch the background of Buttons if they are pressed. I build a Selector like the answer suggested here: Standard Android Button with a different color
Finally I want to put GradientDrawables inside, but for debugging purposes I just set a color, to check if it works.
Here is my Selector
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/red"/>
<item
android:state_focused="true"
android:drawable="#color/white"/>
<item
android:state_pressed="true"
android:drawable="#color/white"/>
</selector>
Unfortunatly this doesn't work. I set the Selector as Button background and only see them in red color. What Am I doing wrong (Build Target 2.1)
put this at the end
item android:drawable="#color/red"
i mean as the third option, it will work.
android checks the xml conditions from the start, the first tag doesn't have any condition, so it will always pick red, so you have put conditions first and then the default one.
here is the code I use, and it works really well.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_clicked"
android:state_pressed="true" android:state_enabled="true" />
<item android:drawable="#drawable/button" android:state_enabled="true" />
</selector>
here I use two images I made using photoshop as a background
the first is button_clicked and the second is button
copy it and change use your own resources.
hope I could help :)
I made a layout that is just simply a textview that says "What do you want?", followed by a series of buttons underneath it.
All of the buttons can be clicked/touched, but when I scroll with the trackball, none of them become highlighted. I noticed, however, then when I disable the background colors on the buttons, I can see the orange box that shows that button's focus.
Is there any way I can visibly see the focus while still being able to have a background color on the buttons?
EDIT: Found the solution! This helped A LOT. Standard Android Button with a different color
Create a "selector" resource in your res/drawable. It can look something like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_selected="false"
android:state_pressed="false"
android:drawable="#color/white" />
<item
android:state_pressed="true"
android:drawable="#color/orange" />
<item
android:state_selected="true"
android:state_pressed="false"
android:drawable="#color/blue" />
</selector>
Then set the background of your button to be:
android:background="#drawable/your_selector"
Rather than applying a simple background color to buttons, try applying a ColorStateList instead.
To do so, define a new XML file at
/res/color/buttonstate.xml
and use code such as the following:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="# FOCUSED COLOR HERE"
android:state_focused="true" />
<item android:drawable="# DEFAULT COLOR HERE" />
</selector>
Notes:
You can definitely add more colors for more states, such as pressed, enabled, and certain other factors.
In the layout or code just reference R.color.buttonstate or #color/buttonstate (the XML's filename).
Make sure the default color is last. This is because it goes down the list and finds the first item that has all of the states the same as it. If you don't provide android:state_focused="false" for the default item and put it first, it will always display.
You can do a similar thing with drawables and
nine-patch drawables to make your own custom button styles.
Rather than just change the background color, consider using a 9-patch style. This is more work to begin, but you'll have much more control over your app's appearance.
Modify your Button layout to look something like this (the style line is the kicker):
<Button
style="#style/PushButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Your styles.xml resource file then should contain a style similar to this:
<style name="PushButton">
<item name="android:background">#drawable/btn</item>
</style>
Then the btn.xml (put in in res/drawable) contents should look something like this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/btn_pressed"
android:state_pressed="true" />
<item android:drawable="#drawable/btn_focused"
android:state_pressed="false"
android:state_focused="true" />
<item android:drawable="#drawable/btn_default"
android:state_focused="false"
android:state_pressed="false" />
You would then use some image editor to create files named btn_pressed.9.png, btn_focused.9.png, and btn_default.9.png. Drop these files in your res/drawable.
A good starting point is the Google IO app (I lifted the code examples from it). Just grab the png files and modify them to match your desired style.
Keep in mind you can put all sorts of stuff in the style now, like text size, height and width.