按照常规先展示效果图并说明:
主要有以下几个效果:
- edittext中的内容为0时,标签不出现
- edittext中的内容不为0时,标签开始出现
- edittext获取焦点时,下划线的颜色/粗细会发生改变
- edittext失去焦点时,下划线同样发生改变,标签颜色也更改
- 当限制输入字符个数时,右下角计数文字会进行计数
- 超过个数后,下划线和计数文字颜色会发生变化
一、继承EditText
为保留EditText的一些独特属性,我们选择继承EditText来实现自定义MaterialEditText.
但在原生的EditText动手脚绘制一些文字/线,我们需要进行一些预处理:
原生EditText本身含有下划线,我们需要将原生下划线去掉,这里可以通过设置EditView背景为null来实现
// 设置edittext的背景为空,主要为了隐藏自带的下划线 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { setBackground(null); } else { setBackgroundDrawable(null); }
要绘制文字/下划线,我们需要获得坐标。而EditText的内部是可以滑动的,随着文字的增加,高度也会自动的增长。这里我们获取坐标时,使用 getScrollX() 和 getScrollY() 这两个函数获取输入状态下,我们需要的不断变化的横坐标和纵坐标:
// 获取下划线的起点纵坐标y lineStartY = getScrollY()+getHeight()-getPaddingBottom()+dpToPix(5); // 获取下划线的起点横坐标x / 标签文字的横坐标x getScrollX() ...其他类似
在系统开始绘制MaterialEditText之前,我们需要重新设置原生EditText的padding值,为什么需要重新设置padding值呢?因为我们在原生EditText上绘制文字和下划线等,占用了输入框的高度。重新设置padding值后,我们可以在padding的地方绘制我们的文字和下划线。一般我们设置顶部和底部的padding值就好了
// 额外的顶部内边距 private int extraTopPadding; // 额外的底部内边距 private int extraBottomPadding; // 获取额外的顶部内边距:用于绘制文字和文字的margin extraTopPadding = (int) getTextHeight(textPaint) + dpToPix(4); // 获取额外的底部内边距:用于绘制底部的计数的文字和文字的margin extraBottomPadding = (int) getTextHeight(textPaint) + dpToPix(6); // 重新设置内边距 // 因为我们需要绘制标签和下划线,因此需要重新设置padding值 private void correctPaddings() { super.setPadding(getPaddingLeft(),getPaddingTop()+extraTopPadding,getPaddingRight(),getPaddingBottom()+extraBottomPadding+dpToPix(5)); // 最后底部加上5dp主要是为了包含绘制下划线的空间 }
二、自定义属性
解决了上面的问题后,我们需要为MaterialEditText自定义一些常用的属性:
<declare-styleable name="MaterialEditText">
<attr name="preLineColor" format="colo