CheckBox
を持っているので、自分の境界の中央に配置し、横に配置しないでください。おそらく説明よりも簡単に実証されます:
中央に配置されていないことに注意してください。現在次のように定義されています:
<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
でも同じように動作します(小さなチェックボックスは同じように動作します)。
問題は、チェックボックスウィジェットが drawableLeft
属性を持つ通常のTextViewを使用することです。これは、テキストも表示されることを期待しているためです。 (これが、垂直方向の中央に配置されているが、少し左にオフセットしている理由です。)
複数の状態の画像ボタンが必要な場合は、 状態リストセレクター のカスタム画像で ToggleButton を使用することをお勧めします。または、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>
この位置合わせの問題は、View
またはImageView
を拡張し、AppCompatImageView
を直接実装するカスタムCheckable
CheckableImageViewによって解決できます。他の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プロパティに設定するだけで、ドローアブルチェックの状態が自動的に続きます。
使用例
<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 でも入手できます
Android:button="@null"
Android:foreground="@drawable/btn_favorite"
Android:foregroundGravity="center"
唯一のproperソリューションは、画像にインセットを追加することです。 「フォアグラウンド」を使用するソリューションのほとんどは、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" />
これは必要に応じて正しく機能します。背景とボタンの属性のわずかな変更。このコードスニペットは正常にテストされています。お役に立てれば。
<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" />
次のアプローチを使用してください:
<CheckBox
Android:button="@null"
Android:foreground="@drawable/checkbox_selector"
Android:foregroundGravity="center"/>
それは私にはうまくいきます。しかし、それは
targetSdkVersion> = Build.VERSION_CODES.M || FrameLayoutのインスタンスを表示
チェックボックスのみが表示されるようにAndroid:width
を設定し、Android:layout_gravity="center"
を使用して中央に配置します。
上記のj__mの答えを試しましたが、うまくいきましたが、十分ではありません。
私の場合、タッチ領域を増やすために、CheckBoxのドローアブルの周りにパディングを追加したいと思いました。そして、j__mの答えは、UIの調整を困難にします。
より良い解決策は、元の状態のドローアブルをラップするためのインセットドローアブルを作成することです。これは非常に簡単で完全に機能するはずです。
Recyclerviewでチェックボックスを使用する場合は、このコードを使用して、> SDK23の中央揃えでチェックボックスのバグを回避しないでください。
<CheckBox
Android:button="@null"
Android:drawableLeft="@drawable/checkbox_selector"
Android:drawableStart="@drawable/checkbox_selector"
/>
チェックボックスは、RV(例:スクロール、..)の場合、次回のリフレッシュまでonBindViewHolderにチェックインされません。
私はmaterial-components-Android
からMaterialCheckBox
を使用しています(またはAppCompatCheckBox
。似ています)。
CheckBoxにテキストがない場合、Android:minWidth="0dp"
およびAndroid:minHeight="0dp"
を設定すると、すべてのパディングが削除され、ドローアブルが中央に配置されます。
コードで、チェックボックスの高さを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" />