Android输入框光标无法移至行尾问题及系统修改方案咨询
解决Android 11多行EditText光标无法移至行尾的系统级修改方案
问题根源
Android原生StaticLayout(负责文本排版的核心类)的光标定位逻辑默认仅将点击位置映射到最近的字符偏移,未处理行尾空白区域的点击场景,导致点击行尾时光标停在最后一个字符的起始位置。
系统级修改步骤
定位源码文件
打开Android 11源码中的frameworks/base/core/java/android/text/StaticLayout.java修改
getOffsetForHorizontal方法
找到该方法,在原有逻辑基础上添加行尾判断,当点击位置超过当前行的总宽度时,直接返回行尾偏移:@Override public int getOffsetForHorizontal(int line, float x) { // 保留原有字符偏移计算逻辑 int offset = super.getOffsetForHorizontal(line, x); int lineEnd = getLineEnd(line); float lineWidth = getLineWidth(line); // 若点击位置在行尾空白区域,返回行尾偏移 if (x >= lineWidth && offset < lineEnd) { return lineEnd; } return offset; }编译并替换系统框架
- 编译framework模块:执行
make framework(需配置好Android编译环境) - 将编译生成的
framework.jar替换到模拟器的系统分区,或直接刷入修改后的系统镜像
- 编译framework模块:执行
应用层替代方案(无需修改系统)
如果不想修改系统,可通过自定义EditText实现相同效果,重写onTouchEvent处理点击定位:
public class LineEndEditText extends AppCompatEditText { public LineEndEditText(Context context) { super(context); } public LineEndEditText(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { Layout layout = getLayout(); if (layout == null) return super.onTouchEvent(event); int line = layout.getLineForVertical((int) event.getY()); float touchX = event.getX() - getTotalPaddingLeft() - getScrollX(); float lineWidth = layout.getLineWidth(line); int lineEnd = layout.getLineEnd(line); if (touchX >= lineWidth) { setSelection(lineEnd); return true; } } return super.onTouchEvent(event); } }
内容的提问来源于stack exchange,提问作者happy
相关产品推荐
相关产品推荐

