Android 中心复选框可在其内部绘制

Android 中心复选框可在其内部绘制,android,android-layout,checkbox,drawable,padding,Android,Android Layout,Checkbox,Drawable,Padding,我有一个复选框,我希望它在自己的边界内居中,而不是被推到一边。可能演示起来比解释起来容易: 请注意,它没有居中。目前定义为: <CheckBox android:id="@+id/checkbox_star" android:layout_width="wrap_content" android:layout_height="match_parent" android:button="@drawable/btn_favorite" android

我有一个
复选框
,我希望它在自己的边界内居中,而不是被推到一边。可能演示起来比解释起来容易:

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

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


不要让自定义按钮可绘制。它的行为与普通的
复选框的行为相同(小复选框的行为相同)。

我认为问题在于复选框小部件使用带有属性的常规文本视图,因为它希望文本也能显示出来。(这就是为什么可以看到它垂直居中,但稍微向左偏移。)


如果您只是想要一个具有多个状态的图像按钮,我建议在中使用带有自定义图像的。或者,您可以创建一个自定义类来扩展ImageView并实现Checkable。

您可以使用父布局来实现这一点:

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

这将根据需要正确工作。只是背景和按钮属性中的小变化。此代码段已成功测试。 希望这有帮助

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

这个对齐问题可以通过CheckableImageView来解决,这是一个自定义的
视图
,它扩展了
ImageView
AppCompatImageView
并直接实现
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);
    }
}
只需在XML的src属性中设置选择器drawable,检查的drawable状态就会自动跟随

使用示例

<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" />
使用您喜欢的图像更改ic_cb_检查ic_cb_取消选中


如果要使用recyclerview中的复选框,请不要使用此代码通过对>SDK23的中心校准绕过复选框错误

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


只有在下次刷新时才会在BindViewHolder上选中复选框(例如:滚动,…。

设置
android:width
,使其仅显示您的复选框,然后使用
android:layout\u gravity=“center”
将其居中,只需使用以下方法:

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

它对我很有效。 但它只适用于

targetSdkVersion>=Build.VERSION_code.M | | view instanceof 框架布局


我试过上面j__m的答案,它是有效的,但还不够好

在我的例子中,我想在复选框的可绘制区域周围添加填充物,以增加触摸区域。而j_m的答案使得用户界面很难调整


我认为一个更好的解决方案是创建一个嵌入的drawable来包装您的原始状态drawable,这应该非常简单并且工作完美。

唯一合适的解决方案是向图像添加插入。大多数具有“前台”功能的解决方案在API 23以下无法工作

可绘制目录中的btn\u favorite\u 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" />

在代码中,您已将复选框的高度设置为与父项匹配。将其设置为包装内容。这会解决你的问题。为我工作

问题:

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

我使用的是安卓
材质组件(或
AppCompatCheckBox
)中的
MaterialCheckBox
,它们很相似


我发现如果一个复选框没有任何文本,设置它的
android:minWidth=“0dp”
android:minHeight=“0dp”
可以删除所有填充物并将可绘图对象居中。

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




谢谢你的回复,但这正是我说“中心[…]本身”而不是“中心[…]其他东西”;-)的原因,否则我想我早就这么做了。当你考虑控件的点击区域时,这个问题是非常相关的。然后,如果点击区域是你的问题,则将复选框按钮和复选框文本分隔为两个控件。将复选框与文本视图并排使用。我没有(或不想要)任何文本,也无法解决手头的问题。这是关于创建一个大于其可绘制范围的
复选框,同时将所述可绘制范围定位在窗口小部件边界的中心而不是左侧。您所说的并不能做到这一点。这有助于将复选框置于父布局区域的中心。我甚至不必为复选框本身设置重力。可能不是问题的答案,但它帮助我实现了我想要的。宾果!哦,哇,非常感谢。。。简单又简单。。。我没想到要切换按钮!如果按钮大小大于图像大小,
ToggleButton
如何帮助图像居中?对于最后一句话:“或者您可以创建一个自定义类来扩展ImageView并实现Checkable。”,你们不需要自己制作,只需从我的回答中直接复制它就可以了,复选框的按钮不使用TextView drawableLeft。它自己绘制按钮,并且仅支持Gravity.BOTTOM或Gravity.CENTER\u VERTICAL。如果你这样做的话,你也会失去与复选框相关的动画效果。这对我的用例来说非常有效。再加上android:background的可绘制状态选择器,这实现了一个完全定制的复选框。这个答案并不十分清楚。此外,问题已经解决。@MayankSharma在单击CheckableImageView时如何处理可绘制的更改?@parthpatel我们在xml选择器中定义了它。@HendraWD是从我的代码中处理OnClickListener的问题,后者已经解决。谢谢你的建议天哪,这就是我几个小时以来一直在寻找的东西!非常感谢。我不知道为什么,但是你帮我省了很多时间。谢谢这有记录吗?@PNDA我没有找到任何文件。我只是尝试了每一种组合。在Android Studio 4.1中不起作用。@SamChen我用AS 4.1和MDC 1.2.1验证了解决方案,它是有效的。
<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" />