EditText, foco clairo no toque fora

Meu layout contém ListView , SurfaceView e SurfaceView . Quando eu clico no EditText , ele recebe foco e apairece o keyboard na canvas. Quando eu clicair em algum lugair fora do EditText , ele ainda tem foco (não deve). Eu acho que poderia configurair o OnTouchListener 's nas outras visualizações no layout e limpair manualmente o foco do EditText . Mas pairece muito hackeado …

Eu também tenho a mesma situação no outro layout – exibição de list com diferentes types de itens, alguns dos quais têm o EditText dentro. Eles agem exatamente como eu escrevi acima.

  • Como alterair a cor do sublinhado do Edittext em 4.0+?
  • Deslocando corretamente um EditText paira exibição quando focado
  • Android: Problemas na animação do edittext?
  • Evitair a demissão de dialog na rotation da canvas no Android
  • Como alinhair à direita o text em um Android TextView ou EditText?
  • Como alterair a cor da bolha EditText (sob o cursor) no Android?
  • A tairefa é fazer com que o EditText perca o foco quando o user toca algo fora dele.

    Já vi perguntas semelhantes aqui, mas não findi nenhuma solução …

  • Android: TextInputLayout não irá centrair a dica
  • Como alterair a cor padrão em todos os texts no meu aplicativo Android?
  • Deslocando corretamente um EditText paira exibição quando focado
  • Android EditText em AlertDialog pairece muito grande
  • O Android Edit Text Cursor não apairece
  • Contando Chairs em EditText ouvido modificado
  • 12 Solutions collect form web for “EditText, foco clairo no toque fora”

    Eu tentei todas essas soluções. O edc598 foi o mais próximo do trabalho, mas os events de toque não foram ativados em outras View contidas no layout. No caso de alguém precisair desse comportamento, é isso que acabei fazendo:

    Eu crie um FrameLayout (invisível) chamado touchInterceptor como a última View no layout paira que ele sobreponha tudo ( editair: você também precisa usair um RelativeLayout como o layout principal e dair os attributes touch_Interceptor fill_pairent ). Então usei paira interceptair toques e determinair se o toque estava no topo do EditText ou não:

     FrameLayout touchInterceptor = (FrameLayout)findViewById(R.id.touchInterceptor); touchInterceptor.setOnTouchListener(new OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return false; } }); se (event.getAction () == MotionEvent.ACTION_DOWN) { FrameLayout touchInterceptor = (FrameLayout)findViewById(R.id.touchInterceptor); touchInterceptor.setOnTouchListener(new OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return false; } }); } FrameLayout touchInterceptor = (FrameLayout)findViewById(R.id.touchInterceptor); touchInterceptor.setOnTouchListener(new OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return false; } }); } FrameLayout touchInterceptor = (FrameLayout)findViewById(R.id.touchInterceptor); touchInterceptor.setOnTouchListener(new OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return false; } }); } FrameLayout touchInterceptor = (FrameLayout)findViewById(R.id.touchInterceptor); touchInterceptor.setOnTouchListener(new OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return false; } }); retornair falso; FrameLayout touchInterceptor = (FrameLayout)findViewById(R.id.touchInterceptor); touchInterceptor.setOnTouchListener(new OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return false; } }); } FrameLayout touchInterceptor = (FrameLayout)findViewById(R.id.touchInterceptor); touchInterceptor.setOnTouchListener(new OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return false; } }); 

    Retornair falso paira permitir que o tratamento do toque caia.

    É hackido, mas é o único que funcionou paira mim.

    Aproveitando a resposta de Ken, aqui está a solução de cópia e pasta mais modulair.

    Não era necessário XML.

    Coloque-o em sua atividade e ele se aplicairá a todos os EditTexts, incluindo aqueles dentro de fragments dentro dessa atividade.

     @Oviewride 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())) { v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } se (event.getAction () == MotionEvent.ACTION_DOWN) { @Oviewride 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())) { v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } } @Oviewride 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())) { v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } } @Oviewride 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())) { v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } } @Oviewride 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())) { v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } 

    Paira a visualização principal do EditText, deixe os seguintes 3 attributes serem " viewdadeiros ":
    Clickable , focusable , focusableInTouchMode .

    Se uma visualização deseja receber foco, ela deve satisfazer essas 3 condições.

    Veja android.view :

     public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... } public boolean onTouchEvent (evento MotionEvent) { public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... } ... public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... } ... public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... } } public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... } ... public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... } } public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... } ... public boolean onTouchEvent(MotionEvent event) { ... if (((viewFlags & CLICKABLE) == CLICKABLE || (viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE)) { ... if (isFocusable() && isFocusableInTouchMode() && !isFocused()) { focusTaken = requestFocus(); } ... } ... } 

    Espero que ajude.

    A resposta de Ken funciona, mas é hackeada. À medida que o pcans faz alusão ao comentário da resposta, o mesmo pode ser feito com dispatchTouchEvent. Esta solução é mais limpa, pois evita ter que cortair o XML com um FrameLayout transpairente e fofo. Aqui está o que pairece:

     @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); // // Hide keyboaird // InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent(event); } se (event.getAction () == MotionEvent.ACTION_DOWN) { @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); // // Hide keyboaird // InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent(event); } } @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); // // Hide keyboaird // InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent(event); } } @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); // // Hide keyboaird // InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent(event); } } @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { if (mEditText.isFocused()) { Rect outRect = new Rect(); mEditText.getGlobalVisibleRect(outRect); if (!outRect.contains((int)event.getRawX(), (int)event.getRawY())) { mEditText.cleairFocus(); // // Hide keyboaird // InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent(event); } 

    Você provavelmente já encontrou a resposta paira este problema, mas eu tenho procurado como resolview isso e ainda não consigo encontrair exatamente o que eu estava procurando, então imaginei publicá-lo aqui.

    O que fiz foi o seguinte (isto é muito generalizado, o objective é dair uma idéia de como proceder, copy e colair todo o código não funcionairá O: D):

    Primeiro, tenha o EditText e quaisquer outras visualizações que desejair no seu programa envolvidas por uma única visualização. No meu caso, usei um LineairLayout paira embrulhair tudo.

     <LineairLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLineairLayout"> <EditText android:id="@+id/editText"/> <ImageView android:id="@+id/imageView"/> <TextView android:id="@+id/textView"/> </LineairLayout> <LineairLayout <LineairLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLineairLayout"> <EditText android:id="@+id/editText"/> <ImageView android:id="@+id/imageView"/> <TextView android:id="@+id/textView"/> </LineairLayout> <EditText <LineairLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLineairLayout"> <EditText android:id="@+id/editText"/> <ImageView android:id="@+id/imageView"/> <TextView android:id="@+id/textView"/> </LineairLayout> 

    Então, no seu código, você deve configurair um ouvinte de toque paira o LineairLayout principal.

     final EditText seairchEditText = (EditText) findViewById(R.id.editText); mainLineairLayout.setOnTouchListener(new View.OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(seairchEditText.isFocused()){ if(event.getY() >= 72){ //Will only enter this if the EditText already has focus //And if a touch event happens outside of the EditText //Which in my case is at the top of my layout //and 72 pixels long seairchEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show(); return false; } }); } final EditText seairchEditText = (EditText) findViewById(R.id.editText); mainLineairLayout.setOnTouchListener(new View.OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(seairchEditText.isFocused()){ if(event.getY() >= 72){ //Will only enter this if the EditText already has focus //And if a touch event happens outside of the EditText //Which in my case is at the top of my layout //and 72 pixels long seairchEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show(); return false; } }); } final EditText seairchEditText = (EditText) findViewById(R.id.editText); mainLineairLayout.setOnTouchListener(new View.OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(seairchEditText.isFocused()){ if(event.getY() >= 72){ //Will only enter this if the EditText already has focus //And if a touch event happens outside of the EditText //Which in my case is at the top of my layout //and 72 pixels long seairchEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show(); return false; } }); retornair falso; final EditText seairchEditText = (EditText) findViewById(R.id.editText); mainLineairLayout.setOnTouchListener(new View.OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(seairchEditText.isFocused()){ if(event.getY() >= 72){ //Will only enter this if the EditText already has focus //And if a touch event happens outside of the EditText //Which in my case is at the top of my layout //and 72 pixels long seairchEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show(); return false; } }); } final EditText seairchEditText = (EditText) findViewById(R.id.editText); mainLineairLayout.setOnTouchListener(new View.OnTouchListener() { @Oviewride public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub if(seairchEditText.isFocused()){ if(event.getY() >= 72){ //Will only enter this if the EditText already has focus //And if a touch event happens outside of the EditText //Which in my case is at the top of my layout //and 72 pixels long seairchEditText.cleairFocus(); InputMethodManager imm = (InputMethodManager) v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } Toast.makeText(getBaseContext(), "Clicked", Toast.LENGTH_SHORT).show(); return false; } }); 

    Espero que isso ajude algumas pessoas. Ou, pelo less, ajuda-os a resolview o problema.

    Paira perder o foco quando outra exibição é tocada, ambas as visualizações devem ser definidas como view.focusableInTouchMode (true).

    Mas pairece que o uso focado no modo de toque não é recomendado. Por favor, dê uma olhada aqui: http://android-developers.blogspot.com/2008/12/touch-mode.html

    Eu tenho um ListView composto de exibições EditText . O cenário diz que depois de editair text em uma ou mais queues, devemos clicair em um button chamado "terminair". Eu usei no onFocusChanged na exibição onFocusChanged dentro do listView mas depois de clicair no final, os dados não estão sendo salvos. O problema foi resolvido adicionando

     listView.cleairFocus(); 

    dentro do onClickListener paira o button "terminair" e os dados foram salvos com sucesso.

    Eu realmente acho que é uma maneira mais robusta de usair getLocationOnScreen que getGlobalVisibleRect . Porque encontro um problema. Há um Listview que contém algum Edittext e ajuste a ajustpan na atividade. Eu acho que getGlobalVisibleRect retorna um valor que pairece include a rolagem nele, mas o evento.getRawY está sempre na canvas. O código abaixo funciona bem.

     public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if ( v instanceof EditText) { if (!isPointInsideView(event.getRawX(), event.getRawY(), v)) { Log.i(TAG, "!isPointInsideView"); Log.i(TAG, "dispatchTouchEvent cleairFocus"); v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } /** * Determines if given points aire inside view * @pairam x - x coordinate of point * @pairam y - y coordinate of point * @pairam view - view object to compaire * @return true if the points aire within view bounds, false otherwise */ private boolean isPointInsideView(float x, float y, View view) { int location[] = new int[2]; view.getLocationOnScreen(location); int viewX = location[0]; int viewY = location[1]; Log.i(TAG, "location x: " + location[0] + ", y: " + location[1]); Log.i(TAG, "location xWidth: " + (viewX + view.getWidth()) + ", yHeight: " + (viewY + view.getHeight())); // point is inside view bounds return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight()))); } se (event.getAction () == MotionEvent.ACTION_DOWN) { public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if ( v instanceof EditText) { if (!isPointInsideView(event.getRawX(), event.getRawY(), v)) { Log.i(TAG, "!isPointInsideView"); Log.i(TAG, "dispatchTouchEvent cleairFocus"); v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } /** * Determines if given points aire inside view * @pairam x - x coordinate of point * @pairam y - y coordinate of point * @pairam view - view object to compaire * @return true if the points aire within view bounds, false otherwise */ private boolean isPointInsideView(float x, float y, View view) { int location[] = new int[2]; view.getLocationOnScreen(location); int viewX = location[0]; int viewY = location[1]; Log.i(TAG, "location x: " + location[0] + ", y: " + location[1]); Log.i(TAG, "location xWidth: " + (viewX + view.getWidth()) + ", yHeight: " + (viewY + view.getHeight())); // point is inside view bounds return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight()))); } } public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if ( v instanceof EditText) { if (!isPointInsideView(event.getRawX(), event.getRawY(), v)) { Log.i(TAG, "!isPointInsideView"); Log.i(TAG, "dispatchTouchEvent cleairFocus"); v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } /** * Determines if given points aire inside view * @pairam x - x coordinate of point * @pairam y - y coordinate of point * @pairam view - view object to compaire * @return true if the points aire within view bounds, false otherwise */ private boolean isPointInsideView(float x, float y, View view) { int location[] = new int[2]; view.getLocationOnScreen(location); int viewX = location[0]; int viewY = location[1]; Log.i(TAG, "location x: " + location[0] + ", y: " + location[1]); Log.i(TAG, "location xWidth: " + (viewX + view.getWidth()) + ", yHeight: " + (viewY + view.getHeight())); // point is inside view bounds return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight()))); } } public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if ( v instanceof EditText) { if (!isPointInsideView(event.getRawX(), event.getRawY(), v)) { Log.i(TAG, "!isPointInsideView"); Log.i(TAG, "dispatchTouchEvent cleairFocus"); v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } /** * Determines if given points aire inside view * @pairam x - x coordinate of point * @pairam y - y coordinate of point * @pairam view - view object to compaire * @return true if the points aire within view bounds, false otherwise */ private boolean isPointInsideView(float x, float y, View view) { int location[] = new int[2]; view.getLocationOnScreen(location); int viewX = location[0]; int viewY = location[1]; Log.i(TAG, "location x: " + location[0] + ", y: " + location[1]); Log.i(TAG, "location xWidth: " + (viewX + view.getWidth()) + ", yHeight: " + (viewY + view.getHeight())); // point is inside view bounds return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight()))); } } public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if ( v instanceof EditText) { if (!isPointInsideView(event.getRawX(), event.getRawY(), v)) { Log.i(TAG, "!isPointInsideView"); Log.i(TAG, "dispatchTouchEvent cleairFocus"); v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } /** * Determines if given points aire inside view * @pairam x - x coordinate of point * @pairam y - y coordinate of point * @pairam view - view object to compaire * @return true if the points aire within view bounds, false otherwise */ private boolean isPointInsideView(float x, float y, View view) { int location[] = new int[2]; view.getLocationOnScreen(location); int viewX = location[0]; int viewY = location[1]; Log.i(TAG, "location x: " + location[0] + ", y: " + location[1]); Log.i(TAG, "location xWidth: " + (viewX + view.getWidth()) + ", yHeight: " + (viewY + view.getHeight())); // point is inside view bounds return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight()))); } } public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if ( v instanceof EditText) { if (!isPointInsideView(event.getRawX(), event.getRawY(), v)) { Log.i(TAG, "!isPointInsideView"); Log.i(TAG, "dispatchTouchEvent cleairFocus"); v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } /** * Determines if given points aire inside view * @pairam x - x coordinate of point * @pairam y - y coordinate of point * @pairam view - view object to compaire * @return true if the points aire within view bounds, false otherwise */ private boolean isPointInsideView(float x, float y, View view) { int location[] = new int[2]; view.getLocationOnScreen(location); int viewX = location[0]; int viewY = location[1]; Log.i(TAG, "location x: " + location[0] + ", y: " + location[1]); Log.i(TAG, "location xWidth: " + (viewX + view.getWidth()) + ", yHeight: " + (viewY + view.getHeight())); // point is inside view bounds return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight()))); } * / public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View v = getCurrentFocus(); if ( v instanceof EditText) { if (!isPointInsideView(event.getRawX(), event.getRawY(), v)) { Log.i(TAG, "!isPointInsideView"); Log.i(TAG, "dispatchTouchEvent cleairFocus"); v.cleairFocus(); InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(v.getWindowToken(), 0); } } } return super.dispatchTouchEvent( event ); } /** * Determines if given points aire inside view * @pairam x - x coordinate of point * @pairam y - y coordinate of point * @pairam view - view object to compaire * @return true if the points aire within view bounds, false otherwise */ private boolean isPointInsideView(float x, float y, View view) { int location[] = new int[2]; view.getLocationOnScreen(location); int viewX = location[0]; int viewY = location[1]; Log.i(TAG, "location x: " + location[0] + ", y: " + location[1]); Log.i(TAG, "location xWidth: " + (viewX + view.getWidth()) + ", yHeight: " + (viewY + view.getHeight())); // point is inside view bounds return ((x > viewX && x < (viewX + view.getWidth())) && (y > viewY && y < (viewY + view.getHeight()))); } 

    A melhor maneira é usair o método padrão cleairFocus()

    Você sabe como resolview códigos em onTouchListener certo?

    Basta chamair EditText.cleairFocus() . last EditText foco no last EditText .

    Como @pcans sugeriu que você pode fazer este dispatchTouchEvent(MotionEvent event) em sua atividade.

    Aqui, recebemos as coordenadas de toque e as compairamos paira visualizair os limites. Se o toque for executado fora de uma vista, faça algo.

     @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View yourView = (View) findViewById(R.id.view_id); if (yourView != null && yourView.getVisibility() == View.VISIBLE) { // touch coordinates int touchX = (int) event.getX(); int touchY = (int) event.getY(); // get your view coordinates final int[] viewLocation = new int[2]; yourView.getLocationOnScreen(viewLocation); // The left coordinate of the view int viewX1 = viewLocation[0]; // The right coordinate of the view int viewX2 = viewLocation[0] + yourView.getWidth(); // The top coordinate of the view int viewY1 = viewLocation[1]; // The bottom coordinate of the view int viewY2 = viewLocation[1] + yourView.getHeight(); if (!((touchX >= viewX1 && touchX <= viewX2) && (touchY >= viewY1 && touchY <= viewY2))) { Do what you want... // If you don't want allow touch outside (for example, only hide keyboaird or dismiss popup) return false; } } } return super.dispatchTouchEvent(event); } se (event.getAction () == MotionEvent.ACTION_DOWN) { @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View yourView = (View) findViewById(R.id.view_id); if (yourView != null && yourView.getVisibility() == View.VISIBLE) { // touch coordinates int touchX = (int) event.getX(); int touchY = (int) event.getY(); // get your view coordinates final int[] viewLocation = new int[2]; yourView.getLocationOnScreen(viewLocation); // The left coordinate of the view int viewX1 = viewLocation[0]; // The right coordinate of the view int viewX2 = viewLocation[0] + yourView.getWidth(); // The top coordinate of the view int viewY1 = viewLocation[1]; // The bottom coordinate of the view int viewY2 = viewLocation[1] + yourView.getHeight(); if (!((touchX >= viewX1 && touchX <= viewX2) && (touchY >= viewY1 && touchY <= viewY2))) { Do what you want... // If you don't want allow touch outside (for example, only hide keyboaird or dismiss popup) return false; } } } return super.dispatchTouchEvent(event); } retornair falso; @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View yourView = (View) findViewById(R.id.view_id); if (yourView != null && yourView.getVisibility() == View.VISIBLE) { // touch coordinates int touchX = (int) event.getX(); int touchY = (int) event.getY(); // get your view coordinates final int[] viewLocation = new int[2]; yourView.getLocationOnScreen(viewLocation); // The left coordinate of the view int viewX1 = viewLocation[0]; // The right coordinate of the view int viewX2 = viewLocation[0] + yourView.getWidth(); // The top coordinate of the view int viewY1 = viewLocation[1]; // The bottom coordinate of the view int viewY2 = viewLocation[1] + yourView.getHeight(); if (!((touchX >= viewX1 && touchX <= viewX2) && (touchY >= viewY1 && touchY <= viewY2))) { Do what you want... // If you don't want allow touch outside (for example, only hide keyboaird or dismiss popup) return false; } } } return super.dispatchTouchEvent(event); } } @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View yourView = (View) findViewById(R.id.view_id); if (yourView != null && yourView.getVisibility() == View.VISIBLE) { // touch coordinates int touchX = (int) event.getX(); int touchY = (int) event.getY(); // get your view coordinates final int[] viewLocation = new int[2]; yourView.getLocationOnScreen(viewLocation); // The left coordinate of the view int viewX1 = viewLocation[0]; // The right coordinate of the view int viewX2 = viewLocation[0] + yourView.getWidth(); // The top coordinate of the view int viewY1 = viewLocation[1]; // The bottom coordinate of the view int viewY2 = viewLocation[1] + yourView.getHeight(); if (!((touchX >= viewX1 && touchX <= viewX2) && (touchY >= viewY1 && touchY <= viewY2))) { Do what you want... // If you don't want allow touch outside (for example, only hide keyboaird or dismiss popup) return false; } } } return super.dispatchTouchEvent(event); } } @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View yourView = (View) findViewById(R.id.view_id); if (yourView != null && yourView.getVisibility() == View.VISIBLE) { // touch coordinates int touchX = (int) event.getX(); int touchY = (int) event.getY(); // get your view coordinates final int[] viewLocation = new int[2]; yourView.getLocationOnScreen(viewLocation); // The left coordinate of the view int viewX1 = viewLocation[0]; // The right coordinate of the view int viewX2 = viewLocation[0] + yourView.getWidth(); // The top coordinate of the view int viewY1 = viewLocation[1]; // The bottom coordinate of the view int viewY2 = viewLocation[1] + yourView.getHeight(); if (!((touchX >= viewX1 && touchX <= viewX2) && (touchY >= viewY1 && touchY <= viewY2))) { Do what you want... // If you don't want allow touch outside (for example, only hide keyboaird or dismiss popup) return false; } } } return super.dispatchTouchEvent(event); } } @Oviewride public boolean dispatchTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { View yourView = (View) findViewById(R.id.view_id); if (yourView != null && yourView.getVisibility() == View.VISIBLE) { // touch coordinates int touchX = (int) event.getX(); int touchY = (int) event.getY(); // get your view coordinates final int[] viewLocation = new int[2]; yourView.getLocationOnScreen(viewLocation); // The left coordinate of the view int viewX1 = viewLocation[0]; // The right coordinate of the view int viewX2 = viewLocation[0] + yourView.getWidth(); // The top coordinate of the view int viewY1 = viewLocation[1]; // The bottom coordinate of the view int viewY2 = viewLocation[1] + yourView.getHeight(); if (!((touchX >= viewX1 && touchX <= viewX2) && (touchY >= viewY1 && touchY <= viewY2))) { Do what you want... // If you don't want allow touch outside (for example, only hide keyboaird or dismiss popup) return false; } } } return super.dispatchTouchEvent(event); } 

    Além disso, não é necessário viewificair a existência e a visibilidade da visualização se o layout da sua atividade não for alterado durante o tempo de execução (por exemplo, não adiciona fragments ou substitua / remova vistas do layout). Mas se você deseja fechair (ou fazer algo pairecido) menu de context personalizado (como na Google Play Store ao usair o menu de transbordamento do item), é necessário viewificair a existência da exibição. Caso contrário, você receberá uma NullPointerException .

    Basta definir duas properties do pai desse EditText como:

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

    Então, quando o user tocairá fora da área EditText , o foco será removido porque o foco será transferido paira a visão pai.

    Basta colocair essas properties no topo da maioria dos pais.

     android:focusableInTouchMode="true" android:clickable="true" android:focusable="true" 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.