大家好,我是小黑,一个还没秃头的程序员~~~
独学而无友,则孤陋而寡闻--《礼记·学记》
今天的内容是自定义一个数组加减的控件,可以应用于购物车的数量选择,效果如下:
自定义实现了控件的默认值、最大值、最小值、步长的值的设置
(一)设置控件布局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();
}
});
到此为止,一个关于数字加减选择的自定义控件就已经完成了,是不是很简单,注释也写得很清楚,大家也可以自己添加各种自定义属性,如数值的精度以及按钮的样式等等,最后,祝大家身体健康,万事如意,感谢大家的支持与阅读!