android RadioButton button drawable gravity

According to CompoundButton.onDraw() source code it's always left-aligned.

(Note the line buttonDrawable.setBounds(0, y, buttonDrawable.getIntrinsicWidth(), y + height);)

You will have to derive a new class from RadioButton and override onDraw().

EXAMPLE ADDED LATER:

Ok, so here's what you do. Firstly, here's a layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<org.test.TestProj.RadioButtonCenter
    android:id="@+id/myview"
    android:layout_width="fill_parent" 
    android:layout_height="100dp" 
    android:layout_centerInParent="true"
    android:text="Button test"
    />
</RelativeLayout>

Secondly here's the custom-drawing RadioButtonCenter:

package org.test.TestProj;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.RadioButton;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;

public class RadioButtonCenter extends RadioButton {

    public RadioButtonCenter(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CompoundButton, 0, 0);
        buttonDrawable = a.getDrawable(1);
        setButtonDrawable(android.R.color.transparent);
    }
    Drawable buttonDrawable;


     @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);

            if (buttonDrawable != null) {
                buttonDrawable.setState(getDrawableState());
                final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
                final int height = buttonDrawable.getIntrinsicHeight();

                int y = 0;

                switch (verticalGravity) {
                    case Gravity.BOTTOM:
                        y = getHeight() - height;
                        break;
                    case Gravity.CENTER_VERTICAL:
                        y = (getHeight() - height) / 2;
                        break;
                }

            int buttonWidth = buttonDrawable.getIntrinsicWidth();
            int buttonLeft = (getWidth() - buttonWidth) / 2;
            buttonDrawable.setBounds(buttonLeft, y, buttonLeft+buttonWidth, y + height);
                buttonDrawable.draw(canvas);
            }
        }   
}

Finally, here's an attrs.xml file you need to put in res/values so the code can get at platform-defined attributes.

<?xml version="1.0" encoding="utf-8"?>
<resources>    
     <declare-styleable name="CompoundButton">
        <attr name="android:button" />
    </declare-styleable>
</resources>

Based on @Reprator answers.

JAVA version:

public class RadioButtonCentered extends AppCompatRadioButton {

  private Drawable buttonDrawable;


  public RadioButtonCentered(Context context) {
    super(context);
  }

  public RadioButtonCentered(Context context, AttributeSet attrs) {
    super(context, attrs);
  }

  public RadioButtonCentered(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }




  @Override
  protected void onDraw(Canvas canvas) {
      if (buttonDrawable != null) {
        int iconHeight = buttonDrawable.getIntrinsicHeight();
        int buttonWidth = buttonDrawable.getIntrinsicWidth();
        int width = getWidth();
        float totalWidth = buttonWidth + getPaint().measureText(getText().toString()) + getPaddingLeft() + getPaddingRight() + getCompoundDrawablePadding();

        if (totalWidth >= width) { super.onDraw(canvas); }
        else {
            int yTop = 0;
            int height = getHeight();
            int availableSpace = (int) ((width - totalWidth) / 2);
            int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
            int rightWidth = availableSpace + buttonWidth;

            switch (verticalGravity) {
                case Gravity.BOTTOM:
                    yTop = height - iconHeight;
                    break;
                case Gravity.CENTER_VERTICAL:
                    yTop = (height - iconHeight) / 2;
                    break;
            }

            setButtonDrawable(android.R.color.transparent);
            buttonDrawable.setState(getDrawableState());
            buttonDrawable.setBounds(availableSpace, yTop, rightWidth, yTop + iconHeight);
            buttonDrawable.draw(canvas);

            float yPos = (height / 2 - (getPaint().descent() + getPaint().ascent()) / 2);

            canvas.drawText(getText().toString(), ((float) (rightWidth + getCompoundDrawablePadding())), yPos, getPaint());
        }
    } else {buttonDrawable = CompoundButtonCompat.getButtonDrawable(this); invalidate();}
  }
}

Based on @hoot answers, I had customised it to make both text and drawable to the center without using attars,

class RadioButtonCenter(context: Context, attrs: AttributeSet) : RadioButton(context, attrs) {
internal var buttonDrawable: Drawable? = null


init {
    buttonDrawable = CompoundButtonCompat.getButtonDrawable(this@RadioButtonCenter)

}

override fun onDraw(canvas: Canvas) {
    val iconHeight = buttonDrawable!!.intrinsicHeight
    val buttonWidth = buttonDrawable!!.intrinsicWidth

    val totalWidth =
        buttonWidth + paint.measureText(text.toString()) + paddingLeft + paddingRight + compoundDrawablePadding
    if (totalWidth >= width) {
        super.onDraw(canvas)
    } else {
        setButtonDrawable(android.R.color.transparent)

        val availableSpace = ((width - totalWidth) / 2).toInt()

        buttonDrawable!!.state = drawableState
        val height = height
        var yTop = 0
        val verticalGravity = gravity and Gravity.VERTICAL_GRAVITY_MASK
        when (verticalGravity) {
            Gravity.BOTTOM -> yTop = height - iconHeight
            Gravity.CENTER_VERTICAL -> yTop = (height - iconHeight) / 2
        }
        var rightWidth = availableSpace + buttonWidth

        buttonDrawable!!.setBounds(availableSpace, yTop, rightWidth, yTop + iconHeight)
        buttonDrawable!!.draw(canvas)

        rightWidth += compoundDrawablePadding

        val yPos = (height / 2 - (paint.descent() + paint.ascent()) / 2) as Float
        canvas.drawText(
            text.toString(),
            (rightWidth).toFloat(),
            yPos,
            paint
        )
    }
}

}


Simple solution, you can add a background to RadioButton, or set background="@null", .

<RadioButton
                android:id="@+id/cp_rd_btn"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:background="@null"/>

updated:

<RadioGroup
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >

                <RadioButton
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:background="@null"
                    android:button="@null"
                    android:drawableTop="@drawable/account_coolme_selector"
                    android:gravity="center" />

                <RadioButton
                    android:layout_width="0dp"
                    android:layout_height="fill_parent"
                    android:layout_weight="1"
                    android:background="@null"
                    android:button="@null"
                    android:drawableTop="@drawable/account_qq_selector"
                    android:gravity="center"
                    />
            </RadioGroup>