How to vertically align text in a button with a background drawable? - android

I had a simple button set up with a background image defined like
android:background="?attr/button"
where ?attr/button was a reference to a simple 9-patch png. Everything worked fine, text in the button was aligned correctly.
Then I needed to have a different background for a pressed state of the button. So I changed that to
android:background="#drawable/state_button"
where #drawable/state_button is an xml with the following states
<?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/button_pressed" /> <!-- pressed -->
<item android:state_focused="true"
android:drawable="#drawable/button_pressed" /> <!-- focused -->
<item android:drawable="#drawable/button" /> <!-- default -->
</selector>
And after that I can't align the text properly. If I put android:gravity="center_vertical" the text is drawn about 1/4 of the button height from the top.
I double-checked my 9-patch images, everything seems fine with them. And I also tried having regular pngs for the background, it also doesn't change anything.

You should double check the 9 patch drawables you're using. The standard Android buttons include a huge amount of padding at the top and bottom of the buttons, making it look like the text is always centered. You can see this by opening up the 9 patch file, zooming in closely and looking at the difference between the pixels on the left/top and the right/bottom. The left/top sides mark which parts of the image can be stretched to accomodate more text, while the right/bottom sides mark the space that will actually be filled with text. So the difference between the right/bottom side and the left/top will be the padding. It doesn't quite make sense at first, but after playing around with it it's not so bad.
Just in case you aren't familiar with it, a useful tool for editing 9patches is the draw9patch.bat program in your SDK tools folder.

I had the exact same issue however my 9 patch drawables were ok. The cause was still the same though, just i was using custom drawables using the layer-list element.
It seems that when the Button lays out its text it takes into account all of the states in your selector. Once i'd updated all of the states to match each other my text subsequently aligned correctly.

Related

Splash screen with more than one image on android

Currently using the layer-list to achieve a splash screen with a drawable at the center. The app is targetting API 23+ so using bitmap is not mandatory unless it's necessary for what am trying to do. Basically I'm trying to pull off something similar to WhatsApp's new splash screen where the company reference is placed at the bottom of the screen.
But for some reason, the second image is not being shown at all even though it's visible in the Android Studio preview distorted. What I have currently is:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#color/black700" />
<item
android:drawable="#drawable/ic_app_icon"
android:gravity="center" />
<item
android:drawable="#drawable/ic_company_mark"
android:gravity="bottom|center" />
</layer-list>
As stated in the comments I've noticed that the bottom item depends on the phone resolution on some phones. Why it depends on the resolution, I don't know.
To work around you can add padding at the bottom
<item android:bottom="50dp">
for your bottom item in your layer-list and it will show up.
I haven't found a way to dynamically set the value depending on something and therefore used a value which "looks good" for most display resolutions.

Issue with 9 patch buttons in Android

I'm trying to make a custom button style with a 3d look to it, but I'm having issue with the "pressed" state of the button. The button changes image properly, but the text stays still, which makes it look like the text is actually sliding upwards on press.
(Red lines added to show the cancel button's baseline)
XML for the button view (cmdNegative is the cancel button, layDialogControl is a layout directly above the buttons)
<Button
android:id="#+id/cmdPositive"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/button_positive"
android:text="Accept"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintTop_toBottomOf="#+id/layDialogControl"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/cmdNegative"
app:layout_constraintBottom_toBottomOf="parent" />
XML for the button style (button_gray is the exact same as button_green just... well... gray)
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_enabled="false"
android:drawable="#drawable/button_gray" />
<item
android:state_pressed="true"
android:state_enabled="true"
android:drawable="#drawable/button_green_pressed" />
<item
android:state_focused="true"
android:state_enabled="true"
android:drawable="#drawable/button_green_pressed" />
<item
android:state_enabled="true"
android:drawable="#drawable/button_green" />
</selector>
Unpressed 9 patch:
Pressed 9 patch:
As far as I'm understanding, setting the pixels on the right/bottom should have defined the "content area" and the text should stay in the content view, buuuuuuut that's not the case. Any ideas or pointers as to where I've messed up would be greatly appreciated.
I think you have misunderstood 9-patch images. The stretchable areas (top and left sides) that you define will stretch according to your layout definition. The content area, right and bottom parts defined will set the limits for your content similar to like specifying a rectangle/square of area where your content will be kept. Your image for the accept button(pressed) will not stretch when clicked, thus whatever your image looks like is showing.
Furthermore, if your image has the text in it then there is no point of having a content area. If your button image has text defined then you can solve your problem by re-defining your content area. In other words on the pressed-state you are just substituting an image which had the correct content area region so it looks like it has been stretched on click but it is actually just another image.

Android - How to create image button of different states, default , pressed and focussed

In my android application i want to create three different image of a single image for each state pressed , default and focussed. Is there any tool that can help me to create these images.
I think you misunderstood my problem, i knows that how to use three different image for three different states. I only wants to know that how two create those three images.
here http://code.google.com/p/iosched/source/browse/android/#android%2Fres%2Fdrawable-hdpi
you can see that there are three different images for three differenct states
home_btn_announcements_default.png
home_btn_announcements_pressed.png
home_btn_announcements_selected.png
I wants to know that is there any tool that can create the above three images. I think now my question is clear to everyone.
My Question was that how to add white border for default image , gray border for focussed image. I know that how to change image according to different states. I want to ask you that is there any tool that can put white or gray border around my image.
Use selector save this file in drawable/click.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="false" android:drawable="#drawable/notPressedImage ></item>
<item android:state_pressed="true" android:drawable="#drawable/PressedImage" ></item>
</selector>
use click.xml (click) as button src...

Set opacity to ImageButton?

I want to set opacity to my ImageButton, so when it is unselected, I can see the background a bit, and when I press on it - it becomes normal(no transparency).
If the background you are using is itself an image, then you can't simply "set" the transparency, it's coming from the png image that is the resource for the background. I'd recommend creating 3 9-patch png images for the different stages of the button using transparency as necessary for whichever stage you like. There's a description of how to use a different graphic and xml config file for your own background images in the docs on ImageButton
http://developer.android.com/reference/android/widget/ImageButton.html
If you used a solid color for the background, transparency can be achieved using a color code that has AARRGGBB as elements.
android:background="#55FF0000" would be a partially transparent red background.
Use Selector (http://developer.android.com/reference/android/content/res/ColorStateList.html)
The layout code would look sth like that :
android:background="#drawable/my_selector"
and the selector code would be my_selector.xml with following content :
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" android:drawable="#drawable/button_without_opactity" />
<item android:state_selected="true" android:drawable="#drawable/button_without_opactity" />
<item android:drawable="#drawable/button_with_opacity" />
</selector>
button_without_opacity & button_with_opacity should be 9-patches

Fixed: "Android: Detecting focus/pressed color"

I'm trying to detect the focus/pressed color for button and other elements.
This is needed because I'm developing new components and it's important that those look as part of platform.
Those colors are ORANGE on android sdk and GREEN on HTC SenseUI.
If I could detect that color my component will look as part of platform on both version.
Does anyone knows how to do this?
It's possible to create "selector" which uses custom image for default state and platform default for focus/selection.
To do this follow the steps:
1) create xml file with selector in "res/drawable" (e.g. "red_button.xml"):
<?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:drawable/btn_default" >
</item>
<item android:state_focused="true"
android:drawable="#android:drawable/btn_default" >
</item>
<item
android:drawable="#drawable/btn_default_red" >
</item>
</selector>
2) from folder ".../android-sdk-mac/platforms/android-1.5/data/res/drawable/" take picture "btn_default_pressed.9.png" and change color as you like (I needed to change it to red and for this GIMP is enough).
3) place altered picture in "res/drawable" (e.g. with name "btn_default_red.9.png")
4) define button:
<Button
android:id="#+id/info_button"
android:layout_width="wrap_content"
android:layout_height="37dip"
android:layout_marginTop="1dip"
android:background="#drawable/red_button"
android:text="[Info]" />
That's all.
This is result:
alt text http://img200.imageshack.us/img200/1349/custombutton.png
I had this problem too. As already stated, the problem is that the backgrounds aren't simple colors, they're Drawables that could take on all kinds of appearances. However, I found a work-around that may help. If your custom component looks something like an existing one, e.g. a Button or ListView entry, you can just steal their background/selector and set that as the background for your custom component. E.g., in your custom component constructor:
setBackgroundDrawable(new Button(context).getBackground());
or for a background more suitable for list-like components:
setBackgroundDrawable(new ListView(context).getSelector());
You may want to optimise that code somewhat, but you get the idea.
Those aren't colors. They are a few nine-patch images out of a StateListDrawable. I am skeptical that there will be a reliable way for you to determine what the color is, one that will work across all devices and all versions of Android.
This is pretty much a duplicate of: Android ListView Selector Color
Also, why do you need to detect the colours? Just do nothing and your widgets will fit in to the platform's existing look & feel.
Or if you're writing a custom theme, just make yours inherit from android:Theme.

Categories

Resources