android:如何从触摸事件中获取文本位置

Tic*_*ink 8 android selection android-edittext

我想要实现一个自定义文本界面,触摸+拖动选择文本和键盘没有被提升,这与长按一下CCP菜单和键盘的默认行为形成对比.我的理解表明我需要这种方法:

onTouchEvent(event){
  case touch_down:
    get START text position

  case drag
    get END text position
    set selection range from START to END
}
Run Code Online (Sandbox Code Playgroud)

我已经发现所有关于getSelectStart()以及设置范围等的各种方法,但我找不到如何根据触摸事件getX()和getY()获取文本位置.有没有办法做到这一点?我在其他办公应用程序中看到了我想要的行为.

另外,在手动请求之前,如何停止键盘出现?

Way*_*ail 12

"mText.setInputType(InputType.TYPE_NULL)"将禁止软键盘,但它也会禁用Android 3.0及更高版本下的EditText框中的闪烁光标.我编写了一个onTouchListener并返回true以禁用键盘,然后必须从motion事件中获取触摸位置以将光标设置为正确的位置.您可以在ACTION_MOVE运动事件中使用此选项来选择要拖动的文本.

这是我使用的代码:

  mText = (EditText) findViewById(R.id.editText1);
  OnTouchListener otl = new OnTouchListener() {
  @Override
  public boolean onTouch(View v, MotionEvent event) {
      switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
          Layout layout = ((EditText) v).getLayout();
          float x = event.getX() + mText.getScrollX();
          int offset = layout.getOffsetForHorizontal(0, x);
          if(offset>0)
              if(x>layout.getLineMax(0))
                  mText.setSelection(offset);     // touch was at end of text
              else
                  mText.setSelection(offset - 1);
          break;
          }
      return true;
      }
  };
  mText.setOnTouchListener(otl);
Run Code Online (Sandbox Code Playgroud)

  • 我在线上得到了空指针异常:::"int offset = layout.getOffsetForHorizo​​ntal(0,x);" (2认同)

Ser*_*reu 11

感谢Waine Kail分享开始代码,但它只处理了事件的"x"轴.对于多行 EditText,您还必须:

1-计算垂直位置(y):
2-通过垂直位置
获取线偏移3-使用直线和水平位置获取文本偏移

EditText et = (EditText) findViewById(R.id.editText1);

long offset = -1; //text position will be corrected when touching.

et.setOnTouchListener(new OnTouchListener() {

@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
      case MotionEvent.ACTION_UP:
          Layout layout = ((EditText) v).getLayout();
          float x = event.getX() + et.getScrollX();
          float y = event.getY() + et.getScrollY();            
          int line = layout.getLineForVertical((int) y);                      

 // Here is what you wanted:

          offset = layout.getOffsetForHorizontal( line,  x);

          break;
        }
    return false;
}
});
Run Code Online (Sandbox Code Playgroud)


小智 5

我也面临同样的问题.当我尝试使用"int offset = layout.getOffsetForHorizo​​ntal(0,x);"时 像Wayne Kail所说的那样,NPE也在这条线上.所以我尝试了,最后这样写:

mText = (EditText) findViewById(R.id.editText1);
OnTouchListener otl = new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
      EditText editText = (EditText) v;
      float x = event.getX();
      float y = event.getY();
      int touchPosition = editText.getOffsetForPosition(x, y);
      if (touchPosition>0){
          editText.setSelection(touchPosition);
      }
      return true;
    }
};
mText.setOnTouchListener(otl); 
Run Code Online (Sandbox Code Playgroud)