android RadioButton可拖动重力

android RadioButton可拖动重力,android,radio-button,center,drawable,Android,Radio Button,Center,Drawable,我正在使用动态生成单选按钮 RadioButton radioButton=new RadioButton(context); LayoutParams layoutParams=new LayoutParams(radioWidth,radioHeight); layoutParams.gravity=Gravity.CENTER; radioButton.setLayoutParams(layoutParams); radioButton.setGravity(Gravity.CEN

我正在使用动态生成单选按钮

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);
正如你所看到的,我正在拼命地尝试将按钮drawable的重心设置为中心,但没有理由它总是居中和左对齐,原因如下-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>

真的
真的
?安卓:属性/文本外观
?android:attr/textColorPrimaryDisableOnly
中心垂直|左
@android:drawable/btn\u radio\u label\u背景
@android:drawable/btn_收音机
是否有任何方法可以将可拖动的按钮对齐到中心?

根据它始终是左对齐的

(注意行
buttonDrawable.setBounds(0,y,buttonDrawable.getIntrinsicWidth(),y+高度);

您必须从
RadioButton
派生一个新类,并重写
onDraw()

稍后添加的示例:

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();}
  }
}
好的,这就是你要做的。首先,这里有一个布局:

<?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>
最后,这里有一个attrs.xml文件,您需要放入res/values,这样代码就可以获得平台定义的属性

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

简单解决方案,您可以向RadioButton添加背景,或设置背景=“@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>


基本上-我有一个水平对齐的单选组,通过将背景颜色扩展到左侧20dp(或单选按钮宽度的1/2),它看起来像是居中的。

基于@hoot answers,我定制了它,使文本和绘图都可以在不使用附件的情况下居中

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

}

基于@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();}
  }
}

我还认为这听起来像个bug,因为它总是左对齐的。在我的例子中,我通过设置
android:minWidth=“0dp”
android:layout\u width=“wrap\u content”
解决了这个问题,因为材质组件将
android:minWidth
设置为大于可绘制宽度的宽度。如果
单选按钮需要居中,则可以将其添加到容器中,因此无需实现自定义视图

下面是一个它的外观示例:

<FrameLayout
    android:layout_width="200dp"
    android:layout_height="200dp">

    <RadioButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:clickable="false"
        android:minWidth="0dp" />

 </FrameLayout>


但是,请注意,设置最小宽度是有原因的,因为使用了材料设计
?attr/minTouchTargetSize
。因此,如果您确实喜欢上述内容,容器也应该是可触摸的。

非常感谢。请允许我指出,您的版本有一个自定义构造函数,没有正确使用属性,因此不能作为RadioButton的替代品。不要介意。这是我最后一次遇到这种麻烦。另外,请允许我指出,我确实回答了您的问题:您将RadioButton子类化,而不是android.R.id.empty,定义透明颜色并使用R.color.transparent,否则,引发InflateException,但其真正原因是
android.content.res.Resources$NotFoundException:可绘制资源ID中的文件0x1020004
setButtonDrawable(android.R.color.transparent)编译'com.android.support:design:23.0.1'
a.getDrawable(1)返回null。使用
a.getDrawable(R.styleable.CompoundButton\u android\u按钮)对我有效。但这并不能解决问题-感谢您的努力,收音机的按钮仍将与左喇叭对齐-但仍然没有。任务是对齐
按钮
对象,您使用的是drawableTop。看到接受的答案-你需要实现一个自定义的单选按钮来实现这一点。很好,这肯定是一个黑客,但它的工作。我必须有一个单选按钮,只有一个图像没有文字和图像需要居中。我刚把textsize设为0,得到了我所需要的+1
<FrameLayout
    android:layout_width="200dp"
    android:layout_height="200dp">

    <RadioButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:clickable="false"
        android:minWidth="0dp" />

 </FrameLayout>