2011-07-13 441 views
32

我只想在點擊「edittext」之外時自動失去焦點並隱藏鍵盤。目前,如果我點擊「edittext」,它將重點關注,但我需要點擊後退按鈕才能確定焦點。點擊外部edittext以失去焦點

+0

相關問題:http://stackoverflow.com/q/4165414/782870。我認爲大部分答案已經過測試,並且已經發現有效。 – vida

+0

我找到了這個答案:http://stackoverflow.com/a/28939113/2610855最好的一個。 – Loenix

回答

15

假設您的EditText放置在線性佈局或其他ViewGroup上。然後你應該讓這個容器可點擊,可聚焦和focusableInTouchMode。該組onClickListener到這個容器用的onClick覆蓋方法下面的代碼後:

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

就我而言,我在文本字段的焦點上顯示數字鍵盤。我試圖使用你的解決方案。當我點擊背景視圖時,數字鍵盤轉換成AlphaNumeric鍵盤,然後當我再次點擊時,它會消失。 –

13

@woodshy有隱藏鍵盤,但也許將代碼中onClick答案是不是把它在onFocusChanged好。至於迫使它失去焦點,您需要設置對象要轉移焦點,在其XML文件:

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

我可以有一個與此相關的問題:你的意思是說這些代碼應該放在LinearLayout中,或者是我想要忽略的EditText?謝謝。 – detno29

+0

你應該把它作爲父視圖的屬性(你的活動的內容視圖)。你可能想看看這個:http://stackoverflow.com/a/19828165/782870 – vida

-5

我有同樣的要求,因爲我不得不隱藏鍵盤當我觸摸任何地方我的EditText框外。 setOnFocusChangeListener不會執行此任務,即使您在編輯文本框之外觸摸仍處於選中狀態。

爲此,我使用瞭解決方案edc598 here

  • 我首先得到了包含整個視圖的MainLayout,並添加了觸摸監聽器。
  • 當onTouch事件被觸發時,我檢查EditText框是否有焦點。
  • 如果EditText框有焦點,我檢查事件的X-Y座標。
  • 根據我的EditText框的位置我隱藏鍵盤,如果箱子從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

老兄,你得開玩笑我們這個神奇的數字...... –

+0

絕對不需要邊界檢查,因爲EditText會吃觸摸事件。 – pstoppani

1

所以我搜索周圍一點點,和沒有其他解決方案是我正在尋找的。在我看來,焦點在EditText視圖上表現得很奇怪。

我所做的是什麼...

  1. 確保根視圖是一個RelativeLayout的

  2. 添加覆蓋佈局已經結束,這將使鍵盤disapear面積,但不EditText上。類似下面:

在我的情況下,是的EditText在容器在屏幕的底部。所以它涵蓋了其他所有。

  • 具有看起來有點像這樣的一個方法:
  •  
        private void hideKeyboard() { 
         final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
         imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); 
         keyboardOverlay.setVisibility(View.GONE); 
         editText.clearFocus(); 
        } 
    
  • 現在請的onClick此方法您創建的疊加層。

  • 我們現在想要的是在按editText時使覆蓋層可見。你不能使用onFocus事件(至少我沒有得到它的工作......)所以我做的是我管理的onTouch事件。

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

    的requestFocus()方法在這裏是不覆蓋與onTouch的焦點事件。

    快速建議,當您嘗試此操作時,您可以向疊加層添加背景顏色以查看究竟發生了什麼。

    希望它適合你!

    +0

    有沒有更好的方法來做到這一點? – Gohan

    11

    爲了解決這個問題,你必須做的是,EDITTEXT的第一次使用setOnFocusChangeListener

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

    ,然後你需要做的是覆蓋dispatchTouchEvent其中包含EDITTEXT看到下面的代碼的活動是什麼

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

    現在會發生什麼是當用戶點擊外部然後首先這個dispatchTouchEvent將被調用,然後將清除焦點從editext現在你的OnFocusChangeListener將被調用焦點已被改變,現在他你可以做任何你想做的事情,希望它能起作用:)

    +0

    我喜歡這種方法。此外,在editText的直接父級的佈局中添加 'android:focusable =「true」'和'android:focusableInTouchMode =「true」''。 –

    +0

    '重點疏散'應該'重點丟失':) :)) – Stack

    0

    下面的代碼對我來說很完美,我經常使用這個代碼關閉EditText以外的任何地方的SoftKeyboard onTouch

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

    所以,你只需要在你的onCreate()方法和voilla調用一次setupUI()功能,您hidingSoftKeyboard是設置!

    對於失去EditText的完整焦點,只需在您的hideSoftKeyboard()函數中執行editText.clearFocus()即可。

    0

    您可以通過執行以下步驟實現:

    詞根記憶父視圖(你的活動內容視圖),點擊和可聚焦通過添加以下屬性

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

    2.Implement一hideKeyboard()方法

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

    3.最後,設置您的edittext的onFocusChangeListener。

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