i want to hide the soft keyboard when i click开发者_Python百科 out side of editbox in a screen. how can i do this?
Had to edit this one to get it to work. Added a check to see if the focused view is a 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;
}
Could probably be done in a smoother way but it works really well.
To forcibly hide the keyboard you would use the following code... I put it in a method called 'hideSoftKeyboard()'. As mentioned by Falmarri, the softkeyboard should hide itself when you click out of it. However, if you call this method in an 'onClick()' of another item, it will forcibly close the keyboard.
private void hideSoftKeyboard(){
if(getCurrentFocus()!=null && getCurrentFocus() instanceof EditText){
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(yourEditTextHere.getWindowToken(), 0);
}
}
This can be done using following code :
1) Take a reference of your parent layout into java code by using findViewById().
2) then apply setOnTouchListener() to it.
3) Add following code in 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;
}
});
I added the following to my activity. It works because touching outside a Focusable View doesn't change the focus (so w == v) but the touch will be outside the View's rectangle.
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;
}
[edit: fix minor bug]
As an supplementary to the accepted answer.
If the accepted answer is not working for you, you can add the hideSoftKeyboard()
method to the onClick()
method of the onClickListener
of your EditText
. For example:
editText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
hideSoftKeyboard();
}
});
(place the above code in onResume()
or somewhere else)
ps. the definition of hideSoftKeyboard()
private void hideSoftKeyboard(){
if(getCurrentFocus()!=null && getCurrentFocus() instanceof EditText){
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 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;
}
set inputType to zero for edit text
editText.setInputType(0);
it's work for me
First of all thank you to Daniel, his code is really nice and I was using it for a while.
Recently I realized that I have to improve it. The problem was scrolling page. I had many EditText
s in my project and it was hiding the keyboard when you scroll the page.
I came up with a solution using onGestureListener
instead of overriding 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;
}
}
So, if user scrolls the page it goes to onScroll
method and it does nothing. If users just touches to screen it triggers onSingleTapUp
method.
I also had to change if statement of Daniel's code. Daniel was checking if the touch event is outside the EditText
. Since I have many EditViews
I changed the code to find if touch event is inside any of EditText
s.
It works fine with me, let me know for any kind of improvements or mistakes.
Just set the input type to null like that
editText.setInputType(InputType.TYPE_NULL);
I got a good solution.I know its too late but when searching most of times getting this link as first link. so it may be helpful for others. If you click on any text/button it will hide the softkeyboard which is already visible.
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);
}
});
精彩评论