2013-12-20 324 views
12

我有一個叫myTextviewEditText。當我點擊EditText時,我想讓軟鍵盤顯示,但如果我點擊EditText以外的地方,則會退出。所以我使用下面的方法。但是當我在視圖外點擊時鍵盤不會消失(我點擊TextView)。我如何修復此代碼?在android中點擊EditText之外的時候關閉鍵盤

myTextview.setOnFocusChangeListener(new OnFocusChangeListener() { 

     @Override 
     public void onFocusChange(View v, boolean hasFocus) { 
      if (hasFocus) { 
       getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); 
      } else { 
       InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE); 
       imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0); 
      } 

     } 
    }); 
+1

可能重複[如何點擊EditText上外後隱藏軟鍵盤在Android?](http://stackoverflow.com/questions/4165414/how-to- hide-soft-keyboard-on-android-after-click-outside-edittext) – Fllo

回答

2

這樣,只有觸摸可以獲得焦點的視圖時,鍵盤纔會消失。我建議你做到以下幾點:

創建自定義的ViewGroup是這樣的:

public class TouchLayout extends LinearLayout { 

    private OnInterceptTouchEventListener mListener; 

    public TouchLayout(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event) { 
     if(mListener != null) { 
      return mListener.onInterceptTouchEvent(event); 
     } 
     return super.onInterceptTouchEvent(event); 
    } 

    public void setOnInterceptTouchEventListener(OnInterceptTouchEventListener listener) { 
     mListener = listener; 
    } 

    public interface OnInterceptTouchEventListener { 
     public boolean onInterceptTouchEvent(MotionEvent event); 
    } 
} 

然後添加自定義查看你的XML佈局的根:

<com.example.TouchLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/root" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" > 

     <EditText 
      android:id="@+id/text" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" /> 

而在你的活動你應該做以下幾點:

final TouchLayout root = (TouchLayout) findViewById(R.id.root); 
final EditText text = (EditText) findViewById(R.id.text); 
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 

root.setOnInterceptTouchEventListener(new OnInterceptTouchEventListener() { 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event) { 
     final View v = getCurrentFocus(); 
     if(v != null && v.equals(text)) { 
      final int screenCords[] = new int[2]; 
      text.getLocationOnScreen(screenCords); 
      final Rect textRect = new Rect(screenCords[0], screenCords[1], screenCords[0] + text.getWidth(), screenCords[1] + text.getHeight()); 
      if(!textRect.contains(event.getRawX(), event.getRawY() { 
       imm.hideSoftInputFromWindow(myTextview.getWindowToken(), 0); 
       // Optionally you can also do the following: 
       text.setCursorVisible(false); 
       text.clearFocus(); 
      } 
     } 
     return false; 
    } 
}; 
15

也許有點容易:

在您的編輯文本上設置focusChangedListener,然後在沒有焦點時隱藏鍵盤。

yourEditText.setOnFocusChangeListener(new OnFocusChangeListener() { 

    @Override 
    public void onFocusChange(View v, boolean hasFocus) { 
     if(!hasFocus){ 
      hideKeyboard(); 
     }    
    } 
}); 

private void hideKeyboard() { 
    InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE); 
    imm.hideSoftInputFromWindow(yourEditText.getWindowToken(), 0); 
} 
35

我發現了一個更好的解決方案:即使您正在使用的WebView工作

@Override 
public boolean dispatchTouchEvent(MotionEvent ev) { 
    View v = getCurrentFocus(); 

    if (v != null && 
      (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && 
      v instanceof EditText && 
      !v.getClass().getName().startsWith("android.webkit.")) { 
     int scrcoords[] = new int[2]; 
     v.getLocationOnScreen(scrcoords); 
     float x = ev.getRawX() + v.getLeft() - scrcoords[0]; 
     float y = ev.getRawY() + v.getTop() - scrcoords[1]; 

     if (x < v.getLeft() || x > v.getRight() || y < v.getTop() || y > v.getBottom()) 
      hideKeyboard(this); 
    } 
    return super.dispatchTouchEvent(ev); 
} 

public static void hideKeyboard(Activity activity) { 
    if (activity != null && activity.getWindow() != null && activity.getWindow().getDecorView() != null) { 
     InputMethodManager imm = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.hideSoftInputFromWindow(activity.getWindow().getDecorView().getWindowToken(), 0); 
    } 
} 

這是適用的。

字體:http://kuznetsow.com/?p=196&lang=en

+0

整潔,最佳的解決方案,保存我最大的時間 –

+0

如果點擊另一個EditText,會發生什麼? – Simas

+0

我可以確認 - 如果另一個EditText被點擊,焦點只轉移到EditText。這個解決方案對我來說很完美。 –

3

使用下面的代碼。

public static void hideSoftKeyboard(Activity activity) { 
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); 
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0); 
} 

它對我有用。

2

懇求:我承認我沒有影響力,但請認真對待我的回答。

問題:當離開鍵盤或使用最少代碼編輯文本時關閉軟鍵盤。

解決方案:外部庫被稱爲Butterknife。

一號線解決方案:

@OnClick(R.id.activity_signup_layout) public void closeKeyboard() { ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); } 

更可讀的解決方案:

@OnClick(R.id.activity_signup_layout) 
public void closeKeyboard() { 
     InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); 
} 

說明:綁定的OnClick監聽到活動中的XML佈局父ID,因此任何點擊在佈局上(而不是在編輯文本或鍵盤上)將運行代碼將隱藏keyb的代碼片段OARD。

例子:如果你的佈局文件是R.layout.my_layout,你的佈局ID是R.id.my_layout_id,那麼你的Butterknife綁定調用應該是這樣的:

(@OnClick(R.id.my_layout_id) 
public void yourMethod { 
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
    imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0); 
} 

Butterknife文檔鏈接:http://jakewharton.github.io/butterknife/

插件: Butterknife將徹底改變你的android開發。考慮一下。

+0

你至少再給出一次相同的答案。它聞起來像垃圾郵件。對不起,但那不會奏效。 – GhostCat

+0

@GhostCat爲什麼它不起作用或爲什麼它是一個不好的解決方案?你有很大的影響力,我非常確信這個社區非常尊重。這種黑客解決方案只適用於其他很多嘗試都不適用的情況。我希望能解釋爲什麼它不能解決問題,而不是模糊的誹謗。我只是想學習。 –

+0

重複完全相同的答案在這裏不是一個好習慣。就這樣。 – GhostCat

0

視圖上的觸摸事件將從ACTION_DOWN開始從頂部傳遞到此視圖的層次結構。覆蓋dispatchTouchEvent做更多的事情。下面是一個例子,從FrameLayout在科特林擴展:

class TLayout @JvmOverloads constructor(context: Context, attrs: AttributeSet?=null): 
     FrameLayout(context, attrs){ 

    var preDispatchTouchEvent: ((ev: MotionEvent?)->Boolean)? = null 

    override fun dispatchTouchEvent(ev: MotionEvent?): Boolean { 
     if (preDispatchTouchEvent==null || !preDispatchTouchEvent!!.invoke(ev)) { 
      super.dispatchTouchEvent(ev) 
     } 
     return true 
    } 

} 

包裝你EditText及其他相關View s此佈局下,並設置preDispatchTouchEvent駁回EditText當事件不是它上面。

查詢this OS questionofficial doc對觸摸事件傳遞有更深的理解。

0

此Xamarin的Android代碼:

public override bool DispatchTouchEvent(MotionEvent ev) 
    { 
     try 
     { 
      View view = CurrentFocus; 
      if (view != null && (ev.Action == MotionEventActions.Up || ev.Action == MotionEventActions.Move) && view is EditText && !view.Class.Name.StartsWith("android.webkit.")) 
      { 
       int[] Touch = new int[2]; 
       view.GetLocationOnScreen(Touch); 
       float x = ev.RawX + view.Left - Touch[0]; 
       float y = ev.RawY + view.Top - Touch[1]; 
       if (x < view.Left || x > view.Right || y < view.Top || y > view.Bottom) 
        ((InputMethodManager)GetSystemService(InputMethodService)).HideSoftInputFromWindow((Window.DecorView.ApplicationWindowToken), 0); 
      } 
     } 
     catch (System.Exception ex) 
     { 

     } 

     return base.DispatchTouchEvent(ev); 
    } 
相關問題