I have two Edit text in an item of Recycler view, I have set a focus change listener for each of edit texts. The input type of both is text. Focus change listener works well for the first Edit text, but for the second one even I click the check button(right bottom) from keyboard it does not lose focus. What could be the problem ?
holder.textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
//textView.setGravity(Gravity.LEFT);
if(b){
holder.textView.setTextColor(getResources().getColor(R.color.TabYellow));
discreteScrollView.scrollToPosition(infiniteAdapter.getClosestPosition(position));
}
else {
Toast.makeText(getActivity(),"Input loose focus",Toast.LENGTH_SHORT).show();
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
holder.textView.setTextColor(getResources().getColor(R.color.white));
// textView.setGravity(Gravity.CENTER);
}
}
});
holder.newToDo.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
if(b){
discreteScrollView.scrollToPosition(infiniteAdapter.getClosestPosition(position));
}
else {
Toast.makeText(getActivity(),"Input loose focus",Toast.LENGTH_SHORT).show();
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
});`
Although It's not a good approach to create such type of layout but still what you can do is add keyEventListner of keyboard and check the type of key and insert the code of passing focus to another position's edit text.
Related
I'm trying to show a Keyboard for a view as the focus is set to it once it renders. I tried multiple ways of trying to get it to work but whenever the Dialog renders and the focus is in the View, it doesn't show the keyboard until I click it.
This was one way I tried and it didn't work.
yieldEdit.RequestFocus();
imm = (InputMethodManager)(this.Activity).GetSystemService(AMSessionActivity.InputMethodService);
I then also tried to add an event to the view like so.
yieldEdit.FocusChange += (sender, e) =>
{
if (e.HasFocus)
{
imm.ToggleSoftInput(ShowFlags.Forced, 0);
}
};
This also doesn't seem to work. I'm not sure why it isn't working as it worked when it was an Activity.
Thanks
Use below code in EditText xml;
android:focusable="true"
android:focusableInTouchMode="true"
and use the following to your activity
AMSessionActivity amsActivity = (AMSessionActivity) Activity;
yieldEdit.RequestFocus();
InputMethodManager imm = (InputMethodManager)amsActivity.GetSystemService(Context.InputMethodService);
imm.ShowSoftInput(yourTextBox, ShowFlags.Implicit);
Try to use :-
editText.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
editText.post(new Runnable() {
#Override
public void run() {
InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT);
}
});
}
});
editText.requestFocus();
My scenario is as it follows: I have a search fragment and in that fragment, I have 3 text fields(Search by name, by zip code and by distance). When the focus is applied on the "Search by name" field, the other 2 fields dissapear and the width of the selected field increases. My problem is that I can't lose focus of the first field and so, after I am done with writing the information, I can't use the other 2 fields.
What I am looking for is a way to lose focus of the fields when I press "enter" or when I press anywhere else on the screen but the text field.
Here is the code that I am running right now:
final EditText searchByName = (EditText) getActivity().findViewById(R.id.search_by_name);
final EditText searchByZipcode = (EditText) getActivity().findViewById(R.id.search_by_zipcode);
final EditText searchByDistance = (EditText) getActivity().findViewById(R.id.search_by_distance);
searchByName.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
/* When focus is lost check that the text field
* has valid values.
*/
if (hasFocus) {
searchByName.getLayoutParams().width=900;
searchByZipcode.setVisibility(View.INVISIBLE);
searchByDistance.setVisibility(View.INVISIBLE);
} else {
searchByName.getLayoutParams().width=405;
searchByZipcode.setVisibility(View.VISIBLE);
searchByDistance.setVisibility(View.VISIBLE);
}
}
});
searchByZipcode.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
/* When focus is lost check that the text field
* has valid values.
*/
if (hasFocus) {
searchByZipcode.getLayoutParams().width=700;
searchByName.setVisibility(View.INVISIBLE);
} else {
searchByZipcode.getLayoutParams().width=240;
searchByName.setVisibility(View.VISIBLE);
}
}
});
Inside your Activity Class , add this below method , it will work for you .It will hide keyboard and will clear focus anywhere outside you click in that one it will work .
#Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.
INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
I have three edit-text fields. Of these fields I want to display the soft input keyboard only for the first field and disabled for the later two fields sice these are date and time fields.
Edit-Text 1 //Show the keyboard
Edit-Text 2 and 3 //Hide the keyboard
By using below code I'm able to disable the keyboard for field 2 and 3 but when the user has focus on field 1 the keyboard appears but didn't hide when user taps on field 2 or 3. Although when field 2 or 3 is tapped first no keyboard appears.
//Code to disable soft input keyboard
public static void disableSoftInputFromAppearing(EditText editText) {
if (Build.VERSION.SDK_INT >= 11) {
editText.setRawInputType(InputType.TYPE_CLASS_TEXT);
editText.setTextIsSelectable(true);
} else {
editText.setRawInputType(InputType.TYPE_NULL);
editText.setFocusable(true);
}
How can I hide the soft input keyboard if its already open?
//activity
public static void hideSoftKeyboard(Activity activity) {
InputMethodManager inputMethodManager = (InputMethodManager)activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}
// fragment
public void hideSoftKeyboard() {
InputMethodManager inputMethodManager = (InputMethodManager) getActivity().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
}
// If edit-text loses the focus, hiding keyboard
edTxtMessage.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (isEditable){
v.setFocusable(true);
v.setFocusableInTouchMode(true);
} else {
edTxtMessage.setFocusable(false);
}
return false;
}
});
edTxtMessage.setOnFocusChangeListener(new View.OnFocusChangeListener({
#Override
public void onFocusChange(View view, boolean b) {
if (!b){
hideKeyboard(getContext(), view);
}
}
});
private void hideKeyboard(Context context, View view) {
if (view != null) {
InputMethodManager imm = (InputMethodManager)context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
Easy way is using the xml
android:inputType="none"
android:textIsSelectable="true
You can set the two attributes to your edittext
android:focusable="false"
android:focusableInTouchMode="false"
Note: By this Your edittext is clickable for the date and time not focus to softkeyboard
Check if the current focus is not null, otherwise it might lead to a null pointer exception
if (getCurrentFocus() != null) {
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
}
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;
}
});
the editText is not losing focus in my app when I click out of it, it has the orange border all time and that black line cursor..
I did this a LinearLayout according to this surrounding the editText:
Stop EditText from gaining focus at Activity startup
so it doesn't get focus on start of the app..
this is my code:
final EditText et = (EditText)findViewById(R.id.EditText01);
final InputMethodManager imm = (InputMethodManager) getSystemService(
INPUT_METHOD_SERVICE);
et.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
imm.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
}
});
et.setOnFocusChangeListener(new View.OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasfocus) {
if(hasfocus) {
imm.showSoftInput(et, InputMethodManager.SHOW_IMPLICIT);
} else {
imm.hideSoftInputFromWindow(et.getWindowToken(), 0);
}
}
});
But, it doesn't seem to be calling the onFocusChange when I click anywhere outside the editText!
It's simple. You can put the following in LinearLayout or any other else:
android:focusableInTouchMode="true"
Override Activity.dispatchTouchEvent():
#Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
View view = getCurrentFocus();
if (view != null && view instanceof EditText) {
Rect r = new Rect();
view.getGlobalVisibleRect(r);
int rawX = (int)ev.getRawX();
int rawY = (int)ev.getRawY();
if (!r.contains(rawX, rawY)) {
view.clearFocus();
}
}
}
return super.dispatchTouchEvent(ev);
}
That way, whenever someone clicks anywhere, you have control, and it's at only one point in code.
Create an onClick listener, possibly in your XML layout to listen for clicks in the background LinearLayout. From here you can call .clearFocus() on your EditText after you make it an instance variable of the activity you are working in.
You can remove the focus from the EditText, by setting the focus to other field by calling the method.
Suppose I have set the focus to back button on click of done button, then call the method on back button inside done button click listener.
And your problem is solved.
back.requestFocusFromTouch();