2010-10-23 36 views
16

tôi muốn ẩn bàn phím mềm khi tôi nhấp vào bên của hộp chỉnh sửa trong màn hình. tôi có thể làm cái này như thế nào?ẩn bàn phím mặc định khi nhấp chuột trong android

+0

Nó sẽ tự động thực hiện điều đó. Miễn là bạn bấm vào một nơi nào đó mà không mang lên bàn phím chính nó – Falmarri

+0

@Falmarri Ban đầu tôi nghĩ bạn đã đúng nhưng tôi không thể làm điều này xảy ra trên ứng dụng thử nghiệm của tôi. Kịch bản thử nghiệm: 1) bấm vào một EditText-xem mà sẽ trả về bàn phím, 2) bấm vào một SeekBar trong cùng một mảnh 3) bấm vào một RadioButton với focusable = true. Cả 2 cũng không phải 3 đóng bàn phím. Hành vi được đề xuất này có được ghi lại ở bất kỳ đâu không? – Nilzor

Trả lời

31

Để buộc phải ẩn bàn phím, bạn sẽ sử dụng mã sau ... Tôi đặt nó vào một phương thức có tên là 'hideSoftKeyboard()'. Như đã đề cập bởi Falmarri, phím chức năng nên tự ẩn khi bạn nhấp vào nó. Tuy nhiên, nếu bạn gọi phương thức này trong 'onClick()' của một mục khác, nó sẽ buộc phải đóng bàn phím.

private void hideSoftKeyboard(){ 
    if(getCurrentFocus()!=null && getCurrentFocus() instanceof EditText){ 
     InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.hideSoftInputFromWindow(yourEditTextHere.getWindowToken(), 0); 
    } 
} 
+0

Không làm việc từ năm 2015 – delive

6

Tôi đã thêm hoạt động sau vào hoạt động của mình. Nó hoạt động bởi vì việc chạm vào bên ngoài Chế độ xem tiêu điểm sẽ không thay đổi tiêu điểm (vì vậy w == v) nhưng chạm sẽ nằm ngoài hình chữ nhật của Chế độ xem.

public boolean dispatchTouchEvent(MotionEvent event) { 
    View v = getCurrentFocus(); 
    boolean ret = super.dispatchTouchEvent(event); 
    View w = getCurrentFocus(); 
    int scrcoords[] = new int[2]; 
    w.getLocationOnScreen(scrcoords); 
    float x = event.getRawX() + w.getLeft() - scrcoords[0]; 
    float y = event.getRawY() + w.getTop() - scrcoords[1]; 

    Log.d("Activity", "Touch event "+event.getRawX()+","+event.getRawY()+" "+x+","+y+" rect "+w.getLeft()+","+w.getTop()+","+w.getRight()+","+w.getBottom()+" coords "+scrcoords[0]+","+scrcoords[1]); 
    if (event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom())) { 
     inputManager.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0); 
    } 
    return ret; 

} 

[sửa: sửa chữa lỗi nhỏ]

57

Đã phải sửa cái này để làm cho nó làm việc. Thêm một kiểm tra để xem xem tập trung là một EditText.

@Override 
public boolean dispatchTouchEvent(MotionEvent event) { 

    View v = getCurrentFocus(); 
    boolean ret = super.dispatchTouchEvent(event); 

    if (v instanceof EditText) { 
     View w = getCurrentFocus(); 
     int scrcoords[] = new int[2]; 
     w.getLocationOnScreen(scrcoords); 
     float x = event.getRawX() + w.getLeft() - scrcoords[0]; 
     float y = event.getRawY() + w.getTop() - scrcoords[1]; 

     Log.d("Activity", "Touch event "+event.getRawX()+","+event.getRawY()+" "+x+","+y+" rect "+w.getLeft()+","+w.getTop()+","+w.getRight()+","+w.getBottom()+" coords "+scrcoords[0]+","+scrcoords[1]); 
     if (event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom())) { 

      InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
      imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0); 
     } 
    } 
return ret; 
} 

Có thể được thực hiện một cách mượt mà hơn nhưng hoạt động thực sự tốt.

+2

Để thêm một chút làm rõ - nếu bạn đang tìm cách đóng bàn phím khi người dùng nhấp vào BẤT KW NỘI DUNG NGOẠI TỆ của AN EDITTEXT, và không chỉ trong nút onClick(), thì mã của Daniel hoạt động hoàn hảo. Chỉ cần thêm/ghi đè phương thức vào Hoạt động của bạn và người dùng sẽ có thể đóng bàn phím bằng cách nhấp vào bất kỳ đâu bên ngoài EditText (cũng hoạt động với nhiều EditTexts trên một màn hình). Cảm ơn Daniel! –

+2

Đây không phải là câu trả lời hoàn hảo vì nó sẽ ẩn bàn phím khi chạm vào, không nhấn. Nếu bạn, ví dụ: cuộn một chút, bàn phím sẽ bị ẩn. Điều này thường không được mong muốn. – Ixx

+0

@daniel cảm ơn, đây là thiên tài – bibangamba

6

Điều này có thể được thực hiện bằng đoạn mã sau:

1) Hãy tham khảo các cách bố trí cha mẹ của bạn vào mã java bằng cách sử dụng findViewById().

2) sau đó áp dụng setOnTouchListener() cho nó.

3) Thêm mã sau vào onTouchMethod().

lin = (LinearLayout) findViewById(R.id.lin); 
    lin.setOnTouchListener(new OnTouchListener() 
    { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) 
     { 
       InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); 
           imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0); 
         return false; 
     } 
    }); 
0
public boolean OutsideTouchEvent(MotionEvent m_event) { 
    View v = getCurrentFocus(); 
    boolean value = super.dispatchTouchEvent(m_event); 
    View w = getCurrentFocus(); 
    int scrcoords[] = new int[2]; 
    w.getLocationOnScreen(scrcoords); 
    float x = m_event.getRawX() + w.getLeft() - scrcoords[0]; 
    float y = m_event.getRawY() + w.getTop() - scrcoords[1]; 

    if (m_event.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom())) { 
     InputMethodManager inputMethodManager = (InputMethodManager) YourActivity.this.getSystemService(Activity.INPUT_METHOD_SERVICE); 
     inputMethodManager.hideSoftInputFromWindow(YourActivity.this.getCurrentFocus().getWindowToken(), 0); 
    } 
    return value; 

} 
0

bộ inputType để không cho chỉnh sửa văn bản
editText.setInputType(0);

nó làm việc cho tôi

0

Trước hết cảm ơn bạn để Daniel, mã của mình là thật sự tốt đẹp và tôi đã sử dụng nó trong một thời gian.

Gần đây tôi nhận ra rằng tôi phải cải thiện nó. Vấn đề là cuộn trang. Tôi đã có nhiều EditText giây trong dự án của mình và nó đã ẩn bàn phím khi bạn cuộn trang.

tôi đã đưa ra một giải pháp sử dụng onGestureListener thay vì trọng dispatchTouchEvent.

public class TabActivity extends ActionBarActivity implements GestureDetector.OnGestureListener { 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     ... 
     ... 
     gestureScanner = new GestureDetector(TabActivity.this,this); 
    } 

    @Override 
    public boolean dispatchTouchEvent(MotionEvent ev) { 
     gestureScanner.onTouchEvent(ev); 
     return super.dispatchTouchEvent(ev); 
    } 

    @Override 
    public boolean onSingleTapUp(MotionEvent event) { 
     View v = getCurrentFocus(); 

     if (v instanceof EditText) { 
      View w = getCurrentFocus(); 
      int scrcoords[] = new int[2]; 
      w.getLocationOnScreen(scrcoords); 
      boolean hide = true; 

      View view = ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0); 
      ArrayList<View> editTexts = view.getFocusables(0);  // Get All EditTexts in view 

      for(int i=0; i< editTexts.size(); i++){ 
       View editText = editTexts.get(i); 
       editText.getLocationOnScreen(scrcoords); 
       float x = event.getRawX(); 
       float y = event.getRawY(); 
       int viewX = scrcoords[0]; 
       int viewY = scrcoords[1]; 

       // If touch is in any of EditText, keep keyboard active, otherwise hide it. 
       if (event.getAction() == MotionEvent.ACTION_UP && (x > viewX && x < (viewX + editText.getWidth())) && (y > viewY && y < (viewY + editText.getHeight()))) { 
        hide = false; 
       } 
      } 

      if (hide) { 
       InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
       imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0); 
      } 
     } 
     return true; 
    } 

    @Override 
    public boolean onScroll(MotionEvent event, MotionEvent e2, float distanceX, float distanceY) { 
     return true; 
    }  
} 

Vì vậy, nếu người dùng cuộn trang nó đi để onScroll phương pháp và nó không có gì. Nếu người dùng chỉ cần chạm vào màn hình, nó sẽ kích hoạt phương thức onSingleTapUp.

Tôi cũng phải thay đổi nếu câu lệnh của mã của Daniel. Daniel đang kiểm tra xem sự kiện cảm ứng có nằm ngoài số EditText không. Vì tôi có nhiều EditViews Tôi đã thay đổi mã để tìm xem sự kiện cảm ứng có nằm trong bất kỳ EditText giây nào không.

Nó hoạt động tốt với tôi, hãy cho tôi biết cho bất kỳ loại cải tiến hoặc sai lầm nào.

+0

Xem chế độ xem = ((ViewGroup) findViewById (android.R.id.content)). GetChildAt (0); tôi đã không nhận được điều này. Bạn sẽ giải thích? – Tara

+0

Đó là một dự án cũ tôi đã làm việc, tôi không nhớ chi tiết. Về cơ bản, những gì tôi làm ở đó là truy xuất chế độ xem cha mẹ. 'android.R.id.content' sẽ cung cấp cho bạn chế độ xem gốc. 'getChildAt (0)' có thể được sử dụng để truy xuất cha của EditTexts của tôi. –

+0

vì vậy bạn muốn nói thêm tất cả văn bản chỉnh sửa trong nhóm xem hoặc chế độ xem bên trong? – Tara

0

Chỉ cần thiết lập các loại đầu vào null như thế

editText.setInputType(InputType.TYPE_NULL);

0

Là một bổ sung cho câu trả lời chấp nhận.

Nếu câu trả lời được chấp nhận không hoạt động cho bạn, bạn có thể thêm phương thức hideSoftKeyboard() vào phương pháp onClick() của onClickListener trong số EditText. Ví dụ:

editText.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     hideSoftKeyboard(); 
    } 
}); 

(đặt mã trên trong onResume() hoặc ở một nơi khác)

ps. định nghĩa của hideSoftKeyboard()

private void hideSoftKeyboard(){ 
    if(getCurrentFocus()!=null && getCurrentFocus() instanceof EditText){ 
     InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE); 
     imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); 
    } 
} 
0

Tôi nhận được giải pháp tốt.Tôi biết quá muộn nhưng khi tìm kiếm hầu hết các lần nhận liên kết này là liên kết đầu tiên. vì vậy nó có thể hữu ích cho người khác. Nếu bạn nhấp vào bất kỳ văn bản/nút nào, nó sẽ ẩn softkeyboard đã được hiển thị.

date.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      // Hide soft keyboard 
     InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE); 
      imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); 

     // here i am showing the Date Dialog. one can proceed with their functionality 

      //show date picker dialog 
      showDialog(Date_DIALOG_ID); 
     } 
    }); 
Các vấn đề liên quan