今天项目有个需求,就是在编辑栏的左边添加一张图片,但是我不是很想使用布局嵌套的方式来进行,所有我就干脆自定义了一个控件来进行显示。

效果图:

代码如下:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.EditText;

/**
 * 创建时间:2016.8.1
 * 创建人:王亮
 * 功能作用:带有自定义下划线的编辑框(已经添加过图片)
 * 逻辑:使setGravity()方法不向父类返回,让文字位置设置失效;使setBackground()方法向父类返回为空,使原本下滑线消失;
 * 使用onTextChanged()方法监听文字改变并记录文字;使用setCompoundDrawables()方法来计算向编辑框中添加图片的宽高;
 * 最后重写ondraw()方法进行重绘下滑线,并记录初始设置的文字颜色,记录之后将初始文字颜色设置为透明色,然后在计算新的文字
 * 所要显示的位置的坐标,最后再将记录的文字重绘
 */
public class UnderlineEdittextView extends EditText {
    private Integer leftMinimumWidth;
    private Integer topMinimumHeight;
    private Integer rightMinimumWidth;
    private Integer bottomMinimumHeight;
    private Paint linePaint;//下划线画笔


    public UnderlineEdittextView(Context context) {
        super(context);
        init();
    }

    public UnderlineEdittextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public UnderlineEdittextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


    /** 要显示的文字 */
    private String showText;
    /** 文字的颜色 */
    private Integer showTextColor;
    /** 文字的大小 */
    private int showTextSize;
    /** 文字的方位 */
    private int showTextAlign;
    /** 左上角显示  */
    public static final int TEXT_ALIGN_LEFT_TOP                 = 0x00000001;
    /** 左侧中间显示  */
    public static final int TEXT_ALIGN_LEFT_CENTER              = 0x00000010;
    /** 左侧下方显示  */
    public static final int TEXT_ALIGN_LEFT_BOTTOM              = 0x00000100;
    /** 右上角显示  */
    public static final int TEXT_ALIGN_RIGHT_TOP                = 0x00001000;
    /** 右侧中间显示 */
    public static final int TEXT_ALIGN_RIGHT_CENTER             = 0x00010000;
    /** 右侧下方显示  */
    public static final int TEXT_ALIGN_RIGHT_BOTTOM             = 0x00100000;
    /** 中间顶部显示  */
    public static final int TEXT_ALIGN_CENTER_HORIZONTAL_TOP    = 0x00001000|0x00010000;
    /** 中间下方显示  */
    public static final int TEXT_ALIGN_CENTER_HORIZONTAL_BOTTOM = 0x10000010;
    /** 居中显示  */
    public static final int TEXT_ALIGN_CENTER                   = 0x10000100;
    /** 居中靠上显示  */
    public static final int TEXT_ALIGN_CENTER_TOP               = 0x10001000;
    /** 居中靠下显示  */
    public static final int TEXT_ALIGN_CENTER_BOTTOM            = 0x10010000;
    /** 居中靠左显示  */
    public static final int TEXT_ALIGN_CENTER_LEFT              = 0x10100000;
    /** 居中靠右显示  */
    public static final int TEXT_ALIGN_CENTER_RIGHT             = 0x11000000;
    /** 居中靠左上显示  */
    public static final int TEXT_ALIGN_CENTER_LEFT_TOP          = 0x11000001;
    /** 居中靠左下显示  */
    public static final int TEXT_ALIGN_CENTER_LEFT_BOTTOM       = 0x11000010;
    /** 居中靠右上显示  */
    public static final int TEXT_ALIGN_CENTER_RIGHT_TOP         = 0x11000100;
    /** 居中靠右下显示  */
    public static final int TEXT_ALIGN_CENTER_RIGHT_BOTTOM      = 0x11001000;
/**   */
    /** 文本中轴线X坐标 */
    private Float showTextCenterX = 0f;
    /** 文本baseline线Y坐标 */
    private Float showTextBaselineY = 0f;
    /** 控件的宽度 */
    private int viewWidth;
    /** 控件的高度 */
    private int viewHeight;
    private Paint.FontMetrics fm;
    /** 场景 */
    private Paint showTextPaint;

    private void init(){
        showTextPaint = new Paint();
        showTextPaint.setTextSize(getTextSize());

        linePaint = new Paint();
        linePaint.setColor(Color.BLACK);
        linePaint.setStrokeWidth(5);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(showTextColor == null) {
            showTextColor = getTextColors().getDefaultColor();//记录初始文字颜色值
            setTextColor(Color.parseColor("#00000000"));//使初始文字变透明
            setCursorVisible(false);//取消光标显示
        }else {
            showTextPaint.setColor(showTextColor);
            setTextLocation(showTextPaint);//计算文字显示位置
        }

        if(leftMinimumWidth != null) {
            canvas.drawLine(leftMinimumWidth, getHeight(), getWidth(), getHeight(), linePaint);
            canvas.drawText(showText,showTextCenterX + leftMinimumWidth / 2,showTextBaselineY,showTextPaint);
        }else if(topMinimumHeight != null) {
            canvas.drawLine(0, getHeight(), getWidth(), getHeight(), linePaint);
            canvas.drawText(showText,showTextCenterX,showTextBaselineY + topMinimumHeight / 2,showTextPaint);
        }else if(rightMinimumWidth != null) {
            canvas.drawLine(0, getHeight(), getWidth() - rightMinimumWidth, getHeight(), linePaint);
            canvas.drawText(showText,showTextCenterX - rightMinimumWidth / 2,showTextBaselineY,showTextPaint);
        }else  if(bottomMinimumHeight != null) {
            canvas.drawLine(0, getHeight() - bottomMinimumHeight, getWidth(), getHeight() - bottomMinimumHeight, linePaint);
            canvas.drawText(showText,showTextCenterX,showTextBaselineY - bottomMinimumHeight / 2,showTextPaint);
        }else{
            canvas.drawLine(0, getHeight(), getWidth(), getHeight(), linePaint);
            canvas.drawText(showText,showTextCenterX,showTextBaselineY,showTextPaint);
        }

    }

    /**
     * 定位文本绘制的位置
     */
    private void setTextLocation(Paint showTextPaint) {
        viewHeight = getHeight();
        viewWidth = getWidth();
        fm = showTextPaint.getFontMetrics();
        //文本的宽度
        float textWidth = showTextPaint.measureText(showText);
        float textHeight = fm.descent - fm.ascent;
        float textCenterVerticalBaselineY = viewHeight / 2 - fm.descent + (fm.descent - fm.ascent) / 2;
        switch (showTextAlign) {
            case TEXT_ALIGN_CENTER://居中
                default:
                showTextCenterX = (float)viewWidth / 2 - textWidth / 2;
                showTextBaselineY = textCenterVerticalBaselineY;
                break;
            case TEXT_ALIGN_LEFT_CENTER://居中靠最左
                showTextCenterX = textWidth / 2;
                showTextBaselineY = textCenterVerticalBaselineY;
                break;
            case TEXT_ALIGN_RIGHT_CENTER://居中靠最右
                showTextCenterX = viewWidth - textWidth / 2;
                showTextBaselineY = textCenterVerticalBaselineY;
                break;
            case TEXT_ALIGN_CENTER_HORIZONTAL_BOTTOM://居中靠最下
                showTextCenterX = Float.valueOf(viewWidth / 2);
                showTextBaselineY = viewHeight - fm.bottom;
                break;
            case TEXT_ALIGN_CENTER_HORIZONTAL_TOP://居中靠最上
                showTextCenterX = Float.valueOf(viewWidth / 2);
                showTextBaselineY = -fm.ascent;
                break;
            case TEXT_ALIGN_LEFT_TOP://左上
                showTextCenterX = textWidth / 2;
                showTextBaselineY =  -fm.ascent;
                break;
            case TEXT_ALIGN_LEFT_BOTTOM://左下
                showTextCenterX = textWidth / 2;//
                showTextBaselineY = viewHeight - fm.bottom;
                break;
            case TEXT_ALIGN_RIGHT_TOP://右上
                showTextCenterX = viewWidth - textWidth / 2;
                showTextBaselineY = -fm.ascent;
                break;
            case TEXT_ALIGN_RIGHT_BOTTOM://右下
                showTextCenterX = viewWidth - textWidth / 2;
                showTextBaselineY = viewHeight - fm.bottom;
                break;
            case TEXT_ALIGN_CENTER_TOP://居中靠上
                showTextCenterX = (float)viewWidth / 2;
                showTextBaselineY = textCenterVerticalBaselineY - textHeight / 2;
                break;
            case TEXT_ALIGN_CENTER_BOTTOM:/** 居中靠下显示  */
                showTextCenterX = (float)viewWidth / 2;
                showTextBaselineY = textCenterVerticalBaselineY + textHeight / 2;
                break;
            case TEXT_ALIGN_CENTER_LEFT:/** 居中靠左显示  */
                showTextCenterX = (float)viewWidth / 2 - textWidth / 2 ;
                showTextBaselineY = textCenterVerticalBaselineY;
                break;
            case TEXT_ALIGN_CENTER_RIGHT:/** 居中靠右显示  */
                showTextCenterX = (float)viewWidth / 2 + textWidth / 2 ;
                showTextBaselineY = textCenterVerticalBaselineY;
                break;
            case TEXT_ALIGN_CENTER_LEFT_TOP:/** 居中靠左上显示  */
                showTextCenterX = (float)viewWidth / 2 - textWidth / 2 ;
                showTextBaselineY = textCenterVerticalBaselineY - textHeight / 2 ;
                break;
            case TEXT_ALIGN_CENTER_LEFT_BOTTOM:/** 居中靠左下显示  */
                showTextCenterX = (float)viewWidth / 2 - textWidth / 2 ;
                showTextBaselineY = textCenterVerticalBaselineY + textHeight / 2 ;
                break;
            case TEXT_ALIGN_CENTER_RIGHT_TOP:/** 居中靠右上显示  */
                showTextCenterX = (float)viewWidth / 2 + textWidth / 2 ;
                showTextBaselineY = textCenterVerticalBaselineY - textHeight / 2 ;
                break;
            case TEXT_ALIGN_CENTER_RIGHT_BOTTOM:/** 居中靠右下显示  */
                showTextCenterX = (float)viewWidth / 2 + textWidth / 2 ;
                showTextBaselineY = textCenterVerticalBaselineY + textHeight / 2 ;
                break;
        }
    }

    public UnderlineEdittextView setShowTextAlign(int showTextAlign) {
        this.showTextAlign = showTextAlign;
        postInvalidate();
        return this;
    }


    @Override
    public void setCompoundDrawables(Drawable left, Drawable top, Drawable right, Drawable bottom) {
        super.setCompoundDrawables(left, top, right, bottom);
        if(left != null) {
            leftMinimumWidth = new Integer(left.getMinimumWidth()) + getPaddingLeft();
        }
        if(top != null) {
            topMinimumHeight = new Integer(top.getMinimumHeight()) + getPaddingTop();
        }
        if(right != null) {
            rightMinimumWidth = new Integer(right.getMinimumWidth()) + getPaddingRight();
        }
        if(bottom != null) {
            bottomMinimumHeight = new Integer(bottom.getMinimumHeight()) + getPaddingBottom();
        }
    }



    @Override
    public void setBackground(Drawable background) {
        super.setBackground(null);
    }

    @Override
    public void setGravity(int gravity) {
    }

    /**
     * 重写当字符改变时候的监听
     * @param text
     * @param start
     * @param lengthBefore
     * @param lengthAfter
     */
    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        this.showText = text.toString();
        postInvalidate();
        invalidate();
    }

}