You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Java登录页EditText仅显单个字符问题排查求助

Android 9/8设备EditText输入异常问题分析

问题现象

  • 部分Android 9和8设备上,用户名输入框仅能显示单个字符,输入第二个字符时第一个会消失
  • 光标移至左侧输入时,字符串反转显示(如输入hello显示olleh)
  • 密码输入框功能完全正常

布局与代码示例

用户名输入框布局

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/userWrapper"
    style="@style/MessageError"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:layout_marginTop="2dp"
    android:textAlignment="center"
    android:layout_marginBottom="5dp"
    android:gravity="center_horizontal">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
    <EditText
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:id="@+id/user_edit_text"
        android:hint="Name"
        android:background="@drawable/custom_input"
        android:padding="10dp"
        android:paddingStart="20dp"
        />
    <ImageButton
        android:id="@+id/clean"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_alignParentRight="true"
        android:src="@drawable/ic_baseline_cancel_24"
        android:layout_centerVertical="true"
        android:layout_marginTop="2dp"
        android:layout_marginLeft="-40dp"
        android:background="@color/white_with_alpha"
        android:onClick="cleanText"
        android:visibility="gone"
        android:text="Button"/>
    </LinearLayout>
</com.google.android.material.textfield.TextInputLayout>

密码输入框布局

<com.google.android.material.textfield.TextInputLayout
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/passwordWrapper"
    style="@style/MessageError"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:gravity="center_horizontal"
    android:textAlignment="center"
    android:layout_marginTop="0dp"
    app:passwordToggleDrawable="@drawable/ic_password_visibility_selector"
    app:passwordToggleEnabled="true"
    app:passwordToggleTint="@color/grey"
    >
<EditText
    android:layout_width="300dp"
    android:layout_height="wrap_content"
    android:id="@+id/password_edit_text"
    android:layout_below="@+id/login"
    android:layout_marginTop="-10dp"
    android:hint="mot de passe"
    android:inputType="numberPassword"
    android:drawableEnd="@drawable/ic_eye_password"
    android:background="@drawable/custom_input_v3"
    android:padding="10dp"
    android:paddingStart="15dp"
    />
</com.google.android.material.textfield.TextInputLayout>

字符处理的TextWatcher代码

class myTextWatcher implements TextWatcher {
    int first = 0;
    int second;
    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void afterTextChanged(Editable editable) {
        second = first;
        first = editable.length();
        if(TextUtils.isEmpty(editable.toString())){
            clean.setVisibility(View.GONE);
        }else{
            clean.setVisibility(View.VISIBLE);
        }
        if(editable.length() == 5 && first>second){
            user_edit_text.append(".");
        }
        if(editable.length() == 5 && second>first){
            String newString = editable.toString();
            user_edit_text.setText(newString.substring(0,newString.length()-1));
        }
    }
}

问题根源

  1. TextWatcher循环回调导致文本状态混乱
    在afterTextChanged里直接调用user_edit_text.append()或setText(),会再次触发TextWatcher的回调,形成循环。Android 8/9的EditText系统实现对这种循环的兼容性较差,会引发字符覆盖、光标位置计算错误,最终出现输入字符消失、文本反转的问题。
  2. 状态判断逻辑不严谨
    用first和second两个变量判断输入/删除操作的逻辑太粗糙,无法应对光标位置变化的场景,比如用户在文本中间输入或删除时,会错误触发文本修改逻辑,导致显示异常。
  3. 布局对齐属性冲突
    用户名输入框嵌套在LinearLayout中,同时TextInputLayout设置了textAlignment="center"和gravity="center_horizontal",这些属性和EditText自身的文本对齐逻辑冲突,在部分系统版本中干扰了光标位置的计算,加重了输入异常。

修复建议

1. 重构TextWatcher,避免循环回调

直接操作Editable对象,添加锁防止循环触发,同时优化操作判断逻辑:

class myTextWatcher implements TextWatcher {
    private boolean isUpdating = false;
    private int lastLength = 0;

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

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

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void afterTextChanged(Editable editable) {
        if (isUpdating) return;
        isUpdating = true;

        // 控制清除按钮显示
        clean.setVisibility(TextUtils.isEmpty(editable) ? View.GONE : View.VISIBLE);

        int currentLength = editable.length();
        // 输入时添加点
        if (currentLength == 5 && currentLength > lastLength) {
            editable.append(".");
            // 手动设置光标到末尾
            user_edit_text.setSelection(editable.length());
        }
        // 删除时移除点
        else if (currentLength == 4 && currentLength < lastLength) {
            if (editable.length() > 0 && editable.charAt(editable.length() - 1) == '.') {
                editable.delete(editable.length() - 1, editable.length());
            }
        }

        lastLength = currentLength;
        isUpdating = false;
    }
}

2. 调整布局,移除冲突属性

移除嵌套的LinearLayout,把EditText直接放在TextInputLayout内,同时去掉TextInputLayout上的对齐属性,改用EditText自身的gravity设置文本对齐:

<com.google.android.material.textfield.TextInputLayout
    android:id="@+id/userWrapper"
    style="@style/MessageError"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true"
    android:layout_marginTop="2dp"
    android:layout_marginBottom="5dp">

    <EditText
        android:id="@+id/user_edit_text"
        android:layout_width="300dp"
        android:layout_height="wrap_content"
        android:hint="Name"
        android:background="@drawable/custom_input"
        android:padding="10dp"
        android:paddingStart="20dp"
        android:gravity="start"/>

    <ImageButton
        android:id="@+id/clean"
        android:layout_width="35dp"
        android:layout_height="35dp"
        android:layout_alignParentRight="true"
        android:src="@drawable/ic_baseline_cancel_24"
        android:layout_centerVertical="true"
        android:layout_marginTop="2dp"
        android:layout_marginLeft="-40dp"
        android:background="@color/white_with_alpha"
        android:onClick="cleanText"
        android:visibility="gone"
        android:text="Button"/>
</com.google.android.material.textfield.TextInputLayout>

内容的提问来源于stack exchange,提问作者Sed9dn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 10:45:27