Android 重写EditText自定义密码输入框

Stella981
• 阅读 692

首先看看效果

Android 重写EditText自定义密码输入框

如上图的密码输入框,没有密码时,有几个密码就有几条下划线,输入密码后显示的内容为“*”,并且底部就没有下划线了,同样有很多方式实现,这里就偷懒改改EditText来实现,所以需要做的就是画线、画“*”,代码很简单,偷懒也没有写attr,属性直接初始化写死了。这个思路同样适用于那些内容区域是方框的密码输入,就是画线和画矩形的区别。

public class PasswordUnderLineEditText extends EditText {

    public interface TextIndexChangeListener {
        void onTextIndexChange(CharSequence text, int index);
    }

    private TextIndexChangeListener mTextIndexChangeListener;

    @ColorInt
    private int lineColor;
    private int lineCount;
    private int lineMargin;
    private int lineHeight;
    private int linePaddingBottom;

    private String changedText;
    private int changedTextSize;
    private int changedTextColor;
    private int textLength;
    private boolean isHideLineOnChanged;

    private Paint mLinePaint;
    private TextPaint mChangedTextPaint;


    public PasswordUnderLineEditText(Context context) {
        this(context, null);
    }

    public PasswordUnderLineEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        lineColor = getResources().getColor(R.color.gray);
        changedTextColor = getResources().getColor(R.color.black);
        lineCount = 6;
        changedTextSize = DensityUtil.sp2px(context, 20);
        lineMargin = DensityUtil.dp2px(context, 12);
        linePaddingBottom = DensityUtil.dp2px(context, 10);
        lineHeight = DensityUtil.dp2px(context, 1);

        changedText = "*";
        isHideLineOnChanged = true;
        setGravity(Gravity.CENTER_VERTICAL);
        setTextColor(getResources().getColor(android.R.color.transparent));
        setBackgroundColor(Color.WHITE);
        setCursorVisible(false); 
        setInputType(InputType.TYPE_CLASS_NUMBER); 
        setFilters(new InputFilter[]{new InputFilter.LengthFilter(lineCount)});

        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mLinePaint.setColor(lineColor);
        mLinePaint.setStyle(Paint.Style.FILL);
        mLinePaint.setStrokeWidth(lineHeight);
        mChangedTextPaint = new TextPaint();
        mChangedTextPaint.setColor(changedTextColor);
        mChangedTextPaint.setTextSize(changedTextSize);
        mChangedTextPaint.setStyle(Paint.Style.FILL);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int height = getHeight();
        int width = getWidth();
        canvas.save();

        int singleLineWidth = width / lineCount;
        int startX = 0;
        int stopX = 0;
        int startY = height - linePaddingBottom;
        for (int i = 0; i < lineCount; i++) {
            if (textLength == 0) {
                startX = i * singleLineWidth + lineMargin;
                stopX = (i + 1) * singleLineWidth - lineMargin;
                canvas.drawLine(startX, startY, stopX, startY, mLinePaint);
            } else if (textLength > 0) {
                int changeIndex;
                if (isHideLineOnChanged) {
                    changeIndex = textLength;
                } else {
                    changeIndex = 0;
                }
                startX = (i + changeIndex) * singleLineWidth + lineMargin;
                stopX = (i + changeIndex + 1) * singleLineWidth - lineMargin;
                canvas.drawLine(startX, startY, stopX, startY, mLinePaint);
            }
        }
        for (int i = 0; i < textLength; i++) {
            startX = i * singleLineWidth + lineMargin;
            stopX = (i + 1) * singleLineWidth - lineMargin;
            canvas.drawText(changedText, (startX + stopX) / 2 - changedTextSize / 4, (height + changedTextSize) / 2, mChangedTextPaint);
        }

        canvas.restore();
    }


    @Override
    protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
        this.textLength = text.length();
        invalidate();
        if(mTextIndexChangeListener!=null){
            mTextIndexChangeListener.onTextIndexChange(text,textLength);
        }
    }
点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
vue 支付密码组件
vue支付密码组件我们要做一个类似京东、支付宝支付时的6位密码组件,效果如下。!(https://oscimg.oschina.net/oscnet/up2a8038f271d1d5b909b0e3ce0c1d6fb4c8a.png)专门为PC端写的。移动端的很多框架基本都已经有了,而且实现逻辑会比pc简单,
Irene181 Irene181
3年前
手把手教你用Python破解加密 zip 文件的密码
摄影:产品经理海鲜咖喱泡饭之前在家里的老电脑中,发现一个加密zip压缩包,由于时隔太久忘记密码了,依稀记得密码是6位字母加数字,网上下载了很多破解密码的软件都没有效果,于是想到自己用Python写一个暴力破解密码的脚本。Python有一个内置模块zipfile可以干这个事情,测试一波,一个测试文件,设置解压密码为123。import zipfile
Easter79 Easter79
3年前
ssh连接服务器
1.概述ssh是一种网络通信协议,用于计算机之间的加密登录.一般用ssh连接服务器有两种方式:密码认证与密钥认证.密码认证就是通过传统的输入密码的方式登录,密钥认证就是把产生的公钥注册到服务器后,用私钥登录,这样就可以不用每次登录输入密码.特别适合作者这种脑残记不住密码的懒人.2.密码认证密码认证登录直接在终端使用ssh
Wesley13 Wesley13
3年前
MySQL远端连接设置
下面是步骤:0、新安装完后是没有密码的,为root添加密码:mysqladminurootpasswordroot'spassword1、登陆本地的mysqlServer:mysql uroot p输入密码后进入mysql。参数u是输入用户名,这里是用root登陆,p是要输入密码。2、使用并查看mysql
Wesley13 Wesley13
3年前
ubuntu 16.04 tty登录显示 login incorrect,输入用户名后无法输入密码
按Ctrl Alt F3进入命令行终端。当输入用户名并按下时Enter后,它不会等待输入密码(就像Enter没有输入任何东西一样按下它)。即使我迅速输入密码,文本以明文显示,然后它继续说密码是错误的。然后循环提示 loginincorrect
Stella981 Stella981
3年前
Git远程推送时记住用户名和密码
当使用HTTPS协议推送代码到Git仓库时,发现每次都需要输入密码,操作起来非常麻烦。下面介绍几种免去输入密码的方法。HTTPS协议推送使用HTTPS协议,有一种简单粗暴的方式是在远程地址中带上密码。gitremoteseturloriginhttp://yourname:password@bitbucket.org
Wesley13 Wesley13
3年前
Mysql常用命令行大全
1、连接Mysql格式:mysqlh主机地址u用户名-p用户密码1、连接到本机上的MYSQL。首先打开DOS窗口,然后进入目录mysql\\bin,再键入命令mysqlurootp,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密码前必须没有空格,否则让你重新输入密码。
Wesley13 Wesley13
3年前
EditText数据回显
首先我们假设我们把用户名和密码都保存在data/data/com.xxx.xxx/files/info.txt中,格式为:用户名密码。我们接下来要做的就是把info.txt中保存的用户名和密码分别回显在两个EditText中。下面为自定义的回显用户名和密码的方法:publicstaticMap<String,StringgetSaveUs
Stella981 Stella981
3年前
Android 如何自定义EditText 下划线?
项目要求:笔者曾经做过一个项目,其中登录界面的交互令人印象深刻。交互设计师给出了一个非常作的设计,要求做出包含根据情况可变色的下划线,左侧有可变图标,右侧有可变删除标志的输入框,如图!Android如何自定义EditText下划线?(http://i.imgur.com/oYlipFY.jpg)记录制作过程:第一版本pu
Stella981 Stella981
3年前
EditText 使用详解
本篇文章主要介绍Android开发中的部分知识点,通过阅读本篇文章,您将收获以下内容:一、EditText继承关系二、EditText常用举例三、EditText自定义背景框四、EditText自动检测输入内容五、Edittext密文显示六