En EditText, aparece un diálogo al hacer clic en un subconjunto específico de texto

Encontró dos soluciones – vea la respuesta seleccionada

Cuando el usuario hace clic en una región determinada de un EditText, quiero mostrar un diálogo. Utilicé onClick para capturar el clic. Esto funciona parcialmente: la primera vez que el usuario toca el EditText, el teclado virtual aparece y el cuadro de diálogo no. Los golpes subsiguientes muestran el teclado y después el diálogo (y el teclado desaparece).

Sospecho que esto tiene algo que ver con el EditText ganando foco.

He aquí un recorte de código:

public class PrefixEditText extends EditText implements TextWatcher, OnClickListener { public PrefixEditText (Context context) { super (context); setOnClickListener (this); } @Override public void onClick(View v) { int selStart = getSelectionStart(); if (selStart < some_particular_pos) bring_up_dialog(); } } 

IMPORTANTE: No quiero desactivar completamente el comportamiento normal de EditText. Quiero que el usuario pueda hacer selecciones de región (para copiar y pegar). Probablemente todavía quiero que se enfoque (por lo que no romper el modelo cuando las personas con teclados físicos utilizar la aplicación). Y está bien para el clic para establecer la posición del cursor. Por lo tanto, las soluciones que anulan onTouch y bloquean todas las acciones onTouch del EditText no funcionarán para mí.

ACTUALIZACIÓN He descubierto un poco más. Si EditText está ganando el foco, onFocusChange se llama y onClick no. Si ya tiene foco, onClick se llama y onFocusChange no.

En segundo lugar, es posible ocultar el teclado llamando

 setInputType (InputType.TYPE_NULL); 

Hacerlo en onFocusChange funciona: el teclado nunca aparece. Hacerlo en onClick (suponiendo que el teclado estaba oculto antes del clic) aparentemente es demasiado tarde – el teclado aparece y luego desaparece.

La siguiente idea para intentar sería ocultar el teclado durante onTouch. Sin embargo, tengo miedo de meterse con ese código – parece que lo que descubro sería muy frágil con respecto a futuras versiones de EditText.

Cualquier thoughs en esto?

Intente cambiar captura haga clic en onClick to onTouch

  this.editText.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { //dialogue popup } return false; } }); 

Puede que esto pueda funcionar

  EditText e = new EditText(context); e.setOnFocusChangeListener(new OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { // TODO Auto-generated method stub if(hasFocus) { //dialogue popup } } }); 

U puede utilizar e.hasFocus(); Y luego use e.setFocusable(false); Para hacerla desenfocar

/////////////// mi código

 e.setInputType(InputType.TYPE_NULL); e.setOnClickListener(new OnClickListener() { public void onClick(View v) { // TODO Auto-generated method stub AlertDialog.Builder sa = new Builder(ctx); sa.create().setOnDismissListener(new OnDismissListener() { public void onDismiss(DialogInterface dialog) { // TODO Auto-generated method stub e.setInputType(InputType.TYPE_CLASS_TEXT); } }); sa.show(); } }); 

Intente esto si puede ayudar u.primera vez que el edittext se comportará como un editttext normal y en la condición u puede demostrar el diálogo según lo necesitado

  EditText editText; mTim_edittext.setOnFocusChangeListener(new OnFocusChangeListener() { public void onFocusChange(View v, boolean hasFocus) { if(!hasFocus){ //statement if(condition){ AlertDialog diaBox = Utils.showErrorDialogBox( "Term in Months Cannot be 0", context); diaBox.show(); } } } }); 

Después de un montón de experimentos, aquí hay dos soluciones de trabajo! Los probé en mis dos dispositivos – Nexus 7 que funciona 4.2.1, Kyocera C5170 runing 4.0.4. Mi preferencia es la Solución 2.

SOLUCIÓN 1

Para el primero, el truco era determinar la posición del cursor en onTouch en lugar de onClick, antes de que EditText tuviera la oportunidad de hacer su trabajo – en particular antes de que aparezca el teclado.

Un comentario adicional: asegúrese de establecer android: windowSoftInputMode = "stateHidden" en su manifiesto para el popup, o obtendrá el teclado junto con el popup.

Aquí está el código completo:

 public class ClickText extends EditText implements OnTouchListener { public ClickText (Context context, AttributeSet attrs) { super (context, attrs); setOnTouchListener (this); } @Override public boolean onTouch (View v, MotionEvent event) { if (event.getActionMasked() == MotionEvent.ACTION_DOWN) { int line = getLayout().getLineForVertical ((int)event.getY()); int onTouchCursorPos = getLayout().getOffsetForHorizontal (line, event.getX()); if (onTouchCursorPos < 10) // or whatever condition showPopup (this); // or whatever you want to do } return false; } private void showPopup (final EditText text) { Intent intent = new Intent (getContext(), Popup.class); ((Activity)getContext()).startActivity (intent); } } 

SOLUCIÓN 2

Este es en realidad más simple y, creo, es mejor – menos efectos secundarios.

Aquí, el truco es dejar que EditText hacer todo su clic de procesamiento y luego anularlo asincrónicamente. La esencia es: esperar a que el tacto de "dejar ir" – MotionEvent.ACTION_UP – y luego en lugar de hacer su acción en ese momento, publicar un Runnable a la cola de eventos y hacer su acción allí.

El código completo:

 public class ClickText extends EditText implements OnTouchListener { public ClickText (Context context, AttributeSet attrs) { super (context, attrs); setOnTouchListener (this); } @Override public boolean onTouch (View v, MotionEvent event) { switch (event.getActionMasked()) { case MotionEvent.ACTION_UP: { post (new Runnable () { // Do this asynch so that EditText can finish setting the selectino. @Override public void run() { int selStart = getSelectionStart(); int selEnd = getSelectionEnd(); // If selStart is different than selEnd, user has highlighed an area of // text; I chose to ignore the click when this happens. if (selStart == selEnd) if (selStart >= 0 && selStart < 10) // or whatever range you want showPopup (this); } }); break; } } return false; } private void showPopup (final EditText text) { Intent intent = new Intent (getContext(), Popup.class); ((Activity)getContext()).startActivity (intent); } } 
  • ¿Cómo puedo mantener los eventos de ontouch manejados por un widget incluso si las coordenadas de tacto ya no están dentro del widget, en android
  • onTouchEvent () of Activity se dispara 3 veces?
  • Android ACTION_UP incluso nunca se llama
  • Android (singletouch) aplicación de dibujo método de deshacer no funciona correctamente
  • Manejo del evento de toque Intercept sin extender ViewGroup
  • Cómo detectar un solo toque, así como multi-toque en onTouchEvent ()
  • Android dibuja una línea para seguir tu dedo
  • Android - Detectar Fin de Prensa Larga
  • OnTouchListener de una vista vs onTouchEvent
  • Android - ¿Cómo circular zoom / ampliar parte de la imagen?
  • ¿Cómo puedo arrastrar y soltar varias vistas de imagen sobre otras vistas de imagen de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.