android用java写文本框_Android 使用TextView实现验证码输入框

一、需求问题

网上开源的是构建同等数量的EditText,这种存在很多缺陷,主要如下

1、数字/字符键盘切换后状态无法保存

2、焦点切换无法判断

3、光标位置无法修正

为了解决上述问题,使用TextView实现输入框,需要解决的问题是

1、允许TextView可编辑输入

2、修改onDraw实现

效果如下

fe4e179fb71b6174645455636130350d.png

二、使用TextView 实现输入框

public class EditTextView extends TextView implements TextWatcher {

private final int INPUT_BOX_NUM = 5;

private int mBoxSpace = 10;

public EditTextView(Context context) {

this(context,null);

}

public EditTextView(Context context, @Nullable AttributeSet attrs) {

this(context, attrs,0);

}

public EditTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

setFocusable(true);

setFocusableInTouchMode(true); //支持触摸聚焦

setClickable(true);

setGravity(Gravity.CENTER_VERTICAL);

setMaxLines(1);

setFilters(new InputFilter[]{

new InputFilter.LengthFilter(INPUT_BOX_NUM)

});

if(Build.VERSION.SDK_INT>=23) {

setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);

}

mBoxSpace = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,10,context.getResources().getDisplayMetrics());

addTextChangedListener(this);

}

@Override

protected boolean getDefaultEditable() {

return true;

}

@Override

protected void onDraw(Canvas canvas) {

// super.onDraw(canvas);

TextPaint paint = getPaint();

int strokeWidth = (int) paint.getStrokeWidth();

int boxWidth = (getWidth()- strokeWidth*2 - (INPUT_BOX_NUM-1)*mBoxSpace)/INPUT_BOX_NUM;

int boxHeight = getHeight() - strokeWidth*2;

RectF rectF = null;

Paint.Style style = paint.getStyle();

Paint.Align align = paint.getTextAlign();

paint.setTextAlign(Paint.Align.CENTER);

paint.setStyle(Paint.Style.STROKE);

paint.setTextAlign(Paint.Align.CENTER);

String text = getText().toString();

for (int i=0;i

rectF = new RectF(

i*(boxWidth+mBoxSpace),

0,

i*(boxWidth+mBoxSpace)+boxWidth,

boxHeight

);

Paint.FontMetrics fontMetrics = paint.getFontMetrics();

float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top

float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom

int baseLineY = (int) (rectF.centerY() - top/2 - bottom/2);//基线中间点的y轴计算公式

canvas.drawRoundRect(rectF,0,0,paint);

if(text.length()>i) {

String CH = String.valueOf(text.charAt(i));

canvas.drawText(CH,rectF.centerX(),baseLineY,paint);

}

}

paint.setStyle(style);

paint.setTextAlign(align);

}

/**

* 控制是否返回完整文本

* @return

*/

@Override

public boolean getFreezesText() {

return true;

}

@Override

public Editable getText() {

return (Editable) super.getText();

}

@Override

public void setText(CharSequence text, BufferType type) {

super.setText(text, BufferType.EDITABLE);

}

/**

* 控制光标展示

* @return

*/

@Override

protected MovementMethod getDefaultMovementMethod() {

return ArrowKeyMovementMethod.getInstance();

}

@Override

public void beforeTextChanged(CharSequence s, int start, int count, int after) {

}

@Override

public void onTextChanged(CharSequence s, int start, int before, int count) {

}

@Override

public void afterTextChanged(Editable s) {

}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值