Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android: How to get text position from touch event

I'm wanting to implement a custom text interface, with touch+drag selecting text and the keyboard not being raised, in contrast to the default behavior of a long-click bringing up the CCP menu and the keyboard. My understanding suggests I need this approach:

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

  case drag
    get END text position
    set selection range from START to END
}

I've found out all about getSelectStart() and various methods to setting a range and such, but I cannot find how to get the text position based on a touch event getX() and getY(). Is there any way to do this? I've seen the behaviour I want in other office apps.

Also, how would I stop the keyboard appearing until manually requested?

like image 586
Tickled Pink Avatar asked Apr 21 '12 21:04

Tickled Pink


2 Answers

I'm facing the same issue too. And when I tried to use "int offset = layout.getOffsetForHorizontal(0, x);" like Wayne Kail said, also got NPE in this line. So I tried and in the end write like this:

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); 
like image 72
Ethan Zhong Avatar answered Oct 18 '22 15:10

Ethan Zhong


Thanks Waine Kail for sharing the start code, but it only handled the "x" axis of the event. For multiline EditText, you also must:

1- Calculate the vertical position (y):
2- Get the line offset by the vertical position
3- Get the text offset using the line and horizontal position

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;
}
});
like image 28
Sergio Abreu Avatar answered Oct 18 '22 17:10

Sergio Abreu