700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 自定义自带下划线的EditText输入框

自定义自带下划线的EditText输入框

时间:2021-09-30 07:12:39

相关推荐

自定义自带下划线的EditText输入框

先看看效果

图片中间就是实现的输入框样式了,输入框的个数,每个输入框之间的间距,输入文字和底部线条的颜色都可以动态改变,接下来就是撸代码的时刻了

1.现在values文件夹下创建attrs.xml ,复制样式

<declare-styleable name="VerifyEditText"><!--验证码的个数--><attr name="totalCount" format="integer" /><!-- 每个验证码的间隔间距--><attr name="intervalLength" format="integer" /><!--底部的线的颜色--><attr name="lineColor" format="color" /><!--输入框文字的颜色--><attr name="textColor" format="color" /></declare-styleable>

2.接下来写一个类继承EditText

public interface OnVerifyInputCompleteListener {void onCompleteInput(String input);}

/*** Created by ytt on /7/27.* 自定义验证码输入框*/public class VerifyEditText extends android.support.v7.widget.AppCompatEditText {/*** 本控件的宽高*/private int width;private int height;private OnVerifyInputCompleteListener listener;//TODO 保存输入的验证码集合private StringBuffer sb = new StringBuffer();//底部的线 画笔private Paint mLinePaint;//文字的画笔private Paint mTextPaint;//计算出的每一个输入框的宽度private int textLineLength;//验证码的数量private int totalCount;//每一个验证码之间的距离private int intervalLength;//底部线的颜色private int lineColor;//输入文字的颜色private int textColor;public VerifyEditText(Context context) {this(context, null);}public VerifyEditText(Context context, AttributeSet attrs) {this(context, attrs, R.attr.editTextStyle);}public VerifyEditText(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.VerifyEditText, defStyleAttr, 0);totalCount = typedArray.getInt(R.styleable.VerifyEditText_totalCount, 4);intervalLength = typedArray.getInt(R.styleable.VerifyEditText_intervalLength, 30);lineColor = typedArray.getColor(R.styleable.VerifyEditText_lineColor, getColor(R.color.textE6));textColor = typedArray.getColor(R.styleable.VerifyEditText_textColor, getColor(R.color.text3));typedArray.recycle();initView();}private void initView() {setBackground(null);setMaxLines(1);setLines(1);/*** 必须重写setOnTouchListener 自己处理触摸事件,否则光标可以移动* 必须重写setOnLongClickListener 否则长按可以复制验证码* 不然光标就可以移动啦~~*/setOnLongClickListener(new OnLongClickListener() {@Overridepublic boolean onLongClick(View v) {return true;}});setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent event) {InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);imm.showSoftInput(VerifyEditText.this, 0);return true;}});//TODO 设置输入的字体透明 不可见setTextColor(getColor(android.R.color.transparent));mLinePaint = new Paint();mLinePaint.setColor(lineColor);mLinePaint.setAntiAlias(true);mLinePaint.setStrokeWidth(3);mTextPaint = new Paint();mTextPaint.setTextSize(sp2px(22));mTextPaint.setFakeBoldText(true);mTextPaint.setColor(textColor);mTextPaint.setAntiAlias(true);//TODO 增加输入字符的监听addTextChangedListener(textWatcher);}@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);width = w;height = h;//每一个输入文字的宽度textLineLength = (width - (totalCount - 1) * intervalLength) / totalCount;//定位光标的初始显示位置setPadding(textLineLength / 2, getPaddingTop(), getPaddingRight(), getPaddingBottom());}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if (totalCount <= 0) {return;}int currentLength = 0;//TODO 绘制文字for (int i = 0; i < totalCount; i++) {String textString = String.valueOf((sb != null && sb.length() > i) ? sb.charAt(i) : "");canvas.drawText(textString, currentLength + textLineLength / 2 - mTextPaint.measureText(textString) / 2, height / 2 + mTextPaint.getTextSize() / 2, mTextPaint);currentLength += textLineLength + intervalLength;}//TODO 绘制文字底部的线currentLength = 0;for (int i = 0; i < totalCount; i++) {canvas.drawLine(currentLength, height - 3, textLineLength * (i + 1) + intervalLength * i, height - 3, mLinePaint);currentLength += textLineLength + intervalLength;}}private TextWatcher textWatcher = new TextWatcher() {@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic void onTextChanged(CharSequence s, int start, int before, int count) {}@Overridepublic void afterTextChanged(Editable s) {sb.delete(0, sb.length());if (!TextUtils.isEmpty(s.toString())) {//TODO 只能输入指定totalCount个数的字多出的需要删除if (s.toString().length() > totalCount) {s.delete(totalCount, s.length());return;}sb.append(s);if (s.toString().length() == totalCount && listener != null) {listener.onCompleteInput(sb.toString());}}int paddingLeft;/*** 计算验证码输入之后光标显示的位置* 如果已经输完验证码则光标需要显示在最后一个字符的后面而不是下一个文字输入框* */if (sb.length() < totalCount) {paddingLeft = (int) ((textLineLength + intervalLength) * sb.length()+ textLineLength / 2 - getPaint().measureText(!TextUtils.isEmpty(sb.toString()) ? sb.toString() : ""));} else {paddingLeft = (int) ((textLineLength + intervalLength) * (sb.length() - 1)+ (mTextPaint.measureText(sb.substring(sb.length() - 2, sb.length() - 1)) / 2)+ textLineLength / 2 - getPaint().measureText(!TextUtils.isEmpty(sb.toString()) ? sb.toString() : ""));}setPadding(paddingLeft, getPaddingTop(), getPaddingRight(), getPaddingBottom());}};/*** 设置输入完成监听*/public void setOnVerifyInputCompleteListener(OnVerifyInputCompleteListener listener) {this.listener = listener;}/*** 获取输入的验证码*/public String getVerifyCode() {return sb.toString();}public int getColor(int id) {return ContextCompat.getColor(getContext(), id);}public int sp2px(float spValue) {final float fontScale = getResources().getDisplayMetrics().scaledDensity;return (int) (spValue * fontScale + 0.5f);}}

3.使用VerifyEditText

<cn.test.view.VerifyEditTextandroid:id="@+id/verifyEditText"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="50dp"android:layout_marginRight="50dp"android:inputType="text" />

xml中显示的样式

遇到的问题总结:

1.输入之后因为是根据计算输入的个数给光标设置padding所以光标才可以显示在相应位置,但是输入的文字只是设置成透明色,其实是存在的,这样的话光标就可以点击长按全选复制。。所以必须重写ontouch和onlongclick事件,ontouch事件只允许调起键盘不允许进行其他操作,代码自动实现的操作详情可以查看TextView中的OnTouch事件

2.输入文字之后可以换行,这个吧需要设置lines

其他的暂时也没什么,代码直接拷贝就可以用,噢啦

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。