中心CheckBox内部可绘制

时间:2012-11-16 05:58:55

标签: android android-layout checkbox drawable padding

我有一个CheckBox我希望在自己的边界内居中,而不是被推到一边。可能比解释更容易证明:

enter image description here

请注意,它不居中。目前定义为:

<CheckBox
    android:id="@+id/checkbox_star"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:button="@drawable/btn_favorite"

    android:layout_gravity="center"
    android:minWidth="48dp" />

没关系自定义按钮drawable。它与vanilla CheckBox的行为相同(小复选框的行为相同)。

12 个答案:

答案 0 :(得分:29)

我认为问题在于Checkbox小部件使用带有drawableLeft属性的常规TextView,因为它也希望显示文本。 (这就是为什么你看到它垂直居中,但略微偏向左边。)

如果您只是想要一个包含多种状态的图片按钮,建议您使用ToggleButtonstate list selector中使用自定义图片。或者,您可以创建一个扩展ImageView并实现Checkable的自定义类。

答案 1 :(得分:11)

您可以使用父布局来实现此目的:

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center">

    <CheckBox
        android:id="@+id/checkbox_star"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Check box text" />
</LinearLayout>

答案 2 :(得分:6)

我正在使用MaterialCheckBox(或material-components-android中的AppCompatCheckBox。它们很相似)。

我发现,如果CheckBox没有任何文本,则设置其android:minWidth="0dp"android:minHeight="0dp"可以删除所有填充并将可绘制对象居中。

答案 3 :(得分:5)

此对齐问题可以通过 CheckableImageView 解决,自定义View可以扩展ImageViewAppCompatImageView并直接实现Checkable。它还有其他ImageView属性。

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.Checkable;
import android.widget.ImageView;

/**
 * @author hendrawd on 6/23/16
 */
public class CheckableImageView extends ImageView implements Checkable {

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

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

    private boolean mChecked = false;

    private static final int[] CHECKED_STATE_SET = {android.R.attr.state_checked};

    @Override
    public int[] onCreateDrawableState(final int extraSpace) {
        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
        if (isChecked())
            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
        return drawableState;
    }

    @Override
    public void setChecked(boolean checked) {
        if (mChecked != checked) {
            mChecked = checked;
            refreshDrawableState();
        }
    }

    @Override
    public boolean isChecked() {
        return mChecked;
    }

    @Override
    public void toggle() {
        setChecked(!mChecked);
    }

    @Override
    public void setOnClickListener(final OnClickListener l) {
        View.OnClickListener onClickListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                toggle();
                l.onClick(v);
            }
        };
        super.setOnClickListener(onClickListener);
    }
}

只需将您的选择器drawable设置为XML的src属性,并且可以自动跟踪可绘制的检查状态。

使用示例

<your.package.name.CheckableImageView
    android:id="@+id/some_id"
    android:layout_width="48dp"
    android:layout_height="48dp"
    android:src="@drawable/set_your_selector_here"
    android:padding="14dp"
    android:gravity="center" />

选择器示例(放在扩展名为.xml的可绘制文件夹中)

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_cb_check" android:state_checked="true" android:state_focused="true" />
    <item android:drawable="@drawable/ic_cb_uncheck" android:state_checked="false" android:state_focused="true" />
    <item android:drawable="@drawable/ic_cb_uncheck" android:state_checked="false" />
    <item android:drawable="@drawable/ic_cb_check" android:state_checked="true" />
</selector>

使用您首选的图片更改 ic_cb_check ic_cb_uncheck

此代码也可在https://gist.github.com/hendrawd/661824a721c22b3244667379e9358b5f

获取

答案 4 :(得分:4)

android:button="@null"
android:foreground="@drawable/btn_favorite" 
android:foregroundGravity="center"

答案 5 :(得分:0)

如果要在recyclerview中使用复选框,请不要使用此代码绕过&gt; SDK23的中心对齐的复选框错误。

<CheckBox
android:button="@null"
android:drawableLeft="@drawable/checkbox_selector"
android:drawableStart="@drawable/checkbox_selector"
/>

如果RV(例如:scroll,..)下次刷新,则不会在onBindViewHolder中检查复选框。

答案 6 :(得分:0)

设置android:width,使其仅显示您的复选框,然后使用android:layout_gravity="center"将其居中。

答案 7 :(得分:0)

只需使用以下方法:

          <CheckBox
                  android:button="@null"                        
                  android:foreground="@drawable/checkbox_selector"
                  android:foregroundGravity="center"/>

对我来说效果很好。 但它仅适用于

  

targetSdkVersion&gt; = Build.VERSION_CODES.M ||查看instanceof   的FrameLayout

答案 8 :(得分:0)

我已经尝试过以上j__m的答案,并且可以,但是还不够好。

就我而言,我想在CheckBox的可绘制对象周围添加填充,以增加触摸区域。而且j__m的答案使得调整UI变得很困难。

我认为一个更好的解决方案是创建一个inset drawable来包装您的原始状态可绘制对象,这应该非常容易并且完美地工作。

答案 9 :(得分:0)

唯一的正确解决方案是向图像添加插图。大多数带有“前景”的解决方案都无法在API 23以下使用。

btn_favorite_inset.xml在可绘制目录中

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/btn_favorite"
    android:insetLeft="6dp"
    android:insetTop="6dp"
    android:insetRight="6dp"
    android:insetBottom="6dp" />

您的布局文件

<CheckBox
    android:id="@+id/checkbox_star"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:button="@drawable/btn_favorite_inset"
    android:layout_gravity="center"
    android:minWidth="48dp" />

答案 10 :(得分:0)

在代码中,您已将复选框的高度设置为match_parent。将其设置为wrap_content。这样可以解决您的问题。为我工作!

问题:

<CheckBox
    android:id="@+id/checkbox_star"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:button="@drawable/btn_favorite"

    android:layout_gravity="center"
    android:minWidth="48dp" />

解决方案:

<CheckBox
    android:id="@+id/checkbox_star"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:button="@drawable/btn_favorite"

    android:layout_gravity="center"
    android:minWidth="48dp" />

答案 11 :(得分:0)

默认情况下,它有 minHeight 和 minWidth。 将它们设置为 0dp 会将其对齐到其自身边界内的中心。


<CheckBox
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:minWidth="0dp"
    android:minHeight="0dp" />