跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Java大前端java

Android 自定义 View 实现密码输入控件

Android 自定义 View 实现密码输入控件采用单个 EditText 作为数据捕捉源,配合多个 TextImageView 子类进行字符显示。核心逻辑包括隐藏 EditText 光标、动态添加显示视图、监听文本变化同步更新界面,并在输入完成时触发回调。该方案支持自定义宽高、字体颜色及间距,解决了传统多 EditText 组合的布局问题,实现了更灵活的密码输入体验。

CloudNative发布于 2025/2/7更新于 2026/10/24111 浏览
Android 自定义 View 实现密码输入控件

Android 自定义 View 实现密码输入控件

本示例介绍了一种 Android 自定义 View 实现输入控件的方案。不同于网络上大部分由多个 EditText 组合而成的输入控件,本例采用以下结构:

  • 单个 EditText 作为输入的捕捉控件
  • 多个 ImageView 的子类(TextImageView)作为显示的控件,用于绘制 EditText 中的数据

主要功能特性包括:

  • 输入前和输入后输入框发生响应改变
  • 点击自定义控件弹出软键盘
  • EditText 数据捕捉,且 EditView 不可直接操作(防止数据处理混乱)
  • 输入完成后得到相应提示
  • TextImageView 子类可设置宽高、字体大小颜色以及两个 View 之间的间隔

TextImageView 实现

TextImageView 是 ImageView 的子类,其 onDraw 实现主要判断 text 长度是否大于 0,若大于 0 则绘制文字,同时处理字体颜色、字体大写及获取字体宽高细节。

@Override
protected void onDraw(Canvas canvas) {
    if (text.length() > 0) {
        if (isDrawSrc) {
            super.onDraw(canvas);
        }
        canvas.drawText(text, 0, text.length(), (getMeasuredWidth() - textWidth) / 2, (getMeasuredHeight() + dy) / 2, textPaint);
    } else {
        super.onDraw(canvas);
    }
}

PasswordView 实现

PasswordView 是一个自定义 ViewGroup,引入了一个布局,布局中包含一个 EditText(数据捕捉)和一个 LinearLayout(动态添加 TextImageView)。EditText 的宽高设置为 1dp 和 0dp(避免用户直接操作 EditText);LinearLayout 设置 divider 属性以控制 TextImageView 的间隔。

核心代码

控制 EditText 获取输入:

public void requestEtFocus() {
    catchInput.setFocusable(true);
    catchInput.setFocusableInTouchMode(true);
    catchInput.setClickable(true);
    catchInput.requestFocus();
    showSoftKeyboard(catchInput);
    catchInput.setCursorVisible(false);
    catchInput.setSelection(catchInput.length());
}

动态添加 TextImageView 及输入监听:

// 动态添加 TextImageView
for (int i = 0; i < passwordLength; i++) {
    TextImageView view = new TextImageView(context);
    view.setTextSize(textSize);
    view.setTextColor(textColor);
    content.addView(view);
    if (unInputBg != 0) {
        view.setBackgroundResource(unInputBg); // 设置未输入前的背景
    }
    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams((int) itemWidth, (int) itemHeight);
    if (i == 0) {
        params.setMargins((int) dpToPixel(1), 0, 0, 0);
    }
    if (i == passwordLength - 1) {
        params.setMargins(0, 0, (int) dpToPixel(1), 0);
    }
    view.setLayoutParams(params);
    views[i] = view;
    // 分割字体,给 TextImageView 绘制文字
    if (text != null && i < text.length()) {
        setItemText(text.subSequence(i, i + 1));
    }
}

// 输入监听
catchInput.addTextChangedListener(new TextWatcher() {
    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (s.length() > 0) {
            // index:成员变量,保存当前的输入了几个字符
            if (index < s.length()) {
                removeItemText(); // 删除
            } else {
                setText(s);
                if (s.length() == passwordLength) {
                    if (listener != null) {
                        // 输入完成回调
                        listener.onInputCodeEnd(s);
                    }
                }
            }
        } else if (s.length() == 0 && index > 0) {
            removeItemText();
        }
    }

    @Override
    public void afterTextChanged(Editable s) {
    }
});

实现比较简单,大多是一些细节处理,具体参考源码 PasswordView。

目录

  1. Android 自定义 View 实现密码输入控件
  2. TextImageView 实现
  3. PasswordView 实现
  4. 核心代码

更多推荐文章

查看全部
  • FANUC 机器人 PR 寄存器详解
  • 本地部署 Kimi K2 模型:llama.cpp、vLLM、Docker 三种方案
  • API、REST API、RESTful API 与 Web Service 的区别
  • Prometheus 集成 Python 业务指标的三种主流方案及代码示例
  • 循环神经网络(RNN)与序列数据处理实战
  • Trae AI 与 VS Code 配置 Claude、GPT、Gemini 大模型接入教程
  • Llama.cpp 部署教程:老旧电脑运行大模型方案
  • MySQL 数据库基础:概念、架构与核心使用指南
  • 网络安全行业前景、求职方向与学习路线
  • 医疗 AI 多智能体协同路径规划技术综述(下)
  • 智能家居多协议网关融合配置技术解析
  • AI 短视频制作技术指南:文本、图片与视频生成
  • PHP 低代码流程建模的 5 个致命误区与优化实践
  • 国内主流大模型 API 调用指南与 Python 实战
  • WorkBuddy 接入 QQ 机器人配置指南
  • Stable Diffusion 整合包安装及基础使用教程
  • DeepSeek-R1-Distill-Llama-8B 驱动的 Python 爬虫实战与智能清洗
  • 优雅草正版授权系统前端实现与技术栈
  • VS Code 前端开发必备 10 款插件及配置指南
  • 三款主流云电脑部署 DeepSeek 模型实测对比

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online