Android EditText 光标显示在结尾处问题

发布于 2022-09-07 08:53:36 字数 652 浏览 13 评论 0

需求

  1. 进入页面时,EditText不自动获取焦点(没有光标显示)
  2. 第一次点击EditText区域时,光标显示在结尾处,并且出现软键盘
  3. 第二次点击EditText指定位置,光标移动到指定位置,用户进行编辑

代码

  • 布局
<RelativeLayout
    android:focusable="false"
    android:focusableInTouchMode="true">
    
    <EditText android:background="@null" />
    
</RelativeLayout>

效果

  • 实现了 需求:1
  • 第一次点击EditText区域时,键盘显示,但是光标位置是用户点击的位置,不在结尾处,除非用户点击的位置就是结尾处。

问题

  • 如何实现 需求:2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

琉璃梦幻 2022-09-14 08:53:36

问题已经解决了

这个问题的 关键点setSelection() 方法的执行时机

先说下如何解决

  • 布局中不需要做任何多余的设置
<RelativeLayout
    <!-- 这两个设置不需要了,因为接下来要在程序总设定 -->
    android:focusable="false"
    android:focusableInTouchMode="true" />
    <EditText />
</RelativeLayout>
  • Java代码部分
public class MainActivity extends AppCompatActivity {
    private boolean isFirst = true; // 是否是第一次点击 EditText
    private InputMethodManager mIMM; // 第一次点击时,软键盘不自动弹出,所以要手动弹出
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mIMM = (InputMethodManager) (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
        mEditText = findViewById(R.id.xxx);
        
        // 关键部分
        mEditText.setFocusable(false);
        mEditText.setOnClickListener( v -> {
            if(isFirst) {
                mEditText.setFocusableInTouchMode(true);
                mEditText.requestFocus();
                mEditText.setSelection(mEditText.getText().length());
                mIMM.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
                isFirst = false;
            }
        });
    }
}

再说下尝试的过程

1. 直接设置 setSelection()

因为之前设置了 android:focusabelInTouchMode="true",所以直接设置是没有效果的,第一次点击EditText区域,会自动弹出软键盘,并且光标位置是手指点击的位置

2. 自定义 EditText,重写 onSelectionChanged(int selStart, int selEnd)方法

这个方法感知光标位置的变化,编写如下代码,可控制光标始终在结尾处:

    @Override
    protected void onSelectionChanged(int selStart, int selEnd) {
        super.onSelectionChanged(selStart, selEnd);
            if (selStart == selEnd) { // 不考虑多个文字被选中
                setSelection(getText().length());
            }
    }

这个方法的执行时机在自定义EditText对象初始化之前,并且在没点击之前,或者点击时会多次执行该方法,不好控制是否是第一次点击。因此也没有尝试成功

总结

不知道有没有更好的解决方案?期待你的回答。


2018-05-28 补充

实际项目总可能会遇到一个页面中有多个EditText,那么 isFirstTouch 就可能被多个EditText共用,如果有这个问题存在的话,一种解决方案是自定义EditText:

public class MyEditText extends EditText {
    private boolean isFirstTouch = true;
    // 构造方法中调用 init() 方法
    private void init() {
        post( () -> {
            setFocusable(false);
            if(isFirst) {
                setFocusableInTouchMode(true);
                requestFocus();
                setSelection(mEditText.getText().length());
                inputMethodManger.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
                isFirst = false;
            }
        });
    }
}
另类 2022-09-14 08:53:36

EditText有个setSelection方法,应该可以满足你的需求

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文