Android ImageButton doesnt change on focus - java

I have 4 buttons, they are all image buttons with "#null" as background.
In the xml file I have:
<ImageButton android:src="#drawable/buttonimgplay" android:id="#+id/imageButton1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="startGame" android:background="#null"></ImageButton>
buttonimgplay is another xml file containing this:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/playpressed" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="#drawable/playabitpressed" /> <!-- focused -->
<item android:drawable="#drawable/playnotpressed" /> <!-- default -->
However, when the user presses the button on the screen it doesnt change, as it switches view to something else. on buttons i havent initialised (ie attached a method) yet this image switching works fine.
Any ideas how I can get the image on the button to change before the view is changed?
Thanks,
Ben

Have you tried adding state_selected to your statelist as well? I don't remember if I had the exact same scenario, but I know that I had to start adding this to some of my state list drawables to get them to work, and I believe it was exactly what you're experiencing.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="#drawable/playpressed" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="#drawable/playabitpressed" /> <!-- focused -->
<item android:state_selected="true"
android:drawable="#drawable/playabitpressed" /> <!-- selected -->
<item android:drawable="#drawable/playnotpressed" /> <!-- default -->

Related

How to toggle only the background of a button and save the state (pressed or not)

I'm trying to make a survey app learning a bit about the FragmentContainerView and navigation graph. Everything works perfect when I use existing widgets such as radiobuttons or checkboxes for the answers.
The problem arises when I try to make my own widget or change the behavior of a normal button so that it behaves as seen in the following screenshot:
The behavior is similar to a ToggleButton but I don't want to change the text (on / off text). What I need is that when I click on the button, it is marked as selected (changing the background) and of course, I need to be able to ask the button if it is checked or not, later.
Using a Button and a custom selector, setting the button as checkable I can achieve the expected behavior.
The selector (btn_toggle_background.xml):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--When Button is not enabled -->
<item android:state_checked="false" android:color="#eeeeee" />
<!--When Button is in pressed state -->
<item android:state_checked="true" android:color="#color/blue_electric" />
<!--When Button is in selected state -->
<!--Default Background Color -->
<item android:color="#eeeeee" />
</selector>
And in the XML Layout:
<?xml version="1.0" encoding="utf-8"?>
<Button
android:id="#+id/button2"
android:layout_width="match_parent"
android:layout_height="60dp"
android:backgroundTint="#drawable/btn_toggle_background" <!-- CUSTOM SELECTOR -->
android:textColor="#drawable/btn_toggle_text" <!-- CUSTOM SELECTOR -->
android:checkable="true" <!-- CHECKABLE HERE -->
android:gravity="fill|fill_horizontal"
android:text="A través de mi compañía de seguros"
android:textAlignment="gravity"
android:textAllCaps="false"
app:icon="#android:drawable/btn_radio"
app:iconTint="#drawable/btn_toggle_icon" <!-- CUSTOM SELECTOR --> />
But then the button no longer responds to the OnClick event anymore (I suspect it is for making it checkable). I assume it will respond to the OnCheckedChange event, but it is an event that does not fire a normal Button.
I have also tried extending a custom view from Button and intercepting the OnClick and sending the event through a custom listener (interface). In this case, the button behavior no longer works. It becomes a normal button and ignores the styles and selectors specified in the XML for the checked state.
Is there a widget that looks like what I need? Would extending from a ToggleButton be more appropriate?
You can use:
<com.google.android.material.button.MaterialButton
android:checkable="true"
app:backgroundTint="#drawable/btn_toggle_background"
.../>
with:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:color="#eeeeee" />
<item android:state_checked="true" android:color="#color/...." android:alpha="xxx" />
</selector>
and the OnCheckedChangeListener:
button.addOnCheckedChangeListener { button, isChecked ->
if (isChecked){
//
}
}
Use the method isChecked to know the status:
button.isChecked

Android set color of icon and text in bottomNavigationBar by program fails

I create a xml file to control my bottomNavigation bar, like this:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_checked="true"
android:color="#color/bottomNavigationBarCheckedNormal" />
<item
android:state_pressed="true"
android:color="#color/bottomNavigationBarCheckedNormal" />
<item
android:color="#color/bottomNavigationBarUncheckedNormal" />
</selector>
It is works when I set this in my activity xml file, like this:
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/activity_news_bottom_navigation"
android:layout_width="match_parent"
android:layout_height="50dp"
app:menu="#menu/bottom_navigation_menu"
app:itemIconTint="#drawable/custom_bottom_navigation_normal"
app:itemTextColor="#drawable/custom_bottom_navigation_normal"
app:labelVisibilityMode="labeled" />
But I want to change this by program, so I try to use this:
bottomNavigationView.setBackgroundColor(Color.parseColor(AppColor.bottomNavigationBarBackgroundColor));
bottomNavigationView.setItemIconTintList(ColorStateList.valueOf(R.drawable.custom_bottom_navigation_normal));
bottomNavigationView.setItemTextColor(ColorStateList.valueOf(R.drawable.custom_bottom_navigation_normal));
But it is not work, icon and text color are not different when select and unselect, and the color is not I set. How can I fix it, thank you.
You should use:
bottomNavigationView.setItemTextColor(
AppCompatResources.getColorStateList(this,R.drawable.custom_bottom_navigation_normal));
The method valueOf:
Returns A ColorStateList containing a single color. This value cannot be null.

Loop animation drawable

I'm trying to animate some png and i would loop the animation. This is my code:
wave.setBackgroundResource(R.drawable.wave_animation);
frameAnimation = (AnimationDrawable)wave.getBackground();
frameAnimation.setCallback(wave);
frameAnimation.setVisible(true, true);
frameAnimation.start();
and here the xml with the png
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
<item android:drawable="#drawable/wave_01" android:duration="200" />
<item android:drawable="#drawable/wave_02" android:duration="200" />
<item android:drawable="#drawable/wave_03" android:duration="200" />
<item android:drawable="#drawable/wave_04" android:duration="200" />
</animation-list>
I added also the android:oneshot=false but doesn't work.
just change android:oneshot="false" to be like this
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item android:drawable="#drawable/wave_01" android:duration="200" />
<item android:drawable="#drawable/wave_02" android:duration="200" />
<item android:drawable="#drawable/wave_03" android:duration="200" />
<item android:drawable="#drawable/wave_04" android:duration="200" />
</animation-list>
Your code above shows
android:oneshot="true"
Which will make your animation run Once and only Once.
You say you tried android:oneshot="false".
That will be essential for running through the animation-list more than once. So put it back.
Keep in mind that running animation is a 'background' task which will terminate when the primary/foreground task completes regardless of its own settings.
If you want something else you might need to take a different approach.
This is running an animation on image. Before starting the animation you need to make sure its not already running. Add a check before starting animation, if its running then stop it and then start it.
private void startAnimation(){
imageView.setImageResource(R.drawable.img_animation);
AnimationDrawable imgAnimation = (AnimationDrawable) imageView.getDrawable();
if (imgAnimation .isRunning()) {
imgAnimation .stop();
}
imgAnimation .start();
}
img_animation.xml // Check for comments in below
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true" >
<!-- 24 frame per sec | 1000ms/24 i.e. 41ms per image -->
<item
android:drawable="#drawable/ball01" android:duration="41"/>
<item
android:drawable="#drawable/ball02" android:duration="41"/>
..........so on ..........
<item
android:drawable="#drawable/ball24" android:duration="41"/>
<!-- Reset to first when animation stops-->
<item
android:drawable="#drawable/ball01"
android:duration="10"/>
</animation-list>

Change only one state (the default state) of an ImageButton background

I'd like to change the background for an image button. Basically the image I have looks great on a transparent background and a bit lousy when there are a bunch of them all with a non-transparent background.
This should be easy - just change the android:background on the button to a transparent color (via a drawable):
click_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"><color android:color="#FF008080" />
</item>
<item android:state_pressed="true"><color android:color="#FF008080" />
</item>
<item><color android:color="#00000000" />
</item>
</selector>
Then the button
<ImageButton
android:id="#+id/players"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:background="#drawable/click_background"
android:contentDescription="#string/players"
android:src="#drawable/speaker_tile" />
The problem is that I actually want to retain the state_focussed and state_pressed versions of the background (which I presume is derived from the theme). I would like to have the background appear when the button is pressed or selected (and appear with the exact same colour/drawable) that would be used by the theme normally when a button is pressed would be helpful.
I was wondering if there is a way to do one of the following, but have so far been unable to find anything on either:
Define a selector that in some what inherits from another (similar to the way a theme can inherit from another).
Create an entirely new selector but have it's XML reference the color/drawable of the theme's state_focussed and state_pressed used for an image button. Edit: It looks like this option is out. I would have needed attributes, but you can't reference them from a drawable. See here
I'd like to do this in Declarative XML rather than Programmatic Java if possible.
You can copy the drawables used by the Android OS into your project and use them in your state-list drawable. You can find the images in {android-sdk-directory}/platforms/android-##/data/res/drawable[-*dpi]
EDIT:
If you go to {android-sdk-directory}/platforms/android-##/data/res/values, you'll find the themes.xml and styles.xml files used by Android. Using them you can figure out which drawables you'll be looking for.
For example, the default theme on newer versions of Android is Theme.Holo. This theme has a default style for ImageButtons declared like so:
<item name="imageButtonStyle">#android:style/Widget.Holo.ImageButton</item>
In styles.xml, this style is defined as follows:
<style name="Widget.Holo.ImageButton" parent="Widget.ImageButton">
<item name="android:background">#android:drawable/btn_default_holo_dark</item>
</style>
Thankfully the background attribute is right there defined in plain sight. Sometimes it's inherited from a parent style and you have to find that instead. In any case, here's the drawable (found in the /drawable directory since it's xml):
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="#drawable/btn_default_normal_holo_dark" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="#drawable/btn_default_disabled_holo_dark" />
<item android:state_pressed="true"
android:drawable="#drawable/btn_default_pressed_holo_dark" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="#drawable/btn_default_focused_holo_dark" />
<item android:state_enabled="true"
android:drawable="#drawable/btn_default_normal_holo_dark" />
<item android:state_focused="true"
android:drawable="#drawable/btn_default_disabled_focused_holo_dark" />
<item
android:drawable="#drawable/btn_default_disabled_holo_dark" />
</selector>
So those are the drawables Android uses for the background of a standard ImageButton in the default (holo dark) theme.

Change button background on touch

i want to change the green background of a button when this is touched without using OnTouchListener. i have this situation: i put some butons in a layer, then the layer in another layer, and the last layer in onother layer. when i touch the button the background is changing(i m using OnTouchListener right now) but if i drag the finger outside of the button and then get it out of the screen the background of the button remains the image from the state when it s touch(otherwise if i click the button and the the finnger off the button it is k the background is changing)
1. Prepare 3 images for button states, and put it into resource/drawable folder.
2. create a new XML file in res/drawable/ folder, in whatever name you want, in this case, we just give a name as my_button.xml. This file defined which button state is belong to which image.
Now, you can refer to this button via this Id : #drawable/my_button.
File : res/drawable/my_button.xml
create xml file using the button image like this with my_button.xml in drawable folder
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/button_pressed_yellow"
android:state_pressed="true" />
<item android:drawable="#drawable/button_focused_orange"
android:state_focused="true" />
<item android:drawable="#drawable/button_normal_green" />
</selector>
add a normal button, and attach the background image to above “my_button” via
android:background:#drawable/my_button
The selector will be as below
<?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" /> <!-- pressed -->
<item android:state_focused="true" android:drawable="#drawable/btn_focused" /> <!-- focused -->
<item android:drawable="#drawable/btn_default" /> <!-- default -->
</selector>

Categories

Resources