TextInput 组件(新手村第四篇)

目录

一、核心组件

1、基础组件:EditText(继承自 TextView)

2、增强组件:TextInputLayout + TextInputEditText(推荐)

二、基础用法(EditText 核心属性)、

1、XML 布局配置(基础输入框)

2、核心属性详解(必掌握)

三、增强用法(TextInputLayout + TextInputEditText)

1、1. XML 布局配置(带错误提示 + hint 上浮)

2、Java 代码操作(获取输入、设置错误、密码切换)

四、样式定制(输入框背景、光标、错误样式)

1、自定义 EditText 背景(下划线 + 状态切换)

2、自定义光标样式

五、进阶功能(输入限制、格式格式化、防抖)

1、 输入格式限制(如手机号:3-4-4 分隔)

2、禁止输入空格(或特定字符)

3、 输入防抖(避免频繁校验)


TextInput 相关组件是 Android 中用于 文本输入交互 的核心控件,主要包括 EditText(基础输入框)和 Material Design 提供的 TextInputEditText+TextInputLayout(带提示、错误反馈的增强版输入框),核心作用是接收用户输入(如账号、密码、内容等),支持输入限制、格式校验、输入反馈等功能。以下是其核心用法、属性配置、校验逻辑和进阶技巧(以 Java 代码为主,结合 XML 配置):

一、核心组件

1、基础组件:EditText(继承自 TextView)

EditText 是最基础的输入框组件,直接继承 TextView,因此支持 texttextSizetextColor 等文本属性,同时扩展输入相关功能(如输入类型、光标、hint 提示等)。

2、增强组件:TextInputLayout + TextInputEditText(推荐)

TextInputLayout 是 Material Design 提供的容器组件,包裹 TextInputEditText 后,可实现以下增强功能:

  • 提示文本(hint)上浮效果(输入时 hint 移到输入框上方);
  • 内置错误提示(无需额外布局,直接显示错误信息);
  • 密码可见 / 隐藏切换、计数提示等扩展功能;
  • 更美观的 Material 风格样式(下划线、圆角等)。

⚠️ 注意:使用这两个组件需添加 Material Design 依赖(AndroidX):

dependencies {
    // Material Design 依赖(支持 TextInputLayout/TextInputEditText)
    implementation 'com.google.android.material:material:1.9.0'
}

二、基础用法(EditText 核心属性)、

1、XML 布局配置(基础输入框)

<!-- res/layout/activity_main.xml -->
<EditText
    android:id="@+id/et_username"
    android:layout_width="match_parent"
    android:layout_height="56dp"
    android:hint="请输入用户名"
    android:hintTextColor="#999999"  // 提示文本颜色
    android:textSize="16sp"
    android:textColor="#333333"
    android:inputType="text"  //输入类型(文本)
    android:maxLines="1"  //单行输入
    android:paddingHorizontal="16dp"
    android:background="@drawable/et_bg_selector"  //自定义背景
    android:cursorVisible="true"  //显示光标
    android:cursorColor="#2196F3"  //光标颜色
    android:digits="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"  //允许输入的字符
    android:maxLength="20"/>  //最大输入长度

2、核心属性详解(必掌握)

属性名作用常用值 / 示例
android:hint

输入提示文本

(占位符)

请输入密码
android:inputType

输入类型

(控制键盘样式)

text(普通文本)、textPassword(密码)、number(数字)、textEmailAddress(邮箱)、phone(手机号)
android:maxLines最大输入行数1(单行,避免输入框变形)、3(多行)
android:maxLength最大输入字符数20(限制账号长度)、11(手机号)
android:digits允许输入的字符集合0123456789(仅数字)、abc123(仅字母 + 数字)
android:enabled

是否启用输入

(禁用时无法输入)

true/false
android:editable是否可编辑(已过时,用 enabled 替代)-
android:cursorColor光标颜色#2196F3(蓝色光标)
android:hintTextColor提示文本颜色#999999(灰色)
android:background输入框背景自定义 Drawable(下划线 / 圆角)
android:imeOptions软键盘右下角按钮样式actionDone(完成)、actionNext(下一步)、actionSearch(搜索)

三、增强用法(TextInputLayout + TextInputEditText)

1、1. XML 布局配置(带错误提示 + hint 上浮)

<!-- 必须用 TextInputLayout 包裹 TextInputEditText -->
<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/til_password"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="16dp"
    app:hintEnabled="true"  //启用 hint 上浮效果(默认 true)
    app:hintTextColor="#999999"  //上浮后 hint 颜色
    app:errorTextColor="#FF0000"  //错误提示颜色
    app:counterEnabled="true"  //启用字符计数
    app:counterMaxLength="20"  //计数最大值(与 EditText 一致)
    app:counterTextColor="#666666"  //计数文本颜色
    app:passwordToggleEnabled="true"  //密码可见/隐藏切换(仅输入类型为密码时生效)
    app:passwordToggleDrawable="@drawable/ic_password_toggle"  //自定义密码切换图标
    app:boxBackgroundMode="outline"  //输入框样式:outline(边框)/filled(填充)
    app:boxCornerRadiusTopStart="8dp"
    app:boxCornerRadiusTopEnd="8dp"
    app:boxCornerRadiusBottomStart="8dp"
    app:boxCornerRadiusBottomEnd="8dp"
    app:boxStrokeColor="#E0E0E0"  //边框颜色
    app:boxStrokeWidth="1dp">  //边框宽度 

    <com.google.android.material.textfield.TextInputEditText
        android:id="@+id/et_password"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:hint="请输入密码"
        android:textSize="16sp"
        android:textColor="#333333"
        android:inputType="textPassword" //密码类型
        android:maxLines="1"
        android:maxLength="20"
        android:paddingHorizontal="16dp"/>

</com.google.android.material.textfield.TextInputLayout>

2、Java 代码操作(获取输入、设置错误、密码切换)

import com.google.android.material.textfield.TextInputLayout;
import com.google.android.material.textfield.TextInputEditText;

public class MainActivity extends AppCompatActivity {
    private TextInputLayout tilPassword;
    private TextInputEditText etPassword;
    private EditText etUsername;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化控件(ViewBinding 方式更简洁,此处用 findViewById 示例)
        etUsername = findViewById(R.id.et_username);
        tilPassword = findViewById(R.id.til_password);
        etPassword = findViewById(R.id.et_password);

        // 1. 获取输入内容(注意判空)
        String username = etUsername.getText().toString().trim();
        String password = etPassword.getText().toString().trim();

        // 2. 设置错误提示(通过 TextInputLayout 显示,在输入框下方)
        tilPassword.setError("密码长度不能少于6位");

        // 3. 清除错误提示
        tilPassword.setError(null);
        // 或隐藏错误(保留错误图标空间)
        tilPassword.setErrorEnabled(false);

        // 4. 监听输入变化(实时校验)
        etPassword.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 (tilPassword.isErrorEnabled()) {
                    tilPassword.setError(null);
                }
            }

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

        // 5. 软键盘「下一步」切换到密码输入框(需配合 imeOptions)
        etUsername.setImeOptions(EditorInfo.IME_ACTION_NEXT);
        etUsername.setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_NEXT) {
                // 切换焦点到密码输入框
                etPassword.requestFocus();
                return true;
            }
            return false;
        });

        // 6. 软键盘「完成」按钮逻辑(密码输入框)
        etPassword.setImeOptions(EditorInfo.IME_ACTION_DONE);
        etPassword.setOnEditorActionListener((v, actionId, event) -> {
            if (actionId == EditorInfo.IME_ACTION_DONE) {
                // 隐藏软键盘
                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                // 执行登录校验等逻辑
                validateInput();
                return true;
            }
            return false;
        });
    }

    // 输入校验逻辑
    private void validateInput() {
        String username = etUsername.getText().toString().trim();
        String password = etPassword.getText().toString().trim();

        if (TextUtils.isEmpty(username)) {
            etUsername.setError("用户名不能为空"); // EditText 直接显示错误(光标位置)
            etUsername.requestFocus();
            return;
        }

        if (password.length() < 6) {
            tilPassword.setError("密码长度不能少于6位"); // 通过 TextInputLayout 显示错误
            etPassword.requestFocus();
            return;
        }

        // 校验通过,执行后续逻辑(如登录、提交)
        Toast.makeText(this, "输入校验通过", Toast.LENGTH_SHORT).show();
    }
}

四、样式定制(输入框背景、光标、错误样式)

1、自定义 EditText 背景(下划线 + 状态切换)

创建 Drawable 选择器(res/drawable/et_bg_selector.xml),实现「正常 / 获取焦点 / 禁用」状态切换:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 禁用状态 -->
    <item android:state_enabled="false">
        <layer-list>
            <item android:bottom="1dp">
                <shape android:shape="rectangle">
                    <solid android:color="#EEEEEE"/>
                </shape>
            </item>
        </layer-list>
    </item>
    <!-- 获取焦点状态 -->
    <item android:state_focused="true">
        <layer-list>
            <item android:bottom="1dp">
                <shape android:shape="rectangle">
                    <solid android:color="#2196F3"/> <!-- 蓝色下划线 -->
                </shape>
            </item>
        </layer-list>
    </item>
    <!-- 正常状态 -->
    <item>
        <layer-list>
            <item android:bottom="1dp">
                <shape android:shape="rectangle">
                    <solid android:color="#E0E0E0"/> <!-- 灰色下划线 -->
                </shape>
            </item>
        </layer-list>
    </item>
</selector>

2、自定义光标样式

通过 drawable 定义光标形状(res/drawable/cursor_shape.xml):

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#2196F3"/> <!-- 光标颜色 -->
    <size android:width="2dp"/> <!-- 光标宽度 -->
</shape>

在 XML 中引用:

<EditText
    ...
    android:cursorDrawable="@drawable/cursor_shape"/>

五、进阶功能(输入限制、格式格式化、防抖)

1、 输入格式限制(如手机号:3-4-4 分隔)

通过 TextWatcher 监听输入变化,自动添加分隔符(示例:138-0000-0000):

EditText etPhone = findViewById(R.id.et_phone);
etPhone.addTextChangedListener(new TextWatcher() {
    private boolean isFormatting = false; // 避免递归触发

    @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) {
        if (isFormatting) return;
        isFormatting = true;

        // 移除已有的分隔符
        String str = s.toString().replace("-", "");
        // 超过11位截取前11位(手机号长度)
        if (str.length() > 11) {
            str = str.substring(0, 11);
        }

        // 插入分隔符:3位后加-,7位后加-
        StringBuilder sb = new StringBuilder(str);
        if (sb.length() > 3) {
            sb.insert(3, "-");
        }
        if (sb.length() > 8) {
            sb.insert(8, "-");
        }

        // 设置格式化后的文本
        etPhone.setText(sb.toString());
        // 移动光标到末尾
        etPhone.setSelection(sb.length());

        isFormatting = false;
    }
});

2、禁止输入空格(或特定字符)

通过 InputFilter 过滤空格:

// 禁止输入空格
InputFilter filter = (source, start, end, dest, dstart, dend) -> {
    if (source.toString().contains(" ")) {
        return source.toString().replace(" ", ""); // 替换空格为空
    }
    return null; // 允许输入
};

etUsername.setFilters(new InputFilter[]{filter, new InputFilter.LengthFilter(20)}); // 结合长度限制

3、 输入防抖(避免频繁校验)

类似 Button 防抖,避免输入时实时校验过于频繁:

private long lastCheckTime = 0;
private static final long CHECK_INTERVAL = 300; // 300ms 校验一次

etPassword.addTextChangedListener(new TextWatcher() {
    @Override
    public void afterTextChanged(Editable s) {
        long currentTime = System.currentTimeMillis();
        if (currentTime - lastCheckTime < CHECK_INTERVAL) {
            return;
        }
        lastCheckTime = currentTime;
        // 执行校验逻辑(如密码强度检测)
        checkPasswordStrength(s.toString());
    }

    // 其他方法省略...
});

// 密码强度检测示例
private void checkPasswordStrength(String password) {
    if (password.length() < 6) {
        tilPassword.setHelperText("密码强度:弱");
        tilPassword.setHelperTextColor(Color.parseColor("#FF0000"));
    } else if (password.length() < 10) {
        tilPassword.setHelperText("密码强度:中");
        tilPassword.setHelperTextColor(Color.parseColor("#FF9800"));
    } else {
        tilPassword.setHelperText("密码强度:强");
        tilPassword.setHelperTextColor(Color.parseColor("#4CAF50"));
    }
}

以上就是我们的核心功法啦!我们下期再见!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值