Android自定义九宫格输入框

本文实例为大家分享了Android自定义九宫格输入框的具体代码,供大家参考,具体内容如下

效果

实现

绘制宫格分割线

这里我们用一个RectF类型的数组来装载数据。在onSizeChanged方法中获取到控件尺寸,经过计算,将81个位置合适的矩形保存到数组中。

绘制点击效果

onTouchEvent方法中监听手指离开事件,当手指离开,获取到当前点击区域的RectF,并将状态同样保存到一个数组中。

绘制输入内容

输入内容利用onTextChanged方法获取,同样保存到一个数组中。

PS

控件中没有考虑UI重建数据保存问题,使用中要注意这点~~~

这三个数组中数据一一对应,在onDraw中,根据三个数组中数据内容绘制界面。完成我们的自定义View。

源码 /**  * 自定义九宫格输入框  * attrs: customTableLineColor  宫格分割线颜色  * attrs: customTableLineWidth  宫格分割线宽度  * attrs: customTablePressColor 宫格选中时背景颜色  * attrs: customTableSpace      大宫格间隔  * attrs: customTableTextColor  宫格输入文字颜色  * attrs: customTableTextSize   宫格输入文字大小  * attrs: customTableAngle      宫格圆角尺寸  * 默认值请查看 {@link CustomEditText#initAttrs(Context, AttributeSet)}  */ public class CustomEditText extends AppCompatEditText {     private static final String TAG = "CustomEditText";     //宫格位置     private final RectF[] mTableList = new RectF[81];     //宫格状态     private final Boolean[] mTableState = new Boolean[81];     //宫格数据     private final Integer[] mTableListNumber = new Integer[81];     //绘制宫格画笔     private Paint mPaint;     //绘制宫格背景画笔     private Paint mBackgroundPaint;     //绘制文字画笔     private TextPaint mTextPaint;     //手指离开屏幕X轴坐标     private float mTouchX;     //手指离开屏幕Y轴坐标     private float mTouchY;     //表格内文字尺寸     private float mTextSize;     //表格内文字颜色     private int mTextColor;     //表格分割线颜色     private int mTableLineColor;     //选中对应宫格背景颜色     private int mTablePressColor;     //表格分割线宽度     private float mTableLineWidht;     //大宫格间隔     private float mTableSpace;     //宫格圆角尺寸     private float mTableAngle;     public CustomEditText(Context context) {         this(context, null);     }     public CustomEditText(Context context, AttributeSet attrs) {         this(context, attrs, R.attr.editTextStyle);     }     public CustomEditText(Context context, AttributeSet attrs, int defStyleAttr) {         super(context, attrs, defStyleAttr);         initAttrs(context, attrs);         initSet();         initPaint();     }     /**      * 初始化自定义属性      */     private void initAttrs(Context context, AttributeSet attrs) {         TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomEditText);         mTextColor = typedArray.getColor(R.styleable.CustomEditText_customTableTextColor, Color.parseColor("#000000"));         mTableLineColor = typedArray.getColor(R.styleable.CustomEditText_customTableLineColor, Color.parseColor("#000000"));         mTablePressColor = typedArray.getColor(R.styleable.CustomEditText_customTablePressColor, Color.parseColor("#DDDDDD"));         mTextSize = typedArray.getDimension(R.styleable.CustomEditText_customTableTextSize, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));         mTableLineWidht = typedArray.getDimension(R.styleable.CustomEditText_customTableLineWidth, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, getResources().getDisplayMetrics()));         mTableSpace = typedArray.getDimension(R.styleable.CustomEditText_customTableSpace, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()));         mTableSpace = typedArray.getDimension(R.styleable.CustomEditText_customTableSpace, TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()));         mTableAngle = typedArray.getDimension(R.styleable.CustomEditText_customTableAngle, 0);         typedArray.recycle();     }     /**      * 初始化画笔      */     private void initPaint() {         mBackgroundPaint = new Paint();         mBackgroundPaint.setAntiAlias(true);         mBackgroundPaint.setStyle(Paint.Style.FILL);         mBackgroundPaint.setColor(mTablePressColor);         mPaint = new Paint();         mPaint.setAntiAlias(true);         mPaint.setColor(mTableLineColor);         mPaint.setStrokeWidth(mTableLineWidht);         mPaint.setStyle(Paint.Style.STROKE);         mTextPaint = new TextPaint();         mTextPaint.setColor(mTextColor);         mTextPaint.setTextSize(mTextSize);         mTextPaint.setAntiAlias(true);         mTextPaint.setTextAlign(Paint.Align.CENTER);     }     /**      * 初始化EditText基础设置      */     private void initSet() {         //隐藏光标         setCursorVisible(false);         //设置输入类型         setInputType(InputType.TYPE_CLASS_NUMBER);         //限制输入一行         setSingleLine(true);     }     @Override     protected void onDraw(Canvas canvas) {         for (int i = 0; i < mTableList.length; i++) {             RectF rectF = mTableList[i];             if (mTableState[i]) {                 //绘宫格制背景                 canvas.drawRoundRect(rectF, mTableAngle, mTableAngle, mBackgroundPaint);             }             //绘制宫格分割线             canvas.drawRoundRect(rectF, mTableAngle, mTableAngle, mPaint);             Integer integer = mTableListNumber[i];             if (integer != 0) {                 //测量文字尺寸                 Rect measureTextSize = measureTextSize(integer + "");                 //绘制输入内容                 canvas.drawText(integer + "", rectF.centerX(), rectF.centerY() + measureTextSize.height() / 2.0F, mTextPaint);             }         }     }     @Override     public boolean onTouchEvent(MotionEvent event) {         if (event.getAction() == MotionEvent.ACTION_UP) {//手指离开             mTouchX = event.getX();             mTouchY = event.getY();             //检查输入内容和状态是否对应             for (int i = 0; i < mTableListNumber.length; i++) {                 Integer integer = mTableListNumber[i];                 if (integer == 0) {                     //背景应该为透明                     if (mTableState[i]) {                         mTableState[i] = false;                     }                 }             }             //设置选中宫格             for (int i = 0; i < mTableList.length; i++) {                 if (mTableList[i].contains(mTouchX, mTouchY)) {                     mTableState[i] = true;                     invalidate();                     break;                 }             }         }         if (event.getAction() == MotionEvent.ACTION_DOWN) {             performClick();         }         return super.onTouchEvent(event);     }     @Override     public boolean performClick() {         return super.performClick();     }     @Override     protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {         super.onTextChanged(text, start, lengthBefore, lengthAfter);         String trim = text.toString().trim();         if (!TextUtils.isEmpty(trim) && TextUtils.isDigitsOnly(trim)) {             //保存输入内容             if (trim.length() > 1) {                 trim = trim.substring(trim.length() - 1, trim.length());             }             for (int i = 0; i < mTableList.length; i++) {                 if (mTableList[i].contains(mTouchX, mTouchY)) {                     mTableListNumber[i] = Integer.parseInt(trim);                     //修改宫格背景状态                     mTableState[i] = true;                     //清空默认EditText输入内容                     CustomEditText.this.setText("");                     break;                 }             }         }     }     @Override     protected void onSizeChanged(int w, int h, int oldw, int oldh) {         super.onSizeChanged(w, h, oldw, oldh);         //初始化宫格位置数据         int paddingLeft = getPaddingLeft();         int paddingRight = getPaddingRight();         int paddingTop = getPaddingTop();         int measuredWidth = getMeasuredWidth();         //表格实际显示的宽度         int tableWidht = (int) (measuredWidth - mTableSpace * 2 - paddingLeft - paddingRight);         //每个表格的宽度         float singleTableWidth = tableWidht / 3.0F;         for (int i = 0; i < 9; i++) {             float top;             float left;             float bottom;             float right;             left = paddingLeft + (singleTableWidth * (i % 3)) + (mTableSpace * (i % 3));             right = left + singleTableWidth;             top = paddingTop + (singleTableWidth * (i / 3)) + (mTableSpace * (i / 3));             bottom = top + singleTableWidth;             //最大九个宫格的矩形             RectF rectF = new RectF(left, top, right, bottom);             float width = rectF.width();             float singleTableWidthMin = width / 3.0F;             for (int j = 0; j < 9; j++) {                 float topMin;                 float leftMin;                 float bottomMin;                 float rightMin;                 leftMin = singleTableWidthMin * (j % 3) + rectF.left;                 rightMin = leftMin + singleTableWidthMin;                 topMin = singleTableWidthMin * (j / 3) + rectF.top;                 bottomMin = topMin + singleTableWidthMin;                 //每个小宫格的矩形                 RectF rectFMin = new RectF(leftMin, topMin, rightMin, bottomMin);                 for (int k = 0; k < mTableList.length; k++) {                     if (mTableList[k] == null) {                         mTableList[k] = rectFMin;                         mTableListNumber[k] = 0;                         mTableState[k] = false;                         break;                     }                 }             }         }     }     @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         //强制控件为正方形         super.onMeasure(widthMeasureSpec, widthMeasureSpec);     }     /**      * 测量文字的尺寸      *      * @return 一个汉字的矩阵      */     private Rect measureTextSize(String content) {         Rect mRect = null;         if (!TextUtils.isEmpty(content)) {             if (mTextPaint != null) {                 mRect = new Rect();                 mTextPaint.getTextBounds(content, 0, content.length(), mRect);             }         }         return mRect;     } }

自定义属性

<resources>     <declare-styleable name="CustomEditText">         <attr name="customTableTextSize" format="dimension" />         <attr name="customTableTextColor" format="color" />         <attr name="customTableLineColor" format="color" />         <attr name="customTableLineWidth" format="dimension" />         <attr name="customTableSpace" format="dimension" />         <attr name="customTablePressColor" format="color"/>         <attr name="customTableAngle" format="integer"/>     </declare-styleable> </resources>

推荐阅读