Hide keyboard when user touches fragment inside activity - android

Inside the .xml layout I have 3 components in following order:
A Textview
A fragment (extends ListFragment)
A LinearLayout storing 2 buttons
Whenever user uses the search bar to query, the keyboard appears. Content of the fragment will be updated depending on the query.
What I'm trying to do is whenever user taps the screen (outside the keyboard), the keyboard needs to be hidden. So far, I could only do so if I tap anywhere but the fragment region.
I tried setOnTouchListener inside onActivityCreated() inside the fragment but it doesnt seem to work.
I got tapping outside the fragment = hidding keyboard to work by using the following inside onCreate():
layout.setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View view, MotionEvent ev)
{
hideKeyboard(view);
return false;
}
});
hideKeyboard(View view)
public void hideKeyboard(View view)
{
InputMethodManager in = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
in.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
But not inside the fragment...

I made a silly mistake....
The following code would solve the issue:
Inside onActivityCreated()
getActivity().findViewById(R.id.mid).setOnTouchListener(new View.OnTouchListener()
{
#Override
public boolean onTouch(View dview, MotionEvent ev)
{
f_hideKeyboard(dview);
return false;
}
});
Edited: Nevermind.... The above works only if the query shows zero result. If it shows at least 1 result, touching the fragment region still will not hide keyboard

I know that it's a bit late. From what I have understand from your question, here is the solution below. Use the following code inside onCreateView
//hides keyboard when tap on the screen
view.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_MOVE){
//do something
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}
return true;
}
});

Related

Custom keyboard set visibility gone when touch event dispatch from editText

I want to mimic android keyboard behavior when handling touch event. The android keyboard always hide every time I click somewhere else other the edit text and the keyboard. So far, I could mimic that's behavior using dispatchTouchEvent
Since it will detect for any dispatch touch even, whenever I click my keyboard button then it will close the keyboard it self. I wanna check if I click somewhere else other than my keyboard then hide the keyboard, else keep the keyboard on. I think I just missed piece of code and I can't find it what i missed here. It just need one single step to accomplish this. Please help.
Here my keyboard looks like
and here what i did so far
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (getCurrentFocus() != null) {
View view = getCurrentFocus();
//im not sure this condition would help
if (view == null) {
keyboard.setVisibility(View.GONE);
}
}
return super.dispatchTouchEvent(ev);
}
I can get the view object but i cant determine which view that i need to keep my keyboard on.
The other code (variable declaration)
PhoneKeyboard pk;
InputConnection ic;
LinearLayout keyboard;
pk = findViewById(R.id.phone_keyboard);
ic = phone_no.onCreateInputConnection(new EditorInfo());
pk.setInputConnection(ic);
Handling back pressed (mimic the android keyboard behavior)
#Override
public void onBackPressed(){
if(keyboard.getVisibility() == View.GONE)
super.onBackPressed();
else
keyboard.setVisibility(View.GONE);
}
How I handle request on the editText to make my keyboard visible
phone_no.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(
android.content.Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
if(view.equals(phone_no) && keyboard.getVisibility() == View.GONE) {
phone_no.requestFocus();
keyboard.setVisibility(View.VISIBLE);
}
return false;
}
});
How I handle submit / enter event at my custom keyboard (for who need the solution for custom keyboard, maybe this post can help other:) )
phone_no.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(
android.content.Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
if(view.equals(phone_no) && keyboard.getVisibility() == View.GONE) {
phone_no.requestFocus();
keyboard.setVisibility(View.VISIBLE);
}
return false;
}
});
Here is my snippet code for the keyboard layout view
<include
layout="#layout/layout_keyboard_phone_no"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="false"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Ps. I also have base activity and it extends to all my activity (if your solution required the base activity)
Update 1
I have try this method
phone_no.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
keyboard.setVisibility(View.GONE);
}
}
});
Is doing the same thing with the onDispatch event, whenever I click number on my custom keyboard, it also hide the keyboard. I need to check if the view others than the edit text and my custom keyboard then hide the keyboard else keep the keyboard on. Thank you

Keyboard is hiding on scrolling

In my xml, I am having TextInputLayout edittext inside NestedRecyclerView, when focus is on first edittext and I am going to focus on second edittext then keyboard is hiding and showing, on scrolling also keyboard is hiding but focus is still there.
Any help will be appreciated.
implement OnTouchListener in your project code
MyRecycleView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
return false;
}
});
This might help you Implementation of RecyclerView that will dismiss keyboard

Is scrollView.setOnTouchListener necessary?

I am fairly new to Android and I am looking at a project that has a scroll view in it with the following listener attached to it.
scrollView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
return false;
}
});
To my understanding, the project has this so that the scroll view..well.. scrolls (or hides the keyboard). However, when I comment out this code and rerun the project, the scroll view still scrolls (and hides the keyboard) just fine. So, is there any purpose for this code?

EditText custom properties android

I want to do the following :
I have an edit text and want to be able to select text from it without showing the soft keyboard and without editing it's content, just to select text to use it in another screen
N.B. this edit text is inside dialog box that shown above the activity, the current scenario that it show up the keyboard when open the dialog
I have tried the following
android:windowSoftInputMode="stateHidden"
I have also used the following code :
editText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
v.onTouchEvent(event);
hideSoftKetboard (v);
return true;
}
});
private void hideSoftKetboard (View v){
InputMethodManager imm = (InputMethodManager)v.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
}
can anyone help please ?
Use setInputType(0); will solve the problem

Tap outside edittext to lose focus

I just want when click outside the "edittext" to automatically lose focus and hide keyboard. At the moment, if I click on the "edittext" it focuses but i need to hit the back button to unfocus.
To solve this problem what you have to do is first use setOnFocusChangeListener of that Edittext
edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
Log.d("focus", "focus lost");
// Do whatever you want here
} else {
Log.d("focus", "focused");
}
}
});
and then what you need to do is override dispatchTouchEvent in the activity which contains that Edittext see below code
#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);
}
Now what will happen is when a user click outside then, firstly this dispatchTouchEvent will get called which then will clear focus from the editext, now your OnFocusChangeListener will get called that focus has been changed, now here you can do anything which you wanted to do, hope it works :)
#woodshy has the answer for hiding the keyboard, but maybe putting the code in onClick is not as good as putting it in onFocusChanged. As for forcing it to lose focus, you need to set the object you want to transfer the focus to, in its XML file:
android:focusable="true"
android:focusableInTouchMode ="true"
Suppose your EditText is placed on Linear layout or other ViewGroup. Then you should make this container clickable, focusable and focusableInTouchMode. After that set onClickListener to this container with following code in onClick Override method:
#Override
public void onClick(View view) {
InputMethodManager imm = (InputMethodManager) view.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
You can achieve this by doing the following steps:
1.Make the parent view(content view of your activity) clickable and focusable by adding the following attributes
android:clickable="true"
android:focusableInTouchMode="true"
2.Implement a hideKeyboard() method
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
3.Lastly, set the onFocusChangeListener of your edittext.
edittext.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
hideKeyboard(v);
}
}
});
The following code works perfectly for me, and I regularly use this for closing the SoftKeyboard onTouch anywhere outside the 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);
}
}
}
So you just need to call the setupUI() function once in your onCreate() method and voilla, your hidingSoftKeyboard is setup!
For Losing complete focus of the EditText, simply do editText.clearFocus() in your hideSoftKeyboard() function.
Here universal method for all screens. Put it in your activity
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
clearFocusOnOutsideClick()
return super.dispatchTouchEvent(ev)
}
/*
* Clear focus on outside click
* */
private fun clearFocusOnOutsideClick() {
currentFocus?.apply {
if (this is EditText) {
clearFocus()
}
//Hide keyboard
val imm: InputMethodManager =
getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(windowToken, InputMethodManager.HIDE_NOT_ALWAYS)
}
}
kotlin clearfocus android outside
So I searched around a little bit, and no other solutions was exactly what I was looking for. In my opinion the focus behave strangely on EditText views.
What I did was...
Make sure the root view is a RelativeLayout
Add an overlay layout that is OVER the area that will make the keyboard disapear, but not the EditText. Something like below:
In my case, the EditText was in a container at the bottom of the screen. so it covered everyhting else.
Have a method that looks a bit like this one :
private void hideKeyboard() {
final InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
keyboardOverlay.setVisibility(View.GONE);
editText.clearFocus();
}
Now call this method on the onClick of the overlay you created.
What we want now is to make the overlay visible when you press on the editText. You cannot use the onFocus event (at least I did not get it to work...) So what i did is I managed the onTouch event instead.
editText.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(final View v, final MotionEvent event) {
keyboardOverlay.setVisibility(View.VISIBLE);
editText.requestFocus();
return false;
}
});
The requestFocus() here is to not override the focus event with the onTouch.
Quick advice, when you try this out, you can add a background color to the overlay to see exactly what is happening.
Hope it works for you!
set in a button or any view: this.getCurrentFocus().clearFocus();
For example:
#Override
public boolean onMenuOpened(int featureId, Menu menu) {
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
this.getCurrentFocus().clearFocus();
return super.onMenuOpened(featureId, menu);
}
I had the same requirement as I had to hide the keyboard once I touch anywhere outside my EditText box. The setOnFocusChangeListener does not do the job as even if you touch outside the edit text box is still selected.
For this I used the solution edc598 here.
I first got the MainLayout containing the whole view and add touch listener to it.
When onTouch event was triggered I check if the EditText box has focus.
If the EditText box has focus then I check the event's X-Y co-ordinates.
Based on the placement of my EditText box I hide the key board if touched anywhere outside the box
Code sample modified from 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;
}
});

Categories

Resources