自定义控件——SmartEditText,一个灵活好玩的EditText

转载请注明出处,谢谢~~
控件还有很大的优化和提升控件,欢迎star和pr~!
之前做的一个控件,一直没有写一篇相关的博客,今天打算提笔,写下来。不多说,一贯风格,有图有真相。
重点内容

控件之始,当然是一些初始化的操作

private void init(){
        setWillNotDraw(false);
        paint = new Paint();
        paint.setFlags(Paint.ANTI_ALIAS_FLAG);//消除锯齿
        tPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        tPaint.setTextSize(dp2px(hintTextSize));
        super.setPadding((int)dp2px(paddingLeft), (int)dp2px(paddingTop),
                (int)dp2px(paddingRight), (int)dp2px(paddingBottom) );
        mainTextSize = getTextSize();
    }

这里主要是对画笔和一些padding的设定

然后在onMeasure里记录了宽高

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getWidth();
        height = getHeight();
    }

之后主要的操作就是在OnDraw()里,我们看下代码:

@Override
    protected void onDraw(Canvas canvas) {
        if (!hasFocus()) {
            drawDefaultLineAndText(canvas);
        }else {
            animateLableOut(canvas);
        }
        if(ratioOut >=0 && ratioOut <=1  || ratioIn >=0 && ratioIn <= 1) {
            invalidate();
        }
        super.onDraw(canvas);
    }

这里首先用hasFocus()方法来判断焦点,根据不同的焦点执行不同的绘制逻辑,然后用ratioOut和ratioIn这两个参数控制重绘时机。我们首先看下当没有获取焦点时的绘制逻辑:

private void drawDefaultLineAndText(Canvas canvas) {
        ratioOut = 0;
        paint.setColor(defaultLineColor);
//      tPaint.setColor(defaultTextColor);
        canvas.drawRect(dp2px(lineLeft), height-dp2px(lineHeight), width-dp2px(lineLeft), height, paint);
        ratioIn -= INCREMENT;
        if (ratioIn <= 0) {
            ratioIn = 0;
            ratioOut = ratioIn;
        }
        paint.setColor(endLineColor);
        if (ratioIn == 0) {
            canvas.drawRect(dp2px(lineLeft), height-dp2px(lineHeight), dp2px(lineLeft), height, paint);//解决一些手机上会绘制0-left的横线
        }else {
            canvas.drawRect(dp2px(lineLeft), height-dp2px(lineHeight), ratioIn*((float)(width-dp2px(lineLeft))), height, paint);
        }
        if (TextUtils.isEmpty(this.getText().toString().trim())) {
            if (isLableOut) {
                if (ratioIn == 0) {
                    tPaint.setColor(defaultTextColor);
                    canvas.drawText(hintText, dp2px(paddingLeft), (float)(height-dp2px(textMarginTop)), tPaint);
                }else {
                    tPaint.setColor(endTextColor);
                    canvas.drawText(hintText, dp2px(paddingLeft), (float)(height-dp2px(textMarginTop))-(ratioIn*(mainTextSize + dp2px(10f))), tPaint);
                }
            }else{
                if (ratioIn == 0) {
                    tPaint.setColor(defaultTextColor);
                    canvas.drawText(hintText, dp2px(paddingLeft), (float)(height-dp2px(textMarginTop)), tPaint);
                }
            }
        }else{
            if (ratioIn == 0) {
                tPaint.setColor(defaultTextColor);
            }else {
                tPaint.setColor(endTextColor);
            }
            canvas.drawText(hintText, dp2px(paddingLeft), (height-(cursorSize + dp2px(textMarginTop))), tPaint);
        }
    }

大致讲下这里,具体的思路可以看下代码,全部代码会在文章最后给出。
首先,ratioOut和ratioIn是控制绘制的机制,这两个是一直在变的。首先在没有获取焦点的时候,会绘制一条默认的线和提示文字,提示文字在线的左边,但是如果EditText里面有用户输入的文字的话,提示文字就不会在线上绘制,就会在EditText的上方绘制。

然后贴下当获取焦点时绘制的代码:

 private void animateLableOut(Canvas canvas) {
        ratioOut += INCREMENT;
        paint.setColor(defaultLineColor);
        canvas.drawRect(dp2px(lineLeft), height-dp2px(lineHeight), width-dp2px(lineLeft), height, paint);
        paint.setColor(endLineColor);
        tPaint.setColor(endTextColor);
        if (ratioOut >= 1) {
            ratioOut = 1;
            ratioIn = ratioOut;
        }
        canvas.drawRect(dp2px(lineLeft), height-dp2px(lineHeight), ratioOut*((float)(width-dp2px(lineLeft))), height, paint);
        if (TextUtils.isEmpty(this.getText().toString().trim())) {
//          canvas.drawText(hintText, dp2px(paddingLeft), (float)(height-dp2px(textMarginTop))-(ratioOut*(mainTextSize + dp2px(10f))), tPaint);
            canvas.drawText(hintText, dp2px(paddingLeft), (float)(height-dp2px(textMarginTop))-(ratioOut*(cursorSize)), tPaint);
        }else {
//          canvas.drawText(hintText, dp2px(paddingLeft), (height-(mainTextSize + dp2px(22.5f))), tPaint);
            canvas.drawText(hintText, dp2px(paddingLeft), (height-(cursorSize + dp2px(textMarginTop))), tPaint);
//          ratio = 1.1f;//阻止重绘
        }

        isLableOut = true;
    }

当获取焦点时,会对线和提示文字做一个重绘操作,当然,也要判断当前EditText是否有文字输入。

总体的逻辑大致如此,具体的细节看代码即可。希望这篇文章能对大家有些帮助。

控件还有很大的优化和提升控件,欢迎star和pr~!

代码地址:eclipse版本github代码下载地址
Android studio 版本github代码下载地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值