Ответ 1
Сегодня у меня была такая же проблема (мой пользовательский образ был отрезан с левой стороны). Я исправил его:
android:button="@null"
android:background="@drawable/my_custom_checkbox_state.xml"
Как вы можете видеть на изображении выше. На этом скриншоте есть три вида.
- Первый элемент CheckBox
с текстом и с выключенным состоянием.
- Второй элемент CheckBox
без текста и состояния.
- Последний элемент ImageView
с src, указывающим на отображаемое изображение.
Элементы CheckBox были настроены с помощью android:button
.
Как я пытался использовать меньшие изображения, все флажки выровнены по левому краю.
Сравнение этих двух изображений говорит мне, что размер по умолчанию CheckBox
кажется фиксированным до определенного размера, пока текстовый атрибут не будет достаточно большим, чтобы требовать расширения.
В файле нет ничего особенного. См. Ниже.
custom_cb.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/creditcard_selected" android:state_checked="true" />
<item android:drawable="@drawable/creditcard"/>
</selector>
layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox android:id="@+id/cbFalse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@drawable/custom_cb"
android:text="" />
<CheckBox android:id="@+id/cbTrue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@drawable/custom_cb"
android:focusable="false"
android:checked="true"
android:layout_toRightOf="@id/cbFalse" />
<ImageView android:id="@+id/imvTrue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/creditcard"
android:layout_toRightOf="@id/cbTrue" />
</RelativeLayout>
В любом случае я могу использовать большее изображение для CheckBox, сохраняя размер wrap_content
? Если я устанавливаю CheckBox layout_width
на фактический пиксель или dp, тогда он отображает полное изображение, но это означает, что я должен вручную проверять размер каждый раз, когда он изменяется.
Сегодня у меня была такая же проблема (мой пользовательский образ был отрезан с левой стороны). Я исправил его:
android:button="@null"
android:background="@drawable/my_custom_checkbox_state.xml"
Просто используйте
android:button="@null"
android:background="@null"
android:drawableLeft="your custom selector"
android:drawablePadding="as you need"
android:text="your text"
Вот оно.. Его работа хорошая..
Вам нужно только изменить выноски с android:button
на android:drawableLeft
или android:drawableRight
. И установите для кнопки значение null, чтобы не показывать по умолчанию флажок.
Мой флажок выглядит следующим образом:
<CheckBox
android:id="@+id/cb_toggle_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:button="@null"
android:drawableLeft="@drawable/livescore_btn_check" />
DrawBox drawables не работал у меня вообще, android:button
и android:background
дал совершенно неустойчивые результаты, и ничто не могло исправить его.
Итак, я написал свой собственный "пользовательский флажок".
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import org.apache.commons.lang3.StringUtils;
import butterknife.Bind;
import butterknife.ButterKnife;
import com.example.myapp.R;
/**
* Created by Zhuinden on 2015.12.02..
*/
public class CustomCheckbox
extends LinearLayout
implements View.OnClickListener {
public CustomCheckbox(Context context) {
super(context);
init(null, -1);
}
public CustomCheckbox(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, -1);
}
@TargetApi(11)
public CustomCheckbox(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs, defStyleAttr);
}
@TargetApi(21)
public CustomCheckbox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs, defStyleAttr);
}
private void init(AttributeSet attributeSet, int defStyle) {
TypedArray a = null;
if(defStyle != -1) {
a = getContext().obtainStyledAttributes(attributeSet, R.styleable.CustomCheckbox, defStyle, 0);
} else {
a = getContext().obtainStyledAttributes(attributeSet, R.styleable.CustomCheckbox);
}
defImageRes = a.getResourceId(0, 0);
checkedImageRes = a.getResourceId(1, 0);
checked = a.getBoolean(2, false);
typeface = a.getString(3);
if(StringUtils.isEmpty(typeface)) {
typeface = "Oswald-Book.otf";
}
text = a.getString(4);
inactiveTextcolor = a.getInteger(5, android.R.color.black);
activeTextcolor = a.getInteger(6, android.R.color.red);
textsize = a.getDimensionPixelSize(7, 0);
a.recycle();
setOnClickListener(this);
if(!isInEditMode()) {
LayoutInflater.from(getContext()).inflate(R.layout.view_custom_checkbox, this, true);
ButterKnife.bind(this);
imageView.setImageResource(checked ? checkedImageRes : defImageRes);
typefaceTextView.setTypeface(typeface);
if(!StringUtils.isEmpty(text)) {
typefaceTextView.setText(text);
}
if(textsize != 0) {
typefaceTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textsize);
} else {
typefaceTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
}
}
}
boolean checked;
int defImageRes;
int checkedImageRes;
String typeface;
String text;
int inactiveTextcolor;
int activeTextcolor;
int textsize;
OnCheckedChangeListener onCheckedChangeListener;
@Bind(R.id.custom_checkbox_imageview)
ImageView imageView;
@Bind(R.id.custom_checkbox_text)
TypefaceTextView typefaceTextView;
@Override
protected void onFinishInflate() {
super.onFinishInflate();
}
@Override
public void onClick(View v) {
checked = !checked;
imageView.setImageResource(checked ? checkedImageRes : defImageRes);
typefaceTextView.setTextColor(checked ? activeTextcolor : inactiveTextcolor);
onCheckedChangeListener.onCheckedChanged(this, checked);
}
public void setOnCheckedChangeListener(OnCheckedChangeListener onCheckedChangeListener) {
this.onCheckedChangeListener = onCheckedChangeListener;
}
public static interface OnCheckedChangeListener {
void onCheckedChanged(View buttonView, boolean isChecked);
}
public boolean isChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
imageView.setImageResource(checked ? checkedImageRes : defImageRes);
typefaceTextView.setTextColor(checked ? activeTextcolor : inactiveTextcolor);
}
public void setTextColor(int color) {
typefaceTextView.setTextColor(color);
}
@Override
public Parcelable onSaveInstanceState() {
//begin boilerplate code that allows parent classes to save state
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
//end
ss.checked = this.checked;
ss.defImageRes = this.defImageRes;
ss.checkedImageRes = this.checkedImageRes;
ss.typeface = this.typeface;
ss.text = this.text;
ss.inactiveTextcolor = this.inactiveTextcolor;
ss.activeTextcolor = this.activeTextcolor;
ss.textsize = this.textsize;
return ss;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
//begin boilerplate code so parent classes can restore state
if(!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
//end
this.checked = ss.checked;
this.defImageRes = ss.defImageRes;
this.checkedImageRes = ss.checkedImageRes;
this.typeface = ss.typeface;
this.text = ss.text;
this.inactiveTextcolor = ss.inactiveTextcolor;
this.activeTextcolor = ss.activeTextcolor;
this.textsize = ss.textsize;
}
static class SavedState
extends BaseSavedState {
boolean checked;
int defImageRes;
int checkedImageRes;
String typeface;
String text;
int inactiveTextcolor;
int activeTextcolor;
int textsize;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
this.checked = in.readByte() > 0;
this.defImageRes = in.readInt();
this.checkedImageRes = in.readInt();
this.typeface = in.readString();
this.text = in.readString();
this.inactiveTextcolor = in.readInt();
this.activeTextcolor = in.readInt();
this.textsize = in.readInt();
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeByte(this.checked ? (byte) 0x01 : (byte) 0x00);
out.writeInt(this.defImageRes);
out.writeInt(this.checkedImageRes);
out.writeString(this.typeface);
out.writeString(this.text);
out.writeInt(this.inactiveTextcolor);
out.writeInt(this.activeTextcolor);
out.writeInt(this.textsize);
}
//required field that makes Parcelables from a Parcel
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
Используя следующий attrs.xml
<resources
<declare-styleable name="CustomCheckbox">
<attr name="default_img" format="integer"/>
<attr name="checked_img" format="integer"/>
<attr name="checked" format="boolean"/>
<attr name="chx_typeface" format="string"/>
<attr name="text" format="string"/>
<attr name="inactive_textcolor" format="integer"/>
<attr name="active_textcolor" format="integer"/>
<attr name="textsize" format="dimension"/>
</declare-styleable>
</resources>
В следующем макете view_custom_checkbox.xml
:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/custom_checkbox_imageview"
android:layout_width="@dimen/_15sdp"
android:layout_height="@dimen/_15sdp"
/>
<com.example.TypefaceTextView
android:id="@+id/custom_checkbox_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</merge>
И пример:
<com.example.CustomCheckbox
android:id="@+id/program_info_record_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:clickable="true"
android:gravity="center"
app:default_img="@drawable/ic_recording_off"
app:checked_img="@drawable/ic_recording_on"
app:text="@string/record"
app:inactive_textcolor="@color/program_info_buttons_inactive"
app:active_textcolor="@color/active_color"
app:textsize="@dimen/programInfoButtonTextSize"
app:chx_typeface="SomeTypeface.otf"/>
Измените, если необходимо.
Попробуйте использовать Linearlayout с горизонтальной ориентацией вместо RelativeLayout. Также используйте вес в каждом макете, чтобы заставить представления использовать ту же ширину.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox android:id="@+id/cbFalse"
android:weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:button="@drawable/custom_cb"
android:text="" />
<CheckBox android:id="@+id/cbTrue"
android:weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:button="@drawable/custom_cb"
android:focusable="false"
android:checked="true"
android:layout_toRightOf="@id/cbFalse" />
<ImageView android:id="@+id/imvTrue"
android:weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/creditcard"
android:layout_toRightOf="@id/cbTrue" />