Android: Cómo obtener la posición del texto desde el evento táctil

Estoy deseando implementar una interfaz de texto personalizada, con toque + arrastrar texto de selección y el teclado no se plantea, en contraste con el comportamiento predeterminado de un largo-hacer clic en el menú CCP y el teclado. Mi comprensión sugiere que necesito este enfoque:

onTouchEvent(event){ case touch_down: get START text position case drag get END text position set selection range from START to END } 

He descubierto todo acerca de getSelectStart () y varios métodos para establecer un rango y tal, pero no puedo encontrar cómo obtener la posición del texto basado en un evento táctil getX () y getY (). ¿Hay alguna manera de hacer esto? He visto el comportamiento que quiero en otras aplicaciones de oficina.

Además, ¿cómo puedo detener el teclado que aparece hasta que se solicite manualmente?

"MText.setInputType (InputType.TYPE_NULL)" suprimirá el teclado virtual pero también deshabilitará el cursor parpadeante en un cuadro EditText debajo de Android 3.0 y superior. He codificado un onTouchListener y devuelto true para desactivar el teclado y luego tuvo que obtener la posición de toque del evento de movimiento para poner el cursor en el lugar correcto. Es posible que pueda utilizar esto en un evento de movimiento ACTION_MOVE para seleccionar texto para arrastrar.

Aquí está el código que usé:

  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); 

Gracias Waine Kail por compartir el código de inicio, pero sólo manejó el eje "x" del evento. Para el EditText multilínea , también debe:

1- Calcular la posición vertical (y):
2- Obtener la línea desplazada por la posición vertical
3- Obtener el desplazamiento de texto utilizando la línea y la posición horizontal

 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; } }); 

Estoy enfrentando el mismo problema también. Y cuando traté de usar "int offset = layout.getOffsetForHorizontal (0, x);" Como dijo Wayne Kail , también consiguió NPE en esta línea. Así que lo intenté y al final escribo así:

 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); 

Para mi aplicación que necesitaba para obtener la posición dentro de un listener, pero la solución anterior parece no dar una ubicación precisa. Para mí, la mayoría de las veces estaba fuera de 1-2 caracteres en relación con el cursor de texto. El siguiente código resuelve esto. La clave para que esto funcione es usar post () para posponer el código hasta que se haya actualizado la posición del cursor. Así, la posición que obtengo está garantizada para estar de acuerdo con la de EditText, y el código es también más simple.

 setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent event) { if(event.getAction()==MotionEvent.ACTION_UP) { //At this point the selection has not been updated. So post an //event at the end of the event queue to check where cursor //has been moved post(new Runnable() { public void run() { Editable sb=getText(); int currentPos=getSelectionStart(); //TODO } }); } return false; } }); 
  • Android - obtener la selección de texto de EditText
  • Cómo obtener la selección de usuario de startActivityForResult (Intent.createChooser (fileIntent, "Abrir archivo utilizando ..."), APP_PICKED) ;?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.