Changing button styles programmatically - android

In my app the user views a document they have made. It includes various elements including Buttons and ToggleButtons.
The user can set a custom theme that changes the Typeface and Text color used in the TextViews/EditTexts as well as the background color of the layouts.
All these elements are generated at runtime.
What I would like is to make the Buttons/ToggleButtons respect the style the user chooses. I can determine the basic background color I want for the buttons at runtime, but if I use View.setBackGroundColor() it becomes a flat colored rectangle whereas I would like to retain the border/shadow effect, plus the color change when pressed. i.e. i would like it to look and behave like a Button, just shaded a different color.
Is it possible to get what I want, given that until the app is running the actual colors required remain unknown?

Rounded corners, shadow effects, etc are often accomplished in Android by using images. See this developer documentation for an explanation of how that works.
A widget can have either an image background, or a solid color background. So, by setting the background color you are override the background image. If you want to change the color without losing everything else, you need to edit the image files.

Generally you can't change styles programmatically; you can set the look of a screen, or part of a layout, or individual button in your XML layout using themes or styles. Themes can, however, be applied programmatically.
There is also such a thing as a StateListDrawable which lets you define different drawables for each state the your Button can be in, whether focused, selected, pressed, disabled and so on.
For example, to get your button to change colour when it's pressed, you could define an XML file called res/drawable/my_button.xml directory like this:
<?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/btn_pressed" />
<item
android:state_pressed="false"
android:drawable="#drawable/btn_normal" />
You can then apply this selector to a Button by setting the property
btn.setBackground(drawable);

Related

Custom RadioButtons with different color

I am new to android and try to create a simple color picker.
The idea is to have a few filled circles showing a color and the selected one should have an circle around it.
That didn't sound too hard. I draw the circles with <shape>, create two resources, one with only a filled circle, one with the filled circle and an transparent circle with a solid stroke. Then I created a <selector> and set this as the background of my <RadioButton>.
This worked fine for one color, however now I'd like to have the same styles, but with a different color for each <RadioButton>.
The only solotution I could come up with is to create this triplet of xml-files for each color. This would certainly work, but it strikes me as extremely inelegant.
I tried to access the background of the buttons, but it seems I can only access the <selector>, not it's children.
I also tried to create a FrameLayout that would parent the RadioButton and an ImageView so the RadioButton only needs to display the border. This didn't fully work. I could select a RadioButton, but it wouldn't get deselected upon selecting another one.
I guess the best solution is to have a background that can change itself according to the state of the button, just like <selector> does, but with a more comprehensive way of determining which drawable to use, at least with access to the tag-Property of the RadioButton, but I cannot see how to do this.
check this github repo
https://github.com/VishalJogiya/CustomRadioAndShapes
xml layout code
<customradio.vj.com.library.CustomRadio
android:id="#+id/radio9"
android:layout_width="#dimen/thirty_two_dp"
android:layout_height="#dimen/thirty_two_dp"
android:layout_marginBottom="#dimen/eight_dp"
android:layout_marginLeft="#dimen/sixteen_dp"
android:layout_marginRight="#dimen/sixteen_dp"
android:layout_marginTop="#dimen/eight_dp"
custom:radioColor="#AA00FF"
custom:radioShape="simple_circle2" />

Android: Animating Images?

I have a bar with several ImageViews, each of them is used as a button (by using the OnClickListener). Now what I want to achieve is when a user pressed the image, some kind of a glow effect will appear around the image (much like when you press barButton on the iphone).
Is this possible?
This is possible. The correct way to achieve this is to define a StateList Drawable.
The statelist defines a separate drawable for each state.
For example the following xml defines a drawable that shows the blue_button_pressed drawable if the button is pressed and the blue_button_active drawable in all other cases.
<?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/blue_button_pressed"/>
<item
android:drawable="#drawable/blue_button_active"/>
</selector>
You put this file in the drawable folder like any other image and also reference it in the layout files like any other drawable.
Most Views don't actually animate animatable Drawables though, for some reason. To do this, you have to manually start the animation by calling the start() method on the AnimationDrawable (or Animatable, for that matter).
You can't do this immediately after setting the Drawable to a View though, for some weird reason. Instead, you can try to post the start call to a Handler, so that there is some time between the initial setting of the Drawable and the start of its animation.
Didn't have time to find out why it behaves like this yet, but it is what I ended up having to do.
You could manually generate this glow effect as a background picture and make it appear as a parent view behind the actual images when clicked. But I don't think there is any native function for that.

How to change text style based on state with XML?

StateListDrawables and <selector> are great for setting different drawables for each state of a view, but is there a way to tie in what text style that view should use for each of those states?
For example, if you had a button that was white with black text, and when clicked, the button color became black, you would want your text color to change to white. I can imagine how I would do this with code, but is there a way to do it with XML similar to the <selector> used for drawables?
Well there sort of is. I don't believe there is a way to say, something like state_focused use Bold or italics or fontSize = 20. But there are ways to change the color. So using the selector mechanic you can create a ColorStateList
http://developer.android.com/reference/android/content/res/ColorStateList.html
Basically you do the same thing as you would a state list drawable using a selector except that you can place a color inside the individual items. Then you save your XML inside the color folder.
/res/values/color/my_stateful_color.xml
and set the android:textColor to "#color/my_stateful_color"

Avoiding highlight flash in Android

I have two drawables that are used as backgrounds to indicate state (pressed or selected) of my list items. The Pressed drawable is a selector, but with no state specified; it is wired up via XML to be the android:listSelector for the list.
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#drawable/my_actual_drawable" />
</selector>
The Selected drawable, however, is applied by code, because it's complicated and more than one simple background drawable change needs to happen when an item is selected.
If I click very quickly between two list items, one item can have (and keep) the Selected highlight while a different item has (and keeps) the Pressed highlight. I believe this is because the press happens so quickly that it is not interpreted by the underlying framework as a click, so no onItemClick reaches my list.
One solution is to use the selector with state (that's what selectors are for!):
<?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/my_actual_drawable" />
</selector>
but this has the unfortunate effect of turning off the Pressed highlight before my code can apply the Selected highlight, so there is a flash of unhighlightedness between the two states, no matter how early in the onItemClick handler I put the setBackgroundResource call.
Another solution would be to monitor not only onItemClick events, but also onTouch events, and handle everything in code; that appears to make things too slow.
What can I do to avoid both the flash and the double-selection state?
I see where you say that your situation is more complex than just simply changing the background drawable, so I'm sorry if I have over-simplified.
Why don't you let the xml selector handle all that it can? You should be able to setup the selector xml to handle both the pressed and selected states for changing the background resource to avoid the flash and double-selection that you're seeing. My assumption is that the other stuff that you're doing in java is fast enough to not be noticeable if the background isn't doing strange things.
I like to use the list_selector_background from the android framework and the drawable documentation for state list as my references for doing things like this although the list_selector_background is probably a little more complex that yours will need to be.

Android ImageButton selector - one xml per button?

When using the "selector" to specify different images for buttons for different states, such as pressed, focused etc, do I have to write an xml file for each button? I have about 15-20 buttons in my app, so was wondering if there is a way to write just one xml and refer to parts of it?
Thanks
Chris
There is no way to refer to parts of a StateListDrawable, at least that I am aware of.
However, since StateListDrawables are usually used for button backgrounds, it is unclear why you need more than one in the first place.
StateListDrawable changes the Drawable based on the current state, as state changes at runtime. Choosing what Drawable to use initially is something you already do when specifying the Drawable in the first place.
Even classes like LevelListDrawable still require you to specify the level to the Drawable, not on the actual View the Drawable is used on and AFAIK Android automatically checks if a Drawable can handle states and if so passes them. The Drawable never gets reference to the View the Drawable is being used on.
I would just create multiple Drawable files for each button. If you want to share certain attributes of the Button like text color, padding, font sizing, etc you should use Android styles.
Android styles would let you have styles like BlueButton, RedButton, GreenButton which you can inherit styles. So you could have BlueButton that sets the text color, text size, text shadows, the drawable for blue etc, then create another style for Red that just inherits BlueButton and only changes the Drawable (although it can change any attribute it wishes) and then just use them on your Button widgets. You would still need to have multiple Drawable files for the styles to link to, but the styles can all be in one file.

Categories

Resources