Android自定义九宫格输入框
(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun)
本文实例为大家分享了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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。
相关文章
Android使用HorizontalScrollView实现水平滚动
这篇文章主要为大家详细介绍了Android使用HorizontalScrollView实现水平滚动,并点击有相应的反应效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2018-11-11
最新评论