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.