web-dev-qa-db-ja.com

android RadioButtonボタンの描画可能な重力

ラジオボタンを動的に生成しています

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

ご覧のとおり、私は必死にボタンの重力を中央に設定しようとしていますが、理由もなく常に中央と左に揃えられています。理由は次のとおりです-デフォルトのスタイルAndroidラジオボタン:

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

描画可能なボタンを中央に揃える方法はありますか?

26
Shardul

CompoundButton.onDraw()ソースコード によると、常に左揃えになっています。

(行buttonDrawable.setBounds(0, y, buttonDrawable.getIntrinsicWidth(), y + height);に注意してください)

RadioButtonから新しいクラスを派生させ、onDraw()をオーバーライドする必要があります。

後で追加された例:

さて、これがあなたがすることです。まず、レイアウトは次のとおりです。

<?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>

次に、カスタム描画の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);
            }
        }   
}

最後に、attrs.xmlファイルをres/valuesに入れる必要があります。 -)コードがプラットフォーム定義の属性を取得できるようにします。

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

簡単な解決策として、RadioButtonに背景を追加するか、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"/>

更新しました:

<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>
7
hoot

@hootの回答に基づいて、テキストと、アターを使用せずに中央に描画できるようにカスタマイズしました。

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

}

1
Reprator

@Repratorの回答に基づいています。

Javaバージョン:

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();}
  }
}
0
zzzzza

<radiogroup Android:paddingLeft = "20dp" Android:background="@color/gray">

基本的に-私は水平に配置されたラジオグループを持っており、背景色を左20dp(またはラジオボタンの幅の1/2)に拡大すると、中央に配置されているように見えます。

0
Anna Billstrom