您的位置:首页 > 其它

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

2015-10-09 16:31 375 查看
转载请注明出处,谢谢~~

控件还有很大的优化和提升控件,欢迎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代码下载地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: