2011-07-13 16 views
32

Solo quiero cuando haga clic fuera del "texto de edición" para perder automáticamente el foco y ocultar el teclado. Por el momento, si hago clic en "editar texto", se enfoca, pero necesito presionar el botón Atrás para desenfocar.Toque fuera del texto de edición para perder el foco

+0

Pregunta relacionada: http://stackoverflow.com/q/4165414/782870. Creo que la mayoría de las respuestas ya han sido probadas y se ha encontrado que están funcionando. – vida

+0

Encontré esta respuesta: http://stackoverflow.com/a/28939113/2610855 La mejor. – Loenix

Respuesta

15

Supongamos que EditText se coloca en diseño lineal u otro ViewGroup. Luego debe hacer que este contenedor sea seleccionable, enfocable y enfocable en modo táctil. Después de que el conjunto OnClickListener a este contenedor con el código siguiente en el método de anulación onClick:

@Override 
public void onClick(View view) { 
    InputMethodManager imm = (InputMethodManager) view.getContext() 
      .getSystemService(Context.INPUT_METHOD_SERVICE); 
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0); 
} 
+1

En mi caso, estoy mostrando un teclado numérico en el foco del campo de texto. Traté de usar tu solución. Cuando hago clic en la vista de fondo, el teclado numérico se convierte en el teclado AlphaNumeric y luego, cuando hago clic de nuevo, desaparece. –

13

@woodshy tiene la respuesta para ocultar el teclado, pero tal vez poner el código en onClick no es tan bueno como su puesta en onFocusChanged. En cuanto a lo que obligó a perder el foco, es necesario establecer el objeto que desea transferir el foco a, en su archivo XML:

android:focusable="true" 
android:focusableInTouchMode ="true" 
+0

¿Puedo tener una pregunta relacionada con esta pregunta? ¿Quiere decir que este código debe aparecer en LinearLayout o EditText que quiero desenfocar? Gracias. – detno29

+0

Debe ponerlo como atributo de la vista principal (vista de contenido de su actividad). Es posible que desee comprobar esto: http://stackoverflow.com/a/19828165/782870 – vida

-5

tuve el mismo requisito que tenía que ocultar el teclado una vez que toco en cualquier parte fuera de mi cuadro Editar texto. El setOnFocusChangeListener no hace el trabajo, ya que incluso si toca fuera del cuadro de texto de edición todavía está seleccionado.

Para esto utilicé la solución edc598 here.

  • Primero recibí el MainLayout que contenía toda la vista y le agregué el detector de pulsaciones.
  • Cuando se activó el evento onTouch, verifico si el cuadro EditText tiene foco.
  • Si el cuadro Editar texto tiene un foco, entonces verifico las coordenadas X-Y del evento.
  • Sobre la base de la ubicación de mi caja EditarTexto que ocultar el teclado si se toca en cualquier lugar fuera del cuadro de muestra

código modificado de here:

LinearLayout MainLayout = (LinearLayout) findViewById(R.id.MainLayout); 
EditText textBox  = (EditText) findViewById(R.id.textBox); 
int X_TOP_LEFT  = 157; 
int Y_TOP_LEFT  = 388; 
int X_BOTTOM_RIGHT = 473; 
int Y_BOTTOM_RIGHT = 570; 
MainLayout.setOnTouchListener(new View.OnTouchListener() { 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     // TODO Auto-generated method stub 
     if(textBox.isFocused()){ 

      Log.i("Focussed", "--" + event.getX() + " : " + event.getY() + "--"); 

      if(event.getX() <= 157 || event.getY() <= 388 || event.getX() >= 473 || event.getY() >= 569){ 
       //Will only enter this if the EditText already has focus 
       //And if a touch event happens outside of the EditText 
       textBox.clearFocus(); 
       InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); 
       imm.hideSoftInputFromWindow(v.getWindowToken(), 0); 
       //Do something else 
      } 
     } 
     Log.i("X-Y coordinate", "--" + event.getX() + " : " + event.getY() + "--"); 
    //Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show(); 
     return false; 
    } 
}); 
+32

amigo, tienes que estar bromeando con estos números mágicos ... –

+0

Definitivamente no es necesario comprobar los límites ya que EditText comerá los eventos táctiles. – pstoppani

1

así que busqué alrededor de un poco, y ninguna otra solución era exactamente lo que estaba buscando. En mi opinión, el enfoque se comporta de manera extraña en las vistas de EditText.

Lo que hice fue ...

  1. Asegúrese de que la raíz es una vista RelativeLayout

  2. Añadir un diseño de plantilla que está sobre el área que hará que el disapear teclado, pero no el Editar texto. Algo parecido a continuación:

En mi caso, el EditarTexto estaba en un recipiente en la parte inferior de la pantalla. entonces cubrió todo lo demás.

  1. tener un método que se ve un poco como esta:
 
    private void hideKeyboard() { 
     final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); 
     keyboardOverlay.setVisibility(View.GONE); 
     editText.clearFocus(); 
    } 
  1. Ahora llamar a este método en el onClick de la superposición que creaste

  2. Lo que queremos ahora es hacer que la superposición sea visible cuando presiona EditText. No puede usar el evento onFocus (al menos no lo hice funcionar ...) Entonces, lo que hice fue administrar el evento onTouch.

 
editText.setOnTouchListener(new OnTouchListener() { 

    @Override 
    public boolean onTouch(final View v, final MotionEvent event) { 
     keyboardOverlay.setVisibility(View.VISIBLE); 
     editText.requestFocus(); 
     return false; 
    } 
}); 

El requestFocus() aquí es no anular el evento de enfoque con el onTouch.

Consejo rápido, cuando pruebe esto, puede agregar un color de fondo a la superposición para ver exactamente lo que está sucediendo.

Espero que te sirva!

+0

¿Alguna mejor manera de hacer eso? – Gohan

11

Para resolver este problema lo que tiene que hacer es el primer uso setOnFocusChangeListener de ese EDITTEXT

edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() { 
      @Override 
      public void onFocusChange(View v, boolean hasFocus) { 
       if (!hasFocus) { 
        Log.d("focus", "focus loosed"); 
        // Do whatever you want here 
       } else { 
        Log.d("focus", "focused"); 
       } 
      } 
     }); 

y luego lo que hay que hacer es anular dispatchTouchEvent en la actividad que contiene ese EDITTEXT véase a continuación Código

@Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      View v = getCurrentFocus(); 
      if (v instanceof EditText) { 
       Rect outRect = new Rect(); 
       v.getGlobalVisibleRect(outRect); 
       if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { 
        Log.d("focus", "touchevent"); 
        v.clearFocus(); 
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0); 
       } 
      } 
     } 
     return super.dispatchTouchEvent(event); 
    } 

Ahora, lo que sucederá es que cuando un usuario haga clic en el exterior, primero se llamará a este dispatchTouchEvent, que luego borrará el foco del texto editado, ahora se llamará a OnFocusChangeListener y se cambiará el foco, ahora él re puede hacer cualquier cosa que desee hacer, espero que funcione :)

+0

Me gusta este método. Además, agregue 'android: focusable =" true "' and 'android: focusableInTouchMode =" true "' en el diseño del padre directo de 'editText'. –

+0

'focus loosed' debe ser' focus losted') – Stack

0

El siguiente código funciona perfectamente para mí, y lo uso regularmente para cerrando el SoftKeyboard onTouch en cualquier lugar fuera de EditText.

public void hideSoftKeyboard() 
{ 
     //Hides the SoftKeyboard 
     InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE); 
     inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0); 
} 

public void setupUI(View view) 
{ 
     String s = "inside"; 
     //Set up touch listener for non-text box views to hide keyboard. 
     if (!(view instanceof EditText)) { 

      view.setOnTouchListener(new View.OnTouchListener() { 

       public boolean onTouch(View v, MotionEvent event) { 
        hideSoftKeyboard(); 
        return false; 
       } 

      });   
     } 


    //If a layout container, iterate over children and seed recursion. 
     if (view instanceof ViewGroup) { 

      for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 

       View innerView = ((ViewGroup) view).getChildAt(i); 

       setupUI(innerView); 
      } 
     }  
} 

lo que sólo tiene que llamar a la función setupUI() una vez en su método y onCreate() voilla, su configuración es hidingSoftKeyboard!

Para Perdiendo el foco completo de EditText, simplemente haga editText.clearFocus() en su función hideSoftKeyboard().

0

Usted puede lograr esto haciendo los siguientes pasos:

1.make la vista padre (ver contenido de su actividad) se puede hacer clic y enfocable mediante la adición de los siguientes atributos

android:clickable="true" 
    android:focusableInTouchMode="true" 

2.Implement una hideKeyboard() método

public void hideKeyboard(View view) { 
     InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE); 
     inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); 
    } 

3.Lastly, establecer el onFocusChangeListener de su EditarTexto.

edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() { 
     @Override 
     public void onFocusChange(View v, boolean hasFocus) { 
      if (!hasFocus) { 
       hideKeyboard(v); 
      } 
     } 
    }); 
Cuestiones relacionadas