【问题标题】:Custom CheckBox image gets cut off自定义复选框图像被切断
【发布时间】:2013-04-11 11:52:50
【问题描述】:

如上图所示。此屏幕截图包含三个视图。
- 第一项是CheckBox,带有文本且状态为关闭。
- 第二个项目是CheckBox,没有文字并且有状态。
- 最后一项是ImageView,src 指向可绘制图像。

复选框是使用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>

无论如何我可以在保持wrap_content 大小的同时为 CheckBox 使用更大的图像吗?如果我将 CheckBox layout_width 设置为实际像素或 dp,那么它会显示完整图像,但这意味着我必须在每次更改时手动检查大小。

【问题讨论】:

  • 不确定这是否是您问题的解决方案,但我认为应该是 android:button="@null" 并改用背景属性:android:background="@drawable/custom_cb"

标签: android checkbox


【解决方案1】:

今天我遇到了同样的问题(我的自定义图像在左侧被剪切了)。 我把它修好了:

android:button="@null"
android:background="@drawable/my_custom_checkbox_state.xml"

【讨论】:

  • 这对我有用,尽管当布局宽度和高度设置为 wrap_content 时,CheckBox 不尊重 android:button 可绘制的大小确实感觉像是一个错误。 >
  • 这个解决方案可能在不同设备上的工作方式不同
  • 谢谢,很多。我已经尝试了很多具有自定义按钮可绘制、可缩放按钮等的解决方案,但是您的解决方案对我有用!越野车机器人(
【解决方案2】:

随便用

android:button="@null"
android:background="@null"
android:drawableLeft="your custom selector"
android:drawablePadding="as you need"
android:text="your text"

就是这样..它工作正常..

【讨论】:

    【解决方案3】:

    您只需将您的可绘制对象从android:button 更改为android:drawableLeftandroid: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" />
    

    【讨论】:

      【解决方案4】:

      CheckBox drawables 根本不适合我,android:buttonandroid: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"/>
      

      在必要时进行修改。

      【讨论】:

        【解决方案5】:

        尝试使用水平方向的线性布局而不是相对布局。还可以在每个布局中使用权重来强制视图使用相同的宽度。

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

        【讨论】:

          【解决方案6】:

          也许它对某人有用,将gravity 属性设置为center 帮助我避免了图像裁剪:

          <CheckBox
              android:id="@+id/cb_accept_agreement"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:gravity="center"
              android:button="@drawable/checkbox_selector"/>
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-04-27
            • 1970-01-01
            • 2011-06-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多