set Selector for Button Programmatically issues - android

I have a row of buttons and i am setting their selectors for background and text programatically. The reason i want to do this programmatically is because, I have a set of themes the user can choose from and depending upon the theme selected, i want to change the selector for the button.
For example, if the user selects a blue theme, when loaded, the background of the button is blue and text colour is white. When he presses the button, the background changes to white and the text colour changes to blue. When user removes the finger from button, the changes revert back to default blue for background and white for text colour. You can see the respective selectors for blue below.
This is similar to all other themes. I have separate XMLs for all the themes. The selector for text colour change works fine. The problem is with the background selector for button.
selector_background_blue.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/white" android:state_pressed="true"/>
<item android:drawable="#color/blue_500"/>
</selector>
color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:color="#color/blue_500"/>
<item android:color="#android:color/white"/>
</selector>
I have a class that returns the drawable(selector) depending upon the theme selected. I am getting the selector as follows:
public Drawable getButtonBackgrounds(String theme) {
Drawable drawable = null;
if (theme.equalsIgnoreCase(Const.Theme.BLUE))
drawable = context.getResources().getDrawable(
R.drawable.selector_background_blue);
return drawable;
}
I'm setting these selector for button's background as follows:
private void setButtonBackgrounds(Drawable buttonDrawable) {
int sdk = android.os.Build.VERSION.SDK_INT;
if (sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
btnA.setBackgroundDrawable(buttonDrawable);
btnT.setBackgroundDrawable(buttonDrawable);
.....
.....
btnVoice.setBackgroundDrawable(buttonDrawable);
} else {
btnA.setBackground(buttonDrawable);
btnT.setBackground(buttonDrawable);
.....
.....
btnVoice.setBackground(buttonDrawable);
}
}
button's xml:
<Button
android:id="#+id/btnT"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:background="?android:attr/selectableItemBackground"
android:text="#string/button_t"
android:textSize="22sp" />
Total Row's XML:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<Button
android:id="#+id/btnA"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:background="?android:attr/selectableItemBackground"
android:text="#string/arithmetic_symbol"
android:textSize="16sp" />
<Button
android:id="#+id/btnT"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:background="?android:attr/selectableItemBackground"
android:text="#string/trigonometric_symbol"
android:textSize="16sp" />
<Button
android:id="#+id/btnN"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:background="?android:attr/selectableItemBackground"
android:text="#string/voice_calculator_symbol"
android:textSize="16sp"
android:visibility="gone" />
<ImageButton
android:id="#+id/btnVC"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:background="?android:attr/selectableItemBackground"
android:contentDescription="#string/empty"
android:src="#drawable/ic_keyboard_voice_black"
android:text="" />
<Button
android:id="#+id/btnC"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:background="?android:attr/selectableItemBackground"
android:text="#string/button_c"
android:textSize="16sp" />
<Button
android:id="#+id/btnD"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:background="?android:attr/selectableItemBackground"
android:text="#string/button_del"
android:textSize="16sp" />
</LinearLayout>
This is the same for all the buttons in the row.
The drawable is set just fine on the load. Please refer to the image below.
The problem is When I click on a button(for ex., A), the adjacent ImageButton(microphone) is also changing its state. Please look at the images below:
Why is this happening? Can someone help me with this. Please let me know if you need any other info.

I think that you are experiencing a mutate-related issue (please take a look here, it's extremly useful)
You need to call mutate() on your drawable before assingning it to the View if yout don't want to share the common state across the various instances:
Drawable buttonDrawable = context.getResources().getDrawable(R.drawable.btn);
buttonDrawable.mutate()
btnA.setBackgroundDrawable(buttonDrawable);
In your code you are using the same Drawable for more then one View, so you need to adopt the approach I've described above to avoid the state-sharing.

Dude You have to set the selector From The XML File See below:
<Button
android:id="#+id/btnT"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="0.20"
android:background="#drawable/button_selector"
android:text="#string/button_t"
android:textSize="22sp" />
Here The property android:background="#drawable/you_drawable_selector" is where you have to set The Selector.
Hope I helped.

Related

Clickable icon on image

I want to add a clickable “favorite icon ❤️“ on the top of the ImageView for an Android project. I found similar to this in Zillow application as in the attached image. Any help please?
image from Zillow
use checkbox for this, use 2 icon one is favorite (full heart) and the other is an unfavourite icon(heart with the only border) and set In the selector
set selector file in android:button property in the check box
<androidx.appcompat.widget.AppCompatCheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="#drawable/selector_checkbox"/>
Here is the selector file,
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="true"
android:drawable="#drawable/checkbox_favorite" />
<item
android:state_checked="false"
android:drawable="#drawable/checkbox_unfavourite" />
</selector>
Follow this code ,
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="center"// your scale image on your need!
android:src="your_image" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_baseline_favorite_24"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:clickable="true"// doesnt need just hard code like setOnClick...
android:layout_alignParentEnd="true"
android:layout_margin="16dp"/>
</RelativeLayout>

How to make animation when clicking a TextView?

How to animate a TextView to act like a Button when long pressed?
I've created a TextView using this code
<TextView
android:text="Start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnStart"
android:layout_alignParentBottom="true"
android:gravity="center"
android:clickable="true"
android:focusable="true"
android:longClickable="true"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:textAllCaps="true"
android:textStyle="bold"
android:background="#drawable/rectangle"
android:textSize="20sp"/>
but even setting android:longClickable="true" the TextView does not show the bubble animation when is long pressed. The expected result is here.
You need to set selectable background:
<TextView
android:background="?attr/selectableItemBackground"
.../>
But seeing that you already use android:background you can also use android:foreground instead of it:
<TextView
android:foreground="?attr/selectableItemBackground"
.../>
But beware that android:foreground will work only starting with API 21 (Lollipop).
If you need to have your #drawable/rectangle AND to support Android <5.x then you'll have to create a custom drawable for this to work. See the RippleDrawable documentation for details.
I think you are looking for ripple effect in listview. please add
android:background="?attr/selectableItemBackground". in your textview
If you need to set your custom background you can do something 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/state_one"></item>
<item android:state_enabled="true" android:drawable="#drawable/state_two"></item>
<transition
android:fromId="#+id/usual"
android:toId="#+id/selected" >
<animation-list>
<!--fill in your animation here-->
</animation-list>
</transition>
</selector>
You have to use the xml above instead android:background="#drawable/rectangle".
Also you need to design state_one and state_two in your drawables.

Selector background drawable changing color of parent

I would like to achieve an effect where the background of one of my TextViews is changing on click. I'm achieving this via the drawable below with the state being pressed. I'm running into a strange scenario where if I pressed on the textview, drag away from it, then release my finger, the container background turns grey but the TextView background is white.
Somehow, the drawable effect is being transferred to the parent and causing this weird behavior. Tapping in other areas causes the parent background to change color (it should always remain white). Additionally, this layout is a header of a ListView.
<LinearLayout
android:id="#+id/1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="#+id/2"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/onclick_effect">
<TextView
android:id="#+id/3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/myPublicProfile"/>
<TextView
android:id="#+id/4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<TextView
android:id="#+id/5"
android:layout_width="#dimen/dprEightyFive"
android:background="#drawable/onclick_effect"
android:layout_height="match_parent"
android:gravity="start|center_vertical"/>
</LinearLayout>
drawable/onclick_effect
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<color android:color="#color/grey_subtle" /> <!-- pressed -->
</item>
<item>
<color android:color="#color/White"/>
</item><!-- default -->
</selector>
in xml you can try
android:duplicateParentState="true"

ImageView is not highlighting on click

I am designing an app for multiple devices.In that I am using a imageview and using selector i am setting the background image depends on the state.I works fine for all the devices except only one 10 inch device.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true" >
<LinearLayout
android:layout_width="145dp"
android:layout_height="239dp"
android:layout_marginRight="6dp"
android:background="#drawable/common_selector_thumbnail_shadow_title_background"
android:gravity="center"
android:orientation="vertical"
android:paddingLeft="5dp"
android:paddingRight="5dp" >
<FrameLayout
android:layout_width="130dp"
android:layout_height="186dp"
android:layout_marginTop="5dp"
android:background="#color/RGB_100_215_216_217" >
<ImageView
android:id="#+id/seasonal_favorites_default_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="center"
android:src="#drawable/tw_noitem_movie" />
</FrameLayout>
<TextView
android:id="#+id/seasonal_favorites_list_text"
android:layout_width="140dp"
android:layout_height="43dp"
android:duplicateParentState="true"
android:ellipsize="end"
android:gravity="center_vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:singleLine="true"
android:textColor="#drawable/common_selector_thumbnail_shadow_title_textcolor"
android:textSize="18dp" />
</LinearLayout>
</FrameLayout>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/thumbnail_title_bg_focus" android:state_focused="true" android:state_pressed="true"/>
<item android:drawable="#drawable/thumbnail_title_bg_focus" android:state_pressed="true"/>
<item android:drawable="#drawable/thumbnail_title_bg_focus" android:state_focused="true"/>
<item android:drawable="#drawable/thumbnail_title_bg"/>
</selector>
Thanks in advance.
Probabilly you have to put in your manifest file: hardwareAccelerated="true"
Try that and let me know if it worked!
Use ImageButton there are two methods setBackgroundResource, setImageResource to set resources for button(which one will be pressed) and for image itself
You need to add android:clickable="true" to the LinearLayout or set a OnClickListener there. Otherwise your selector background does not get activated.
Use ImageButton instead of ImageView to get the selector work.
If you can provide the different states of the image then see this
post
Otherwise...
Use a LayerDrawable for the image source. One layer is the actual image, the other layer is a state list selector.
LayerDrawable d = new LayerDrawable(new Drawable[]{getResources().getDrawable(R.drawable.my_image), getResources().getDrawable(R.drawable.my_selector_list)});
imageView.setImageDrawable(d);
Or you can define a layer drawable XML resource and use that in your layout XML.

Changing background or foreground button color dynamically in android

Suppose I have a footer like the following in my app, defined in a XML file such as footer.xml:
<LinearLayout android:id="#+id/llfooter"
android:layout_weight="1" android:layout_width="fill_parent"
android:orientation="horizontal" android:layout_height="0dp"
android:visibility="visible" android:background="#drawable/fbg"
android:weightSum="5.0" android:gravity="center"
android:layout_margin="0dp">
<Button android:id="#+id/home" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1"
android:background="#drawable/home" android:textColor="#FFFFFF"
android:padding="10px"></Button>
<Button android:id="#+id/issue" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1"
android:background="#android:drawable/ic_menu_send" android:textColor="#FFFFFF"
android:padding="10px"></Button>
<Button android:id="#+id/browse" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1"
android:background="#android:drawable/ic_menu_slideshow" android:textColor="#FFFFFF"
android:padding="10px"></Button>
<Button android:id="#+id/search" android:layout_height="wrap_content"
android:layout_width="wrap_content" android:layout_weight="1"
android:background="#drawable/search" android:textColor="#FFFFFF"
android:padding="10px"></Button>
<Button android:layout_height="wrap_content" android:id="#+id/favorite"
android:background="#drawable/favorite" android:layout_width="wrap_content"
android:focusable="true"
android:clickable="true"
android:layout_weight="1"
android:textColor="#FFFFFF" android:padding="10px"></Button>
</LinearLayout>
Now, the problem is that home, issue, browse, etc. are PNG icons, and when I tap on them, user can't have feedback of touching, because they stay unchanged.
I would like to change background colour on pressing them (e.g. just a bit lighter). I know I can write down XML drawables () one per button, such as the following
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:state_pressed="true"
android:drawable="#drawable/bgalt" />
<item android:state_focused="false" android:state_pressed="true"
android:drawable="#drawable/bgalt" />
<item android:drawable="#drawable/bgnorm" />
</selector>
.. but if I have 10 buttons (say, 5 for footer, 5 for header) I should create other 10 buttons with altered background (so more work with graph editor and .apk heavier because of more raster icons.. ).
Is there a way to create (even in java) a ligher color "onClick" and normal color "onRelease" instead, with only one icon per feature in resources?
Any suggestions?
Tnx in advance.
Gabo
Use an ImageButton, and set the android:src parameter to the button drawable with a transparent background, then set the android:background value to a selector drawable that changes color when selected for example.
That way you have a set of drawables for your icons and one drawable only for the background which changes according to the state of your button
you can get button bitmap in onTouch in the code and change color, but it's bad idea.
selector is best solution.

Categories

Resources