I'm trying to programmatically add a background resource to a button but as soon as I do that, the highlight effect of when the button is clicked goes away. How do I restore the highlight effect while still using the background?
button_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#layout/avail_button_solid" />
<item android:drawable="#layout/avail_button_shape" />
</layer-list>
avail_button_solid.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ababab" />
</shape>
avail_button_shape.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ffffff" />
<stroke android:width="1dp" android:color="#ff000000" />
</shape>
Java code:
b.setBackgroundResource(R.layout.button_layout);
The code sets the background but takes away the highlighting effect.
Buttons (and many other Android widgets) use a <selector> drawable (the analog in the SDK is a StateListDrawable). This is actually a Drawable container that maps different drawables to different states: pressed, focused, disabled, normal, etc. You should make one of these yourself if you want to replace the button background.
Read more about it here: http://developer.android.com/design/style/touch-feedback.html
Related
I'm working on a project where I have a Main Menu with buttons that have image and text under the image, they are already done:
main menu buttons
To achieve that button layout with rounded corners, I put as background an xml called border_button:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#color/colorPrimary" />
</shape>
And to keep background image and text with rounded corners, my button xml is like that:
<Button
android:id="#+id/buttonMeusDados"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="2sp"
android:layout_weight="1"
android:background="#drawable/border_button"
android:drawableTop="#drawable/button_image_icon_meus_dados"
android:text="#string/my_data"
android:textColor="#android:color/white" />
The problem now is that those buttons don't return any feedback to the user when pressed, they are static, no pressed animation
I found a lot of ways how to do that, but I'm not being able to mix them with what I already have, if I make the pressed effect animation, I lose all my retangle layout with rounded corners and etc
For the pressed effect I mainly followed #Ljdawson answer from this topic: click effect on button in Android but no success, as I explained above
How can I do it?
Your border_button.xml should be a selector. Like in the following example:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- the order of items is important. The first one that matches the state is rendered. -->
<item android:state_pressed="true" android:drawable="#drawable/button_pressed"/>
<item android:drawable="#drawable/button_normal" />
</selector>
<!-- to make transition more visible you can slow it down.
Add this inside of selector tag, after the xmlns:android="..."
android:exitFadeDuration="#android:integer/config_longAnimTime"
-->
button_pressed and button_normal are xml files that draw pressed and normal states of the button, examples given bellow:
<!-- button_pressed.xml -->
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#color/colorAccent" />
</shape>
and
<!-- button_normal.xml -->
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="3dp" />
<solid android:color="#color/colorPrimary" />
</shape>
Good evening everyone!
Is there a way to make my buttons look pressed without having to design two times each button?(one for pressed state, another for not pressed). I've designed the buttons' shapes using http://angrytools.com/android/button/, and using these shapes as the background for the buttons. I've heard about ImageButton but it doesnt seem to apply here as I need the buttons to have text.
Example of one of my background shapes:
Thanks very much in advance!
Try This Code, set this XML file as background to a button.
but_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="#9df20901" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#892379" />
</shape>
</item>
</selector>
Hey guys I just wanna ask question about the default button in android studio when you click it it has effect that it draw circle and fills the button but i wanna know how i can do that in custom button ? thanks for reading
Create a new file "res/drawable/ripple_effect.xml" then add this as background for the button through XML or dynamically.
i.e. android:background="#drawable/ripple_effect"
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:color="#f816a463"
tools:targetApi="lollipop">
<item android:id="#android:id/mask">
<shape android:shape="rectangle">
<solid android:color="#f816a463" />
</shape>
</item>
</ripple>
What I have:
I have a LinearLayout which contains Views with a background Drawable (rectangular shape with rounded corners and a stroke). They act as color selection buttons. Initially the first button has a background with a thicker stroke (4px instead of 1px). Everything is nice (see left side of picture below).
What I want:
However, when I press such a button, I want to remove the thick stroke from the previously selected button and apply it to the actual button. I try it the following way (only a snippet):
// get layout
LinearLayout favoriteColorsLayout = (LinearLayout) findViewById(R.id.favoriteColorsLayout);
// get view at old position, update stroke, invalidate
View view = favoriteColorsLayout.getChildAt(selectedColorButton);
GradientDrawable drawable = (GradientDrawable) view.getBackground();
drawable.setStroke(1, Color.parseColor("#bbbbbb"));
view.invalidate(); // do I need this?
// also update stroke of new view
..
// re-layout
favoriteColorsLayout.requestLayout(); // do I need this?
What I see:
And indeed the thicker stroke is moved but unfortunately the layout is wrong afterwards! The colored background of buttons 2-4 should become thinner when the stroke surrounding them gets thicker so that they are still fitting into the containing layout but this does not happen (see right side of picture below). Instead the stroke is partially cut off (because otherwise it would be drawn outside the bounds of the View). This is not a desired effect.
What do I have to do to get the desired effect instead?
I know how many buttons of which color I have only at runtime, so I would prefer a programmatic solution.
Actually I'm beginning to think it could be an Android bug since drawing the stroke outside the borders per default is surely not desired behavior. I see the effect on the emulator and API level 23 as well as my old phone with API level 11.
A bit of layout xml. The linear layout (Views are added programmatically):
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:id="#+id/favoriteColorsLayout"></LinearLayout>
The button Views:
<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="#dimen/color_selection_button_size"
android:layout_height="#dimen/color_selection_button_size"
android:layout_margin="#dimen/color_selection_button_margin"
android:layout_gravity="center"
android:background="#drawable/color_selection_cell_background">
</View>
The buttons background drawable (color_selection_cell_background.xml):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<stroke
android:width="1px"
android:color="#bbbbbb"/>
<corners
android:radius="5px" />
<gradient
android:angle="90"
android:centerX="0.5"
android:centerY="0.5"
android:startColor="#aaaaaa"
android:endColor="#bbbbbb"
android:type="linear" />
</shape>
Not sure why you are doing it in code but why not have two drawables and change those?
button_blue_selected.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/blue_500" />
<stroke android:width="4dp" android:color="#color/grey_500" />
<corners android:radius="5dp" />
</shape>
button_blue_unselected.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape
android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/blue_500" />
<stroke android:width="1dp" android:color="#color/grey_500" />
<corners android:radius="5dp" />
</shape>
Then update the background drawable in your code:
View view = favoriteColorsLayout.getChildAt(selectedColorButton);
view.setBackgroundResource(R.drawable.button_blue_selected);
Or even better you could use a third drawable with state so you didn't need to update it directly in code:
button_blue.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="#drawable/button_blue_selected" />
<item android:drawable="#drawable/button_blue_unselected" />
</selector>
And then:
view.setSelected(true);
My buttons use two XML files to do some fancy color switching when pressed, but I have a problem with the color drawable (dunno what to call it)...
Here's a button
<Button
android:background="#drawable/main_loginbtn"
android:textColor="#color/main_loginbtn"
android:id="#+id/button1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:onClick="login"
android:text="Login" />
(I know I shouldn't use hardcoded strings, but I will change this later :)
Here's #drawable/main_loginbtn
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle" >
<solid android:color="#FFFFFF"/>
<stroke android:width="2dp"
android:color="#00BFFF"/>
</shape>
</item>
<item>
<shape android:shape="rectangle" >
<solid android:color="#00BFFF"/>
<stroke android:width="2dp"
android:color="#FFFFFF"/>
</shape>
</item>
</selector>
And finally, here's the #color/main_loginbtn file
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#00BFFF"/>
<item android:color="#FFFFFF"/>
</selector>
If I remove the textColor reference to #color/main_loginbtn, it will fix the problem and the text will reappear on the button (in black of course). So i'm pretty sure the problem is in the color drawable.
Normally, I wouldn't care about this, but it messes up the scaling on some buttons because of wrap_content, when there's no text inside the buttons.
Thanks for your time!
UPDATE
I tried creating a second random color drawable, and tested it on a TextView's textColor attribute, and the same problem arose... The entire TextView text disappeared.
So i'm thinking it's a problem with the selector?
Oh, and I also messed up in this question: Nothing "disappears" per say, but rather I can't see the text in the eclipse layout UI. When I run it in the emulator, everything works fine...
You need to set the transparency of your color.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#FF00BFFF"/>
<item android:color="#FFFFFFFF"/>
</selector>
The UI editor is assuming your colors are transparent if you don't (in other words it's defaulting to alpha = 00 if you don't set it).