2011-07-13 38 views
32

Tôi chỉ muốn khi nhấp vào bên ngoài "edittext" để tự động mất tiêu điểm và ẩn bàn phím. Tại thời điểm này, nếu tôi bấm vào "edittext" nó tập trung nhưng tôi cần phải nhấn nút quay lại để không tập trung.Nhấn bên ngoài edittext để mất tiêu điểm

+0

Câu hỏi liên quan: http://stackoverflow.com/q/4165414/782870. Tôi nghĩ rằng hầu hết các câu trả lời đã được kiểm tra và được phát hiện là có hiệu quả. – vida

+0

Tôi tìm thấy câu trả lời này: http://stackoverflow.com/a/28939113/2610855 Tốt nhất. – Loenix

Trả lời

15

Giả sử EditText của bạn được đặt trên Bố cục tuyến tính hoặc Nhóm ViewGroup khác. Sau đó, bạn nên làm cho vùng chứa này có thể nhấp, có thể lấy tiêu điểm và có thể lấy tiêu cựInTouchMode. Sau đó thiết lập OnClickListener vào vùng chứa này với mã sau đây trong phương pháp ghi đè onClick:

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

Trong trường hợp của tôi, tôi đang hiển thị bàn phím số ở tiêu điểm của trường văn bản. Tôi đã cố gắng sử dụng giải pháp của bạn. Khi tôi nhấp vào chế độ xem nền, bàn phím số sẽ chuyển đổi thành bàn phím AlphaNumeric, sau đó khi tôi nhấp lại, nó sẽ biến mất. –

13

@woodshy có câu trả lời cho ẩn bàn phím, nhưng có lẽ đặt mã trong onClick là không tốt như đặt nó trong onFocusChanged. Để buộc phải mất tiêu điểm, bạn cần phải đặt đối tượng bạn muốn chuyển trọng tâm sang, trong tệp XML của nó:

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

Tôi có thể có câu hỏi liên quan đến câu hỏi này không: bạn có nghĩa là các mã này nên được đặt trong LinearLayout hoặc EditText mà tôi muốn bỏ tập trung không? Cảm ơn. – detno29

+0

Bạn nên đặt nó làm thuộc tính của chế độ xem gốc (xem nội dung hoạt động của bạn). Bạn có thể muốn kiểm tra điều này: http://stackoverflow.com/a/19828165/782870 – vida

-5

Tôi có yêu cầu tương tự như tôi phải ẩn bàn phím khi tôi chạm vào bất kỳ đâu bên ngoài hộp EditText của tôi. setOnFocusChangeListener không thực hiện công việc ngay cả khi bạn chạm vào bên ngoài hộp văn bản chỉnh sửa vẫn được chọn.

Đối với điều này, tôi đã sử dụng giải pháp edc598 here.

  • Lần đầu tiên tôi có MainLayout chứa toàn bộ chế độ xem và thêm trình xử lý cảm ứng vào đó.
  • Khi sự kiện onTouch được kích hoạt, tôi kiểm tra xem hộp EditText có tập trung hay không.
  • Nếu hộp EditText có tiêu điểm thì tôi kiểm tra các tọa độ X-Y của sự kiện.
  • Dựa vào vị trí của hộp EditText tôi giấu bàn phím nếu chạm vào bất cứ nơi nào bên ngoài hộp mẫu

Mã sửa đổi từ 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

dude, bạn phải đùa với chúng tôi với số ma thuật này ... –

+0

Chắc chắn không cần kiểm tra giới hạn kể từ khi EditText sẽ ăn các sự kiện liên lạc. – pstoppani

1

Vì vậy, tôi đã tìm kiếm xung quanh một chút, và không có giải pháp nào khác chính xác là những gì tôi đang tìm kiếm. Theo tôi, trọng tâm hoạt động lạ trên các khung nhìn EditText.

Những gì tôi đã làm là ...

  1. Hãy chắc chắn rằng quan điểm gốc là một RelativeLayout

  2. Thêm một bố trí lớp phủ đó là so với khu vực đó sẽ làm cho disapear bàn phím, nhưng không phải là Chỉnh sửa văn bản. Một cái gì đó như dưới đây:

Trong trường hợp của tôi, EditText là trong một container ở dưới cùng của màn hình. nên nó bao phủ mọi thứ khác.

  1. Có một phương pháp mà trông hơi như thế này:
 
    private void hideKeyboard() { 
     final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); 
     keyboardOverlay.setVisibility(View.GONE); 
     editText.clearFocus(); 
    } 
  1. Bây giờ gọi phương pháp này trên onClick của lớp phủ bạn đã tạo.

  2. Điều chúng tôi muốn bây giờ là làm cho lớp phủ hiển thị khi bạn nhấn vào editText. Bạn không thể sử dụng sự kiện onFocus (ít nhất là tôi đã không nhận được nó để làm việc ...) Vì vậy, những gì tôi đã làm là tôi quản lý sự kiện onTouch thay thế.

 
editText.setOnTouchListener(new OnTouchListener() { 

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

Các requestFocus() ở đây là để không ghi đè lên các sự kiện tập trung với onTouch.

Lời khuyên nhanh, khi bạn dùng thử, bạn có thể thêm màu nền cho lớp phủ để xem chính xác những gì đang diễn ra.

Hy vọng nó phù hợp với bạn!

+0

có cách nào tốt hơn để làm điều đó không? – Gohan

11

Để giải quyết vấn đề này những gì bạn phải làm là đầu tiên setOnFocusChangeListener sử dụng EditText rằng

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

và sau đó những gì bạn cần làm là ghi đè dispatchTouchEvent trong hoạt động, trong đó có mà EditText xem dưới đây đang

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

Bây giờ điều gì sẽ xảy ra khi người dùng nhấp vào bên ngoài, trước tiên, dispatchTouchEvent này sẽ được gọi, sau đó sẽ xóa tiêu điểm khỏi editext ngay bây giờ OnFocusChangeListener của bạn sẽ được gọi là trọng tâm đã được thay đổi. bạn có thể làm bất cứ điều gì bạn muốn làm, hy vọng nó hoạt động :)

+0

Tôi thích phương pháp này. Ngoài ra, hãy thêm 'android: focusable =" true "' và 'android: focusableInTouchMode =" true "' vào bố cục của phụ huynh trực tiếp của 'editText'. –

+0

'focus loosed' phải là' focus losted' :)) – Stack

0

Đoạn mã sau hoạt động hoàn hảo cho tôi, và tôi thường sử dụng mã này để đóng SoftKeyboard onTouch ở bất kỳ đâu ngoài 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); 
      } 
     }  
} 

Vì vậy, bạn chỉ cần gọi setupUI() chức năng một lần trong onCreate() phương pháp và voilla của bạn, hidingSoftKeyboard bạn được thiết lập!

Để Mất tiêu điểm hoàn thành của EditText, chỉ cần thực hiện editText.clearFocus() trong hideSoftKeyboard() của bạn.

0

Bạn có thể đạt được điều này bằng cách thực hiện các bước sau:

1.Make quan điểm cha mẹ (xem nội dung hoạt động của bạn) có thể click và đặt tiêu điểm bằng cách thêm các thuộc tính sau đây

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

2.Implement một hideKeyboard() phương pháp

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

3.Lưu ý, đặt onFocusChangeListener của văn bản của bạn.

edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() { 
     @Override 
     public void onFocusChange(View v, boolean hasFocus) { 
      if (!hasFocus) { 
       hideKeyboard(v); 
      } 
     } 
    }); 
Các vấn đề liên quan