Android自定义九宫格输入框

2022-10-07,,,

本文实例为大家分享了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自定义九宫格输入框.doc》

下载本文的Word格式文档,以方便收藏与打印。