Android自定义九宫格输入框

 更新时间:2022年06月28日 10:02:35   作者:Android师哥  
这篇文章主要为大家详细介绍了Android自定义九宫格输入框,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。

相关文章

  • Kotlin的空安全处理方式详解

    Kotlin的空安全处理方式详解

    这篇文章主要为大家介绍了Kotlin的空安全处理方式及空安全的思维方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • Android实现可拖动层叠卡片布局

    Android实现可拖动层叠卡片布局

    这篇文章主要为大家详细介绍了Android实现可拖动层叠卡片布局,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • Android Bluetooth蓝牙技术使用流程详解

    Android Bluetooth蓝牙技术使用流程详解

    这篇文章主要介绍了Android Bluetooth蓝牙技术使用流程详解的相关资料,需要的朋友可以参考下
    2016-02-02
  • Android连接MySQL数据库实现方法详解

    Android连接MySQL数据库实现方法详解

    这篇文章主要介绍了Android连接MySQL数据库实现方法,在Android应用程序中连接MySQL数据库可以帮助开发人员实现更丰富的数据管理功能,而且在Android中操作数据库真的太智能了,需要的朋友可以参考下
    2024-02-02
  • Android使用HorizontalScrollView实现水平滚动

    Android使用HorizontalScrollView实现水平滚动

    这篇文章主要为大家详细介绍了Android使用HorizontalScrollView实现水平滚动,并点击有相应的反应效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • 安卓逆向腾讯动漫app返回数据加密分析案例分享

    安卓逆向腾讯动漫app返回数据加密分析案例分享

    这篇文章主要为大家介绍了安卓逆向腾讯动漫app返回数据加密分析的案例分享,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • Android开发全局音量调整的实现方式详解

    Android开发全局音量调整的实现方式详解

    这篇文章主要为大家介绍了Android开发全局音量调整的实现方式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • android studio的Handler简单实例代码

    android studio的Handler简单实例代码

    今天通过实例代码给大家介绍android studio的Handler简单用法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-10-10
  • Android自定义Dialog内部透明、外部遮罩效果

    Android自定义Dialog内部透明、外部遮罩效果

    这篇文章主要为大家详细介绍了Android自定义Dialog内部透明、外部遮罩效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-10-10
  • Kotlin扩展函数超详细介绍

    Kotlin扩展函数超详细介绍

    Kotlin?可以为一个不能修改的或来自第三方库中的类编写一个新的函数。?这个新增的函数就像那个原始类本来就有的函数一样,可以用普通的方法调用,这种机制的函数称为扩展函数
    2022-09-09

最新评论

?


http://www.vxiaotou.com