0

I have an Android application that uses a MapView with an ImageButton control (to move to the user's current location) I've added in the top right-hand corner. The problem I am having is that the ImageButton control's background is too transparent, but changing it with android:background="#BBFFFFFF" alters both the size of the background and removes the blue "flash" that you normally see when the button is pressed - two qualities I wish to retain.

I start with something like this:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

<com.google.android.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
android:apiKey="my api key"
/>

<ImageButton android:id="@+id/googlemaps_select_location"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    android:layout_marginTop="13dp"
    android:layout_marginRight="13dp"

    android:src="@drawable/device_access_location_found"/> 

</RelativeLayout>

Which achieves something that looks like this:

ImageButton control with background that is too transparent

So then I add:

android:background="#BBFFFFFF"

And I get this:

ImageButton control with more opaque background but other properties affected

Note that although this is basically the level of opacity I want, changing the background has affected the padding, and also doesn't display a blue "flash" when pressed (which obviously isn't illustrated in this question).

So my question is, how can I change just the background color/opacity in the non-pressed state, while retaining the other visual qualities of the button? I had a brief read about Android styles and themes, but can't even figure out where this button is getting its style/theme from and how I would go about just overriding the background color/opacity while retaining all of the other visual features.

Bryce Thomas
  • 10,479
  • 26
  • 77
  • 126
  • Post your complete layout xml, as the solutions depend on the order you are adding the different views. – Luis Oct 20 '12 at 10:55
  • @Luis added the rest of the layout to the question. – Bryce Thomas Oct 20 '12 at 13:23
  • That's strange... You are adding the `ImageButton` over the `MapView` and you get an image with high transparency (in 1st image). One of two things must be happening, your original image (png file) is using an low alfa value, or you are changing it programmatically somewhere in your code. – Luis Oct 20 '12 at 13:52
  • The image is from the standard Android Design Icons provided by Google and yes, it appears to have a transparent background. This doesn't explain the difference in the background sizing though/loss of blue "flash" behaviour on click, which is what I'm really trying to figure out how to fix... – Bryce Thomas Oct 20 '12 at 15:03

2 Answers2

1

Issue

When you are assigning a fixed color to the a view background, you are replacing the default background in the view by the fixed color you define.

In reality, the background of a button is not a simple fixed color. It's a state list of color or drawables, which means, depending on button status (focous, selected, pressed, etc.) a different background is used, resulting in the "flash" animation you see when button is pressed. If you replace this state list by a simple fixed color, not depending on buttons status, you get a fixed background (i.e. not changing when button is pressed).

Resolution

There is a xml parameter that can be used to change the image view's alfa (i.e. transparency) which is:

        android:alpha="1"

where the value 1 above can be any float between 0 and 1, being 1 the maximum opacy. However, I believe this is not solving your issue, because you want to change the alfa of background not the image alfa, if I correctly understood your issue. Anyway the default seems to be 1.

One possibility the should work for you is to define a selector to be used as background. The selector will choose the drawable based on his status.

Example

<?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:state_pressed="true" android:drawable="@android:color/darker_gray" />
  <item android:drawable="@android:color/white" />
</selector>

Save the xml file above in your drawable-xxxx folder with the name my_selector In this example I'm using standard android colors, but you can define your own colors. You need to assigne a color for each different button status that you want to have a different color.

Then you need to define your ImageView backgroung to be the selector you defined above:

<ImageButton
    android:id="@+id/googlemaps_select_location"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_alignParentTop="true"
    android:layout_marginRight="13dp"
    android:layout_marginTop="13dp"
    android:background="@drawable/my_selector"
    android:src="@drawable/device_access_location_found" />

With the above changes, the bacground color used by the button will change when the button is pressed and you can have the "flash" effect.

Luis
  • 11,978
  • 3
  • 27
  • 35
  • Thanks for a great answer and I'll accept this soon if nothing better is posted. I may ultimately have to resort to the method you've described, though are there any alternative ways that involve "surgically" setting *just* the background color/transparency while not clicked, and inheriting all of the existing behaviour/appearance for the other states? – Bryce Thomas Oct 21 '12 at 06:04
  • There is another solution that just change the alpha of background, but it's even more complicated. It involves extending the `ImageView` and overriding a method to change the aplha. You can find more information in http://stackoverflow.com/questions/2838757/how-to-set-opacity-alpha-for-view-in-android and in http://shikii.net/blog/android-button-background-image-pressedhighlighted-and-disabled-states-without-using-multiple-images/ you have a full example. – Luis Oct 21 '12 at 10:16
0

I ended up using a style to inherit the look of Widget.ImageButton with just a few minor tweaks for my purposes:

My /res/values/styles.xml file now looks like:

<resources>

<style name="AppTheme" parent="android:Theme.Light" />

<style name="my_loc_btn_style" parent="@android:style/Widget.ImageButton">
    <item name="android:layout_marginTop">8dp</item>
    <item name="android:layout_marginRight">8dp</item>
</style>

</resources>

And my layout file has:

<ImageButton android:id="@+id/googlemaps_select_location"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    style="@style/my_loc_btn_style"
    android:src="@drawable/device_access_location_found"/>

This seems to have inherited a background from Widget.ImageButton that seems to be just slightly transparent, which is what I was after anyway, so I don't set the transparency at all now.

Bryce Thomas
  • 10,479
  • 26
  • 77
  • 126