大家好,我是小黑,一个还没秃头的程序员~~~
独学而无友,则孤陋而寡闻--《礼记·学记》
今天的内容是自定义一个数组加减的控件,可以应用于购物车的数量选择,效果如下:

自定义实现了控件的默认值、最大值、最小值、步长的值的设置
(一)设置控件布局view_number.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical"> <ImageView android:id="@+id/iv_add" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@mipmap/icon_add_enable" /> <EditText android:id="@+id/edit_value" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:background="@drawable/frame_with_gray_edge_white" android:paddingLeft="15dp" android:paddingTop="10dp" android:paddingRight="15dp" android:paddingBottom="10dp" android:text="1" android:textColor="#000" android:textSize="14dp" /> <ImageView android:id="@+id/iv_minus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:background="@drawable/select_minus_switch" />LinearLayout>按钮样式只实现了可不可点击状态的切换,大家也可自己实现单击状态的效果select_minus_switch.xml代码如下:<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@mipmap/icon_minus_disable" android:state_enabled="false" /> <item android:drawable="@mipmap/icon_minus_enable" android:state_enabled="true" />selector>frame_with_gray_edge_white.xml代码如下:
<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <corners android:radius="5dp" /> <solid android:color="#fff" /> <stroke android:width="0.5dp" android:color="#c0c0c0" />shape>(二)创建类并继承基本布局,加载视图,自定义属性设计获取以及使用自定义属性文件attrs_number_view.xml代码如下:<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="NumberView"> <attr name="min" format="integer" /> <attr name="max" format="integer" /> <attr name="step" format="integer" /> <attr name="defaultValue" format="integer" /> declare-styleable>resources>NumberView.java代码如下:
public class NumberView extends LinearLayout { private ImageView mIvAdd; private ImageView mIvMinus; private EditText mEditValue; private int mCurrentValue;//当前的数值 private OnValueChangeListener mOnValueChangeListener;//值发生变化时的回调 private int mMax;//最大值 private int mMin;//最小值 private int mStep;//步长 private int mDefaultValue;//默认值 public int getMax() { return mMax; } public void setMax(int max) { mMax = max; } public int getMin() { return mMin; } public void setMin(int min) { mMin = min; } public int getStep() { return mStep; } public void setStep(int step) { mStep = step; } public int getDefaultValue() { return mDefaultValue; } public void setDefaultValue(int defaultValue) { mCurrentValue = mDefaultValue = defaultValue; updateText(); } public int getCurrentValue() { return mCurrentValue; } //手动设置值需要更新UI public void setCurrentValue(int currentValue) { mCurrentValue = currentValue; updateText(); } public NumberView(Context context) { this(context, null, 0); } public NumberView(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } public NumberView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(context); getAttrs(context, attrs); } //获取自定义属性 private void getAttrs(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.NumberView); mMax = typedArray.getInt(R.styleable.NumberView_max, 999999); mMin = typedArray.getInt(R.styleable.NumberView_min, 0); mStep = typedArray.getInt(R.styleable.NumberView_step, 1); mDefaultValue = typedArray.getInt(R.styleable.NumberView_defaultValue, 1); mCurrentValue = mDefaultValue;//当前值等于默认值 if (mCurrentValue == mMin) {//当前值为最小值时减号不能点击 mIvMinus.setEnabled(false); } else { mIvMinus.setEnabled(true); } } //加载布局,定义控件以及设置监听 private void initView(Context context) { View inflate = LayoutInflater.from(context).inflate(R.layout.view_number, this, false); this.addView(inflate); mIvAdd = inflate.findViewById(R.id.iv_add); mIvMinus = inflate.findViewById(R.id.iv_minus); mEditValue = inflate.findViewById(R.id.edit_value); mIvAdd.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //先加完再比较,只要一点加号,减号就可以点击了 mCurrentValue += mStep; mIvMinus.setEnabled(true); //为了防止超过最大值,最后一步将最大值设置成当前值 if (mCurrentValue >= mMax) { mCurrentValue = mMax; mIvAdd.setEnabled(false); } //更新UI updateText(); //回调当前值 if (mOnValueChangeListener != null) { mOnValueChangeListener.onValueChange(mCurrentValue); } } }); mIvMinus.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //减号与加号同理 mCurrentValue -= mStep; mIvAdd.setEnabled(true); if (mCurrentValue <= mMin) { mCurrentValue = mMin; mIvMinus.setEnabled(false); } updateText(); if (mOnValueChangeListener != null) { mOnValueChangeListener.onValueChange(mCurrentValue); } } }); } private void updateText() { mEditValue.setText(mCurrentValue + ""); } public interface OnValueChangeListener { void onValueChange(int value); } public void setOnValueChangeListener(OnValueChangeListener onValueChangeListener) { mOnValueChangeListener = onValueChangeListener; }在Activity中的控件使用:
NumberView numberView = findViewById(R.id.view_number); numberView.setOnValueChangeListener(new NumberView.OnValueChangeListener() { @Override public void onValueChange(int value) { Toast.makeText(NumberViewActivity.this, "The current value is :"+value, Toast.LENGTH_SHORT).show(); } });到此为止,一个关于数字加减选择的自定义控件就已经完成了,是不是很简单,注释也写得很清楚,大家也可以自己添加各种自定义属性,如数值的精度以及按钮的样式等等,最后,祝大家身体健康,万事如意,感谢大家的支持与阅读!