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.
- Selección de Android Spinner
- Android: smoothScrollToPosition () no funciona correctamente
- ¿Qué es el modo de selección de selección modal?
- Cómo obtener texto y valor seleccionados Android ListPreference
- Detección de cambios de selección en WebView
Además, ¿cómo puedo detener el teclado que aparece hasta que se solicite manualmente?
- Los identificadores de selección no aparecen en WebView (Android 4.0-4.3)
- ¿Cómo seleccionar un elemento ListView después de un clic largo?
- Cómo utilizar Android Spinner como una lista desplegable
- Establecer un color de fondo en un elemento ListView seleccionado en android
- Selección de texto de Webview no borrada
- Obtener la aplicación seleccionada de Intent.createChooser
- Programatically fuego barra de acción elemento de menú en Android
- ¿Cómo se puede cambiar el widget de selección de texto en pantalla?
"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; } });
- ¿Cómo comprueba si un botón está habilitado o no en Android?
- Obtener directo Vimeo video url Android