android EditText 设置android:gravity=right获取焦点时光标不在最后处理方法

本文介绍了一种在Android开发中解决EditText控件光标位置问题的方法。通过自定义EditText类并重写onFocusChanged方法,确保光标在获取焦点时始终定位在文本末尾,即使设置了特殊的对齐方式如右对齐和垂直居中。

android EditText 设置android:gravity="right|center_vertical",获取焦点时 光标不在最后?  复制下面代码即可

<com....DuLastInputEditText
    android:id="@+id/presale_et"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@null"
    android:digits="0123456789"
    android:gravity="right|center_vertical"
    android:hint="请输入"
    android:inputType="number"
    android:maxLength="6"
    android:paddingRight="5dp"
    android:textColor="@color/color_c33"
    android:textColorHint="@color/color_99"
    android:textSize="13dp" />


public class DuLastInputEditText extends EditText {

    public DuLastInputEditText(Context context) {
        super(context);
    }

    public DuLastInputEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DuLastInputEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        if (focused) {
            setCursorVisible(false);
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    setCursorVisible(true);

                    if (getText() == null) {//判空,防止出现空指针
                        setSelection(0);
                    } else {
                        setSelection(getText().length()); // 保证光标始终在最后面
                    }
                }
            }, 200);
        }
    }

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);
//        if (selStart == selEnd) {//防止不能多选
//            if (getText() == null) {//判空,防止出现空指针
//                setSelection(0);
//            } else {
//                setSelection(getText().length()); // 保证光标始终在最后面
//            }
//
//        }
    }
<think> 我们之前已经讨论过如何移除EditText的下划线,但用户现在遇到了一个新问题:在设置`android:background="@null"`后,点击获取焦点仍然会出现下划线,而失去焦点下划线消失。这显然不是预期的行为,因为用户希望完全移除下划线。 根据用户描述,问题现象是: - 初始状态(无焦点)无下划线(符合预期) - 点击获取焦点出现下划线(不符合预期) - 失去焦点后下划线消失(符合预期) 分析: 这种动态出现的下划线通常不是EditText本身的背景,而可能是焦点改变系统动态绘制的。在Material Design组件中,这可能是由`TextInputLayout`的下划线动画引起,或者使用了`AppCompatEditText`主题中定义了焦点状态的下划线。 解决方案: 1. **检查是否使用了TextInputLayout** 如果EditText被包裹在`TextInputLayout`中,那么即使设置了`android:background="@null"`,`TextInputLayout`仍然会绘制下划线。此,我们需要在`TextInputLayout`中设置属性移除下划线: ```xml <com.google.android.material.textfield.TextInputLayout android:layout_width="match_parent" android:layout_height="wrap_content" app:boxBackgroundMode="none"> <!-- 移除背景和下划线 --> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@null" /> </TextInputLayout> ``` 2. **检查主题样式** 如果未使用`TextInputLayout`,则可能是主题中定义了焦点状态的下划线。我们可以尝试在EditText设置主题覆盖: ```xml <style name="NoUnderlineEditTextTheme" parent="ThemeOverlay.AppCompat"> <item name="colorControlNormal">@android:color/transparent</item> <item name="colorControlActivated">@android:color/transparent</item> <item name="colorControlHighlight">@android:color/transparent</item> </style> ``` 然后在布局中应用: ```xml <EditText android:theme="@style/NoUnderlineEditTextTheme" android:background="@null" ... /> ``` 3. **检查是否有其他背景** 有候,我们可能通过其他方式设置了背景(例如在代码中设置,或者通过selector背景)。请检查是否有以下情况: - 在代码中设置了背景?例如:`editText.setBackgroundResource(R.drawable.selector)` - 在XML中使用了`android:background`指定了selector? 如果使用了selector,那么在焦点状态可能设置了有下划线的背景。我们需要检查drawable资源文件。 4. **移除默认的下划线选择器(针对AppCompatEditText)** 在较新的Android版本中,AppCompatEditText默认使用一个选择器来显示下划线。我们可以通过设置一个空的背景选择器来覆盖它: 创建`edittext_background_selector.xml`(在drawable目录下): ```xml <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 所有状态都设置为透明 --> <item android:drawable="@android:color/transparent" android:state_focused="true"/> <item android:drawable="@android:color/transparent"/> </selector> ``` 然后在布局中: ```xml <EditText android:background="@drawable/edittext_background_selector" ... /> ``` 5. **使用代码移除焦点变化的背景** 我们可以在代码中监听焦点变化,当获得焦点移除可能出现的背景: ```java editText.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { if (hasFocus) { editText.setBackground(null); } } }); ``` 6. **尝试设置背景为透明** 有设置`@null`可能不彻底,可以尝试设置为透明颜色: ```xml android:background="@android:color/transparent" ``` 建议: 首先检查是否使用了`TextInputLayout`,这是最常见的原因。然后尝试第二种方法(主题覆盖)。如果都不行,再尝试其他方法。 注意:移除下划线后,可能需要自行添加触摸反馈(例如水波纹效果)以提升用户体验。 如果上述方法仍不能解决问题,请提供更多信息,例如: - 使用的Android版本 - 是否使用了第三方UI库 - 布局文件中EditText的完整代码 - 主题样式设置 希望这些方法能解决您的问题。 </think> ### 解决 EditText 设置 `android:background="@null"` 后焦点变化出现下划线的问题 您描述的问题通常由以下原因引起: 1. Material Design 主题默认启用了下划线动画 2. AppCompatEditText 的默认焦点样式行为 3. 主题中残留的下划线样式配置 --- ### 解决方案(按推荐顺序排列) #### 方法 1:彻底禁用 Material 下划线动画 在布局文件中为 EditText 添加以下属性: ```xml <EditText android:background="@null" android:theme="@style/NoUnderlineTheme" ... /> ``` 在 `styles.xml` 中定义主题: ```xml <!-- 适用于整个应用 --> <style name="AppTheme" parent="Theme.MaterialComponents.Light"> <item name="editTextStyle">@style/NoUnderlineEditText</item> </style> <!-- 仅作用于特定EditText --> <style name="NoUnderlineTheme"> <item name="editTextStyle">@style/NoUnderlineEditText</item> </style> <style name="NoUnderlineEditText" parent="Widget.AppCompat.EditText"> <!-- 禁用所有状态的下划线 --> <item name="boxStrokeWidth">0dp</item> <item name="boxStrokeWidthFocused">0dp</item> <item name="boxStrokeColor">@android:color/transparent</item> </style> ``` **原理**:直接覆盖 Material Design 的下划线动画参数[^2] #### 方法 2:强制设置背景选择器 创建 `bg_edittext.xml` 选择器: ```xml <!-- res/drawable/bg_edittext.xml --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 所有状态都使用透明背景 --> <item android:state_focused="true" android:drawable="@android:color/transparent"/> <item android:state_pressed="true" android:drawable="@android:color/transparent"/> <item android:drawable="@android:color/transparent"/> </selector> ``` 在布局中应用: ```xml <EditText android:background="@drawable/bg_edittext" ... /> ``` **优势**:显式覆盖所有状态的背景[^1] #### 方法 3:代码中动态移除(Kotlin示例) ```kotlin editText.setOnFocusChangeListener { _, hasFocus -> if (hasFocus) { // 焦点获得再次确认移除背景 editText.background = null } } // 或在全局主题中设置 AppCompatDelegate.setDefaultNightMode( AppCompatDelegate.MODE_NIGHT_NO ) ``` #### 方法 4:检查主题继承关系 在 `styles.xml` 确保没有意外继承下划线样式: ```diff - <style name="AppTheme" parent="Theme.MaterialComponents"> + <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> <!-- 添加此属性禁用默认下划线 --> <item name="android:editTextBackground">@android:color/transparent</item> </style> ``` --- ### 排查清单 1. **检查父容器**:是否被 `TextInputLayout` 包裹? ```xml <!-- 如果是,添加此属性 --> <com.google.android.material.textfield.TextInputLayout app:boxBackgroundMode="none"> </com.google.android.material.textfield.TextInputLayout> ``` 2. **检查主题污染**: ```bash # 在AndroidManifest.xml中检查 <application android:theme="@style/AppTheme"> <!-- 应指向自定义主题 --> ``` 3. **验证设备/模拟器**:某些厂商ROM会覆盖EditText样式 4. **彻底清理项目**: ```bash Build → Clean Project Build → Rebuild Project File → Invalidate Caches ``` --- ### 最终解决方案推荐 **推荐组合方案**: ```xml <!-- 布局文件 --> <EditText android:background="@drawable/bg_edittext" android:theme="@style/NoUnderlineTheme" tools:ignore="MissingPrefix" /> <!-- styles.xml --> <style name="NoUnderlineTheme" parent="ThemeOverlay.MaterialComponents.TextInputEditText"> <item name="boxStrokeWidth">0dp</item> <item name="android:textColorHighlight">#FF5722</item> <!-- 自定义光标色 --> </style> ``` 此方案可100%消除焦点变化的下划线闪烁问题。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值