ImageButton background swiching on it's own? Drawables gone wild? - android

I having an issue where the ImageButton background is being drawn with a different drawable from one of my resources. I'm setting the background to be transparent but on some cases it's picking up one of my drawables called bottom_shadow.9.png. Why why!? It's freaking weird...
I've seen this issue before... Some of my app users have complained seeing this issue and now I'm determined to figure this out! Take a look below what I currently have. Any tips or ideas would help.
The color value I created under values/colors.xml:
<color name="transparent">#00000000</color>
My ImageButton under my one xml layout under layout/:
<ImageButton
android:id="#+id/ibHelp"
android:layout_width="wrap_content"
android:layout_height="#dimen/settings_list_item_height"
android:background="#color/transparent"
android:contentDescription="#string/content_desc_more_information"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:scaleType="centerInside"
android:src="#drawable/btn_help" />
This is what I'm seeing on the generated R.java file:
public static final class drawable {
public static final int bottom_shadow=0x7f020000;
}
public static final class color {
public static final int transparent=0x7f080009;
}
This is what it should look like:
This is what I'm seeing:

Could it be related to this issue?
http://code.google.com/p/android/issues/detail?id=20283

I think you are facing the same issue as I on another project : When using the transparent color #00000000 on a background, Android will not actually make it transparent but instead use the background drawable of the element directly under it.
Not sure what I've just said is clear but to check if this is it, I found a quick and easy solutions : Don't use #00000000 as your background transparent but any other completely transparent color : #00FF0000 or even #00F00000 should do it.
See the issue I raised in Google tracker : http://code.google.com/p/android/issues/detail?id=24653

Why are you creating your own color when it's built into Android.R.color? I would try using:
android:background="#android:color/transparent"
Whether or not it fixes your problem, it's simpler and cleaner.

I think you wanna your button's background to be some kind of color, but you have assigned both a src and a color of the button(in the layout xml), which means that the button may use the src picture as the background, not a pure color. I don't know if I made the point.

Just to add to this, I was seeing really strange periodic display corruption in my transparent ImageButton background because I was specifying the items in my background selector as follows:
<item android:drawable="#android:color/transparent" android:state_focused="false" android:state_pressed="false" android:state_selected="true"/>
This might seem to work occasionally, but I definitely had cases where the ImageButtons would render with a ghastly all-white background instead of the nice transparent background.
Note that I was mixing up the android:drawable syntax with a color resource. The correct way to specify a color resource seems to be either an android:color="#FF00FF" attribute or as a child element of item using a element. I searched long and hard, and eventually found this post.

Related

Java/Android get.Background() setting alpha to all instances of drawable? [duplicate]

I've recently updated my phone to Android Marshmallow and ran my existing app on it, but noticed a difference in color behavior: When applying changes to the background of a view (drawable), all views that share the same background (reference) will also the same changes applied. While previously, this was not the case.
Example
In this example, I have a two views with the same background color, and I want to change the alpha level of one of both views.
First we define the views in the layout:
<LinearLayout
android:id="#+id/test1"
android:orientation="horizontal"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/testColor2">
</LinearLayout>
<LinearLayout
android:id="#+id/test2"
android:orientation="horizontal"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/testColor1"
android:layout_marginLeft="5dp">
</LinearLayout>
Both views share the same background color or drawable:
<color name="testColor1">#3F51B5</color>
<color name="testColor2">#3F51B5</color>
The result looks like this:
Now we are going to change one of the two background, like this:
LinearLayout test1 = (LinearLayout) findViewById(R.id.test1);
LinearLayout test2 = (LinearLayout) findViewById(R.id.test2);
test1.getBackground().setAlpha(80);
Which results in this:
However, the desired and expected result is obviously this:
Download the sample project here.
A few thoughs:
When setting the Alpha level trough XML, this behavior does not apply.
It does not matter if both views refer to a different color definition in colors.xml (like in the example), refer to the same color definition of both have the same color (hex) directly in the view's xml file.
Question
How can I make changes to a view's background without this affecting other views that share the same background. Preferably while still being able to use a background that directly refers to a color defined in the color's xml file
Most likely the class of each view's background and constantstate are
the same object. It seems as if the two color resources have been
"merged" somewhere -- meaning they have shared ConstantState. Maybe in
the Resources class' caching? I would've expected them to stay
separate since they're different resources (albeit with the same color
value), but apparently not.
– Snild Dolkow
The ColorDrawable's state stores alpha, so any changes to one will change the others. To prevent this, you can first call mutate() on the drawable, separating the two drawables (by making a copy of the state).
In the example, this would result in using test1.getBackground().mutate().setAlpha(80); instead of directly applying the alpha.

Color/drawable changes are applied to all views with the same background (color) [Marshmallow]

I've recently updated my phone to Android Marshmallow and ran my existing app on it, but noticed a difference in color behavior: When applying changes to the background of a view (drawable), all views that share the same background (reference) will also the same changes applied. While previously, this was not the case.
Example
In this example, I have a two views with the same background color, and I want to change the alpha level of one of both views.
First we define the views in the layout:
<LinearLayout
android:id="#+id/test1"
android:orientation="horizontal"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/testColor2">
</LinearLayout>
<LinearLayout
android:id="#+id/test2"
android:orientation="horizontal"
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#color/testColor1"
android:layout_marginLeft="5dp">
</LinearLayout>
Both views share the same background color or drawable:
<color name="testColor1">#3F51B5</color>
<color name="testColor2">#3F51B5</color>
The result looks like this:
Now we are going to change one of the two background, like this:
LinearLayout test1 = (LinearLayout) findViewById(R.id.test1);
LinearLayout test2 = (LinearLayout) findViewById(R.id.test2);
test1.getBackground().setAlpha(80);
Which results in this:
However, the desired and expected result is obviously this:
Download the sample project here.
A few thoughs:
When setting the Alpha level trough XML, this behavior does not apply.
It does not matter if both views refer to a different color definition in colors.xml (like in the example), refer to the same color definition of both have the same color (hex) directly in the view's xml file.
Question
How can I make changes to a view's background without this affecting other views that share the same background. Preferably while still being able to use a background that directly refers to a color defined in the color's xml file
Most likely the class of each view's background and constantstate are
the same object. It seems as if the two color resources have been
"merged" somewhere -- meaning they have shared ConstantState. Maybe in
the Resources class' caching? I would've expected them to stay
separate since they're different resources (albeit with the same color
value), but apparently not.
– Snild Dolkow
The ColorDrawable's state stores alpha, so any changes to one will change the others. To prevent this, you can first call mutate() on the drawable, separating the two drawables (by making a copy of the state).
In the example, this would result in using test1.getBackground().mutate().setAlpha(80); instead of directly applying the alpha.

Image "inside" button while keeping standard animations

I would like to define a button in Android, through XML, which, below the standard Button graphics (change color when clicked, slightly rounded edges,...), shows an image of my choice. I would like the final product to be somewhat like this:
I have tried change the src and background of an ImageButton, but it does not provide the intended effect. Could you please point me some way of achieving this?
Maybe that's not exactly what you mean by standard, but when you set a background, you end up having to recreate the behavior when the button is clicked. The best way to do it in Android is by using a selector as your button's background. Create a XML drawable with the selector in it.
Example:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="#drawable/button_bg_pressed" />
<item android:drawable="#drawable/button_bg_default" />
</selector>
That way, when your button is clicked, it will change the background to other image that does what you want.
EDIT:
There are other modifiers such as focused, if you need.
If you want Lollipop's ripple effects, I think you can create a Layout and put your button inside it. Change the Layout background and set the button background to transparent. If that doesn't work, try adding android:background="?android:attr/selectableItemBackground" to your button.
As Paulo said, you can achieve the click effect with a selector.
See this answer (https://stackoverflow.com/a/30192562) it gives the code for a very nice and customizable ripple effect.

Android buttons use same Drawable for shape but use different colors

In my application I am using lot of buttons. And all buttons must be in same shape but different in color. I wrote drawable for each button with same features but different solid android:color. This makes more
than 20 drawable xml in my app.
How can I use the same drawable for all buttons, but should be able to
set different background color.
I tried as below, but did not work.
1. In attrs.xml
In drawable folder created buttonshape.xml for rectangle shape
In styles.xml
#drawable/buttonshape
#color/mycolor
In Colors.xml
#000000
And finally in my activity xml, for the button I set the theme as
<Button android:id="#+id/btnTest"
android:theme="#style/TestTheme" android:text="Test" />
This did not work for me. Could anyone of you please help me to sort this out? I am a new to android development. I am not able to figure out where I am going wrong. Any help would be really appreciated.
Thanks,
Roger
use this: GradientDrawable bgShape = (GradientDrawable)view.getBackground().getCurrent(); bgShape.setColor(Color.BLACK);
where ever you want to set different color of any view, just use this code.
.getCurrent gives the selected drawable layerlist
use this it will not throw java.lang.ClassCastException: android.graphics.drawable.GradientDrawable cannot be cast to android.graphics.drawable.ShapeDrawable exception.
it works perfectly for me.

android change view's background color when state changes

how to use color state list for background?
I know android:background="#drawable/drawable_selector", but android:background="#color/color_selector" will cause exceptions.
but android:background="#FFFFFF" works again, can anyone explains why?
now i want to change a layout's background color(not a drawable) when it's pressed,
how to do it?
dynamically you can change like this. Use this if it is useful for you -
textView.setBackgroundColor(Color.parseColor(getResources().getString(R.string.red)));
put the color in res/values/colors.xml,
like #FFFFFF,
and then create a drawable xml in drawable directory,
,that is ok.

Categories

Resources