Center CheckBox drawable within itself

2020-05-19 04:31发布

I have a CheckBox that I want centered within its own boundaries, not pushed to the side. Probably easier demonstrated than explained:

enter image description here

Note that it isn't centered. Currently defined as:

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

Nevermind the custom button drawable. It behaves the same with a vanilla CheckBox as well (the small check box behaves the same).

12条回答
别忘想泡老子
2楼-- · 2020-05-19 04:40

I believe the problem is that the Checkbox widget uses a regular TextView with the drawableLeft attribute, because it expects text to be shown as well. (This is why you see it centered vertically, but offset slightly to the left.)

If you simply want an image button with multiple states, I suggest using a ToggleButton with your custom images in a state list selector. Or you could create a custom class that extends ImageView and implements Checkable.

查看更多
虎瘦雄心在
3楼-- · 2020-05-19 04:40

Just use following approach:

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

It works well for me. But it works only for

targetSdkVersion >= Build.VERSION_CODES.M || view instanceof FrameLayout

查看更多
劫难
4楼-- · 2020-05-19 04:44

You can use a parent layout to achieve this :

<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>
查看更多
Lonely孤独者°
5楼-- · 2020-05-19 04:45

This will work correct as need required. Just small changes in background and button attributes. This code snippet is tested successfully. Hope this helps.

 <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" />
查看更多
够拽才男人
6楼-- · 2020-05-19 04:49

I'm using MaterialCheckBox from material-components-android(or AppCompatCheckBox. They're similar).

I find that if a CheckBox doesn't have any text, setting its android:minWidth="0dp" and android:minHeight="0dp" can remove all paddings and center the drawable.

查看更多
Emotional °昔
7楼-- · 2020-05-19 04:50

This align problem can be solved by CheckableImageView, a custom View that extend ImageView or AppCompatImageView and implement Checkable directly. It also have other ImageView attributes.

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

Just set your selector drawable in src property of your XML and the drawable state of check will follow automatically.

Example of use

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

Selector example(put inside drawable folder with extension .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>

Change ic_cb_check and ic_cb_uncheck with your preferred images.

This code also available at https://gist.github.com/hendrawd/661824a721c22b3244667379e9358b5f

查看更多
登录 后发表回答