效果样式:

这个比较特别的editText是公司的一个新的需求,我也是在网上找了一下,然后看到了一篇博客然后修改成自己需要的样式。这种一般的思路就是在onDraw()方法绘制editText的特别的样式,如果输入里面的值是*这种特殊字符就只用直接绘制,如果需要输入进去的值则可以在onTextChanged方法中获取每一次更改editText值,在onDraw方法里一个个的绘制。

自定义的editText

package com.kkrs.selfedit;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.InputFilter;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.EditText; import static android.graphics.Paint.ANTI_ALIAS_FLAG; /**
* Created by zd on 2018/11/27.
*/ public class InputView extends EditText {
private Context mContext;
/**
* 第一个圆开始绘制的圆心坐标
*/
private float startX;
private float startY; private float cX; int psdType = 0; /**
* 实心圆的半径
*/
private int radius = 10;
/**
* view的高度
*/
private int height;
private int width; /**
* 当前输入密码位数
*/
private int textLength = 0;
private int bottomLineLength;
/**
* 最大输入位数
*/
private int maxCount = 6;
/**
* 圆的颜色 默认BLACK
*/
private int circleColor = Color.BLACK;
/**
* 底部线的颜色 默认GRAY
*/
private int bottomLineColor = Color.GRAY; /**
* 分割线开始的坐标x
*/
private int divideLineWStartX; /**
* 分割线的宽度 默认2
*/
private int divideLineWidth = 2;
/**
* 竖直分割线的颜色
*/
private int divideLineColor = Color.GRAY;
private int focusedColor = Color.BLUE;
private RectF rectF = new RectF();
private RectF focusedRecF = new RectF(); private String texts = "";
/**
* 矩形边框的圆角
*/
private int rectAngle = 0;
/**
* 圆的画笔
*/
private Paint circlePaint;
/**
* 底部线的画笔
*/
private Paint bottomLinePaint; /**
* 需要对比的密码 一般为上次输入的
*/
private String mComparePassword = null; /**
* 当前输入的位置索引
*/
private int position = 0; private onPasswordListener mListener; public InputView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context; getAtt(attrs);
initPaint(); this.setBackgroundColor(Color.TRANSPARENT);
this.setCursorVisible(false);
this.setFilters(new InputFilter[]{new InputFilter.LengthFilter(maxCount)}); } private void getAtt(AttributeSet attrs) {
TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.PayPsdInputView);
maxCount = typedArray.getInt(R.styleable.PayPsdInputView_maxCount, maxCount);
circleColor = typedArray.getColor(R.styleable.PayPsdInputView_circleColor, circleColor);
bottomLineColor = typedArray.getColor(R.styleable.PayPsdInputView_bottomLineColor, bottomLineColor);
radius = typedArray.getDimensionPixelOffset(R.styleable.PayPsdInputView_radius, radius);
divideLineWidth = typedArray.getDimensionPixelSize(R.styleable.PayPsdInputView_divideLineWidth, divideLineWidth);
divideLineColor = typedArray.getColor(R.styleable.PayPsdInputView_divideLineColor, divideLineColor);
psdType = typedArray.getInt(R.styleable.PayPsdInputView_psdType, psdType);
rectAngle = typedArray.getDimensionPixelOffset(R.styleable.PayPsdInputView_rectAngle, rectAngle);
focusedColor = typedArray.getColor(R.styleable.PayPsdInputView_focusedColor, focusedColor); typedArray.recycle();
} /**
* 初始化画笔
*/
private void initPaint() { circlePaint = getPaint(5, Paint.Style.FILL, circleColor); bottomLinePaint = getPaint(2, Paint.Style.FILL, bottomLineColor); } /**
* 设置画笔
*
* @param strokeWidth 画笔宽度
* @param style 画笔风格
* @param color 画笔颜色
* @return
*/
private Paint getPaint(int strokeWidth, Paint.Style style, int color) {
Paint paint = new Paint(ANTI_ALIAS_FLAG);
paint.setStrokeWidth(strokeWidth);
paint.setStyle(style);
paint.setColor(color);
paint.setAntiAlias(true);
paint.setTextSize(40);
return paint;
} @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
height = h;
width = w; divideLineWStartX = w / maxCount; startX = w / maxCount / 2;
startY = h / 2; bottomLineLength = w / (maxCount + 2); rectF.set(0, 0, width, height); } @Override
protected void onDraw(Canvas canvas) {
//不删除的画会默认绘制输入的文字
// super.onDraw(canvas);
drawBottomBorder(canvas); switch (psdType){
case 0:
char[] cc;
cc=texts.toCharArray();
for (int i = 0; i < cc.length; i++) {
Log.e("sys","cc="+cc[i]);
canvas.drawText(cc[i]+"",startX + i * 2 * startX,
startY,circlePaint);
}
break;
case 1:
drawPsdCircle(canvas); break;
}
} /**
* 画密码实心圆
*
* @param canvas
*/
private void drawPsdCircle(Canvas canvas) {
for (int i = 0; i < textLength; i++) {
canvas.drawCircle(startX + i * 2 * startX,
startY,
radius,
circlePaint);
}
}
/**
* 画底部显示的分割线
*
* @param canvas
*/
private void drawBottomBorder(Canvas canvas) { for (int i = 0; i < maxCount; i++) {
cX = startX + i * 2 * startX;
canvas.drawLine(cX - bottomLineLength / 2,
height,
cX + bottomLineLength / 2,
height, bottomLinePaint);
}
} @Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
this.position = start + lengthAfter;
textLength = text.toString().length();
texts = text.toString();
Log.e("onTextChanged",text.toString()); if (textLength == maxCount) {
if (mListener != null) {
if (TextUtils.isEmpty(mComparePassword)) {
mListener.inputFinished(getPasswordString());
} else {
if (TextUtils.equals(mComparePassword, getPasswordString())) {
mListener.onEqual(getPasswordString());
} else {
mListener.onDifference(mComparePassword, getPasswordString());
}
}
}
} invalidate(); } @Override
protected void onSelectionChanged(int selStart, int selEnd) {
super.onSelectionChanged(selStart, selEnd); //保证光标始终在最后
if (selStart == selEnd) {
setSelection(getText().length());
}
} /**
* 获取输入的密码
*
* @return
*/
public String getPasswordString() {
return getText().toString().trim();
} public void setComparePassword(String comparePassword, onPasswordListener listener) {
mComparePassword = comparePassword;
mListener = listener;
} public void setComparePassword(onPasswordListener listener) {
mListener = listener;
} public void setComparePassword(String psd) {
mComparePassword = psd;
} /**
* 清空密码
*/
public void cleanPsd() {
setText("");
} /**
* 密码比较监听
*/
public interface onPasswordListener {
void onDifference(String oldPsd, String newPsd); void onEqual(String psd); void inputFinished(String inputPsd);
}
}

在xml的用法:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
xmlns:psd="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
> <com.kkrs.selfedit.InputView
android:id="@+id/pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="20dp"
android:inputType="number"
psd:maxCount="6"
psd:psdType="pwd"/> <com.kkrs.selfedit.InputView
android:id="@+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:layout_marginTop="20dp"
android:inputType="number"
psd:maxCount="11"
psd:psdType="phone"/> </LinearLayout>

github:https://github.com/tempest1/SelfEdit

一个字符带下滑线的EditText的更多相关文章

  1. sql 字符带下划线匹配问题

    SQL 中 _下划线 作用是 匹配一个任意字符. 如果我们要去掉下划线的作用 单纯只用作一个字符则需要转义成    like '%\_%' escape '\' 字段 1.order_qrsc 2.o ...

  2. Android实现带下划线的EditText(BUG修正)

    之前写了一个关于实现EditText显示下划线的例子,发现仍然存在一些问题,在此继续探索,原文链接:http://www.cnblogs.com/ayqy/p/3599414.html (零)另一个b ...

  3. delphi 仅带下划线的TEdit控件

    在做录入框的时候,很希望有一个只带下划线的文本框,网上介绍的很多,有自己做组件的,须不知Delphi下只需要简单设置几个属性即可达到目的.

  4. ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器。用springframework自带的便可

    ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器.用springframework自带的便可

  5. C++学习45 流成员函数put输出单个字符 cin输入流详解 get()函数读入一个字符

    在程序中一般用cout和插入运算符“<<”实现输出,cout流在内存中有相应的缓冲区.有时用户还有特殊的输出要求,例如只输出一个字符.ostream类除了提供上面介绍过的用于格式控制的成员 ...

  6. utf-8的中文,一个字符占几个字节

    https://blog.csdn.net/kindsuper_liu/article/details/80202150 英文字母和中文汉字在不同字符集编码下的字节数英文字母:·字节数 : 1;编码: ...

  7. utf-8的中文是一个字符占几个字节

    utf-8的中文是一个字符占几个字节 英文字母和中文汉字在不同字符集编码下的字节数英文字母:·字节数 : 1;编码:GB2312 字节数 : 1;编码:GBK 字节数 : 1;编码:GB18030 字 ...

  8. Android带加减的edittext

    看了网上这样自带加减的edittext写得好复杂,还有各种监听事件,我觉得没有必有.于是我自己写了一个. 我这个edittext仅仅限制整数,每次加减1. public class TestEditT ...

  9. php 去掉字符串的最后一个字符

    原字符串1,2,3,4,5,6, 去掉最后一个字符",",最终结果为1,2,3,4,5,6 代码如下: $str = "1,2,3,4,5,6,"; $news ...

随机推荐

  1. Netty源码—五、内存分配概述

    Netty中的内存管理应该是借鉴了FreeBSD内存管理的思想--jemalloc.Netty内存分配过程中总体遵循以下规则: 优先从缓存中分配 如果缓存中没有的话,从内存池看看有没有剩余可用的 如果 ...

  2. @GeneratedValue源码解析

    JPA要求每一个实体必须有且只有一个主键,而@GeneratedValue提供了主键的生成策略,这就是@GeneratedValue注解存在的意义.本文将浅析@GeneratedValue的源码. @ ...

  3. C语言超级搞笑的代码,冷笑话我们程序员也会讲的啊!

    百年修得足下点击本文 欢迎来到"C语言基础"专题,今天我们放松一天,不学习知识,来看下大千世界的千奇百怪的C语言代码,你见过那些? 1.关于随机数这回事 这个随机数有点意思哦. 2 ...

  4. Android 个人手机通讯录开发

    一.Android 个人手机通讯录开发 数据存储:SQLite 数据库 开发工具:Android Studio 二.Phone Module 简介 1. 界面展示                2. ...

  5. QT文件操作

    /* 写文件 */ QFile file(filePath); bool bo = file.open(QIODevice::WriteOnly | QIODevice::Append); //qDe ...

  6. uboot的驱动模型理解

    uboot的驱动模型,简称dm, 具体细节建议参考./doc/driver-model/README.txt 关于dm的三个概念: uclass:一组同类型的devices,uclass为同一个gro ...

  7. [原创] 分享我们自己搭建的微信小程序开发框架——wframe及设计思想详解

    wframe不是控件库,也不是UI库,她是一个微信小程序面向对象编程框架,代码只有几百行.她的主要功能是规范小程序项目的文件结构.规范应用程序初始化.规范页面加载及授权管理的框架,当然,wframe也 ...

  8. 零基础java的福音!史上最全最精简的学习路线图!

    这是一个java系统学习路线,从零基础到项目框架开发,每一个阶段里面内容都标记的很清楚,如果你现在也在学习java,你可以跟着这个系统学习路线学,学完自己可以独立的完成项目框架开发,二线城市拿个7k+ ...

  9. nginx部署静态网站

    实验环境 服务器:centos7.5 1核1G Nginx版本:nginx-1.14.2 主题 部署静态文件 根据不同url请求路径,定向到不同的系统文件夹 部署静态文件 假设nginx安装在“/us ...

  10. Spring 进入Controller前参数校验

    在进入Controller前完成参数的校验,针对对象参数 分为两个验证方式 (1)直接使用已定义的校验方式 1.在需要进行校验的属性上增加校验类型注解 import java.util.Date; i ...