Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android RadioButton button drawable gravity

I am generating RadioButtons dynamically with

RadioButton radioButton=new RadioButton(context);  

LayoutParams layoutParams=new LayoutParams(radioWidth,radioHeight);
layoutParams.gravity=Gravity.CENTER;

radioButton.setLayoutParams(layoutParams);
radioButton.setGravity(Gravity.CENTER);

BitmapDrawable bitmap = ((BitmapDrawable)drawableResource);
bitmap.setGravity(Gravity.CENTER);

radioButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.itabs_radio));
radioButton.setButtonDrawable(bitmap);

as you can see I am desperately trying to set gravity of button drawable to center, but without a reason its always center and left aligned, heres the reason- the default style of android radio button:

<style name="Widget.CompoundButton">
<item name="android:focusable">true</item> 
<item name="android:clickable">true</item>
<item name="android:textAppearance">?android:attr/textAppearance</item> 
<item name="android:textColor">?android:attr/textColorPrimaryDisableOnly</item> 
<item name="android:gravity">center_vertical|left</item> 
</style>

<style name="Widget.CompoundButton.RadioButton">
<item name="android:background">@android:drawable/btn_radio_label_background</item> 
<item name="android:button">@android:drawable/btn_radio</item> 
</style>

Is there any way I can align button drawable to center?

like image 337
Shardul Avatar asked Dec 10 '10 09:12

Shardul


4 Answers

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> 
like image 197
Reuben Scratton Avatar answered Sep 22 '22 02:09

Reuben Scratton


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> 
like image 25
hoot Avatar answered Sep 22 '22 02:09

hoot


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
        )
    }
}

}

like image 39
Reprator Avatar answered Sep 23 '22 02:09

Reprator


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();}
  }
}
like image 30
DJ. XYZ Avatar answered Sep 19 '22 02:09

DJ. XYZ