EditText weird focus behaviour - android

Alright,
When I have the focus on my EditText and the keyboard etc is showing. I click on my drawable at the end of the edittext (Cancel button). I recognize this event with an onTouchListener and hide the keyboard, clear focus, etc myself.
However, when I 'touch' the cancel button, it hides the keyboard but the focus stays on the edittext. Meaning the cursor is still showing, but not blinking. So when I click on the edittext again to get focus, it shows the option to copy/paste, etc like I'm long pressing the cursor and doesn't show the keyboard.
But when I 'press' the cancel button, it clears the focus, hides the keyboard and most importantly it hides the cursor resulting in completely removing the focus. Then when I click on the edittext again, it gets focus back and DOES show the keyboard.
What is this weird behavior and how do I make it that it always does the 'press' behavior.
my code:
searchView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (event.getRawX() >= searchView.getRight() - searchView.getCompoundDrawables()[2].getBounds().width()) {
hideKeyboard(v);
isSearching = false;
searchView.setText("");
searchView.clearFocus();
searchView.setFocusable(false);
searchView.setFocusableInTouchMode(false);
getView().requestFocus(); // parent has both focusables true
searchView.setFocusable(true);
searchView.setFocusableInTouchMode(true);
fetchArticles();
return true;
}
}
return false;
}
});
Like you're seeing, I'm trying everything I can to always get the same behavior. However no luck so far. Hope you guys can help me!

Try these in parent of that EditText or in views you want to touch:
android:clickable="true"
android:focusable="true"
android:focusableInTouchMode="true"
It will allow to completely transfer focus elsewhere from EditText
However, in case when your drawable is inside of your Edittext like here:
android:drawableLeft="#drawable/my_icon"
the solution won't work until you make drawable as separate view in layout.

Oke so my current 'solution' is a suggested solution by #Dmitriy Pavlukhin.
Instead of using the drawableEnd from EditText itself, I created a separate view which has the same drawable and make sure to draw this on the same position. Now when I click this view, it clears the view as desired 100% of the time. The codebase is still the same from the question, however it is now implemented in a OnClick on the separated view.

Related

EditText in Listview loses focus when pressed on Android 4.x

I know there are a lot of similar questions out here
but I couldn't get any of the provided solutions working in a simple sample app.
The problem occurs when the softkeyboard is shown for the first time. As soon as it is shown, only by pressing the editText again makes it editable.
Tried the following:
android:windowSoftInputMode="adjustPan|adjustResize"
This is not solving any issues. It seems that this line is mandatory to have the activity resized after the softkeyboard is popping up. Unfortunately, it's also causing any EditTexts to lose focus. This is probably to the ListView itself gaining focus after the resizing process. So I tried the following workaround:
listView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
This always causes the first visible EditText that the ListView contains to gain focus, which is undesirable. The second EditText in the second row should instead gain focus when pressed, which is not happening. Also, if I eventually managed to focus another EditText other then the first one shown (e.g. by pressing 'Next' on the softkeyboard), the first visible one will receive focus after the keyboard is dismissed and the ListView being resized to its full size again.
I tried several other things like intercepting onFocusChange() events for the ListView, while knowing which EditText was pressed by its TouchListener. Requesting the focus for that certain EditText again did not lead to any success either.
Using a ScrollView instead of a ListView as suggested by other users is not an option either for the concerned project.
A classic hack for situations like this is to use a handler and postDelayed(). In your adapter:
private int lastFocussedPosition = -1;
private Handler handler = new Handler();
public View getView(final int position, View convertView, ViewGroup parent) {
// ...
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (lastFocussedPosition == -1 || lastFocussedPosition == position) {
lastFocussedPosition = position;
edittext.requestFocus();
}
}
}, 200);
} else {
lastFocussedPosition = -1;
}
}
});
return convertView;
}
This works on my device, but keep this code out of production. I also wouldn't be surprised if the focus bug manifests itself differently in different android versions or roms.
There are also many other problems with embedding an EditText within a ListView that have solutions that feel like a hack. See all of the other people struggling.
It's also very easy to have something like this happen:
.
After having gone down similar paths many times myself, I've mostly given up on trying to override any of the default keyboard behaviours or quirks. I would recommend trying to find alternative solution in your app if possible.
Have you considered having the ListView rows be just a styled TextView and then displaying a Dialog with an EditText when a row is clicked, updating the TextView as necessary?
I was having problems with the ActionBar "stealing" focus when I pressed on an EditText located within a ListView row. The above solutions did not work, but the following solution worked for me:
http://www.mysamplecode.com/2013/02/android-edittext-listview-loses-focus.html
Basically I added this to my ListView:
android:descendantFocusability="beforeDescendants"
and added this to my activity:
android:windowSoftInputMode="adjustPan"
Modify your manifest xml to add windowSoftInputMode in your activity:
<activity
android:name=".YourActivity"
android:windowSoftInputMode="adjustPan">
</activity>
I know its a very old thread but this answer might be helpful to someone so here it is:
Switch to RecyclerView and you won't have to worry about these annoying issues of ListView. Instead of making new view it recycles and reuses old views.
I was having the same problem with recyclerView and trying all suggested solutions.
Finally, the problem on my case was that the recyclerView had wrap_content as value for the height on my XML by accident; changed it to match_parent and started working as expected, no focusable value set and using android:windowSoftInputMode="adjustResize"
Use Recycler View, this solves several issues from list and gridview. You can even work with staggered gridviews. You could easily start working with this.
When the list is long enough to cover the soft keyboard, the
EditText in Listview loses focus when pressed on Android 4.x.
One solution is to wrap the Listview in a linear layout with a height of half the screen.
Whenever the Listview doesn't cover the softkeyboard, everything is fine.
was having the same issue. Searched for all such solutions with inputMode, focusability et al. Best solution, migrate to recycler view.
In my case I've added local value currentlyFocusedRow in my Adapter.
In the method getView() I've add these code to each editText:
if (currentlyFocusedRow == position) {
editText.requestFocus();
}
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
if (currentlyFocusedRow == -1) {
currentlyFocusedRow = position;
}
} else {
currentlyFocusedRow = -1;
}
}
});

Android EditText field like button

I am trying to cope with one (seemed to be) smalll thing. In my app I've got one activity with two EditText fields.
I want one of them to be normall field (etNormal), and the other (etButton) behave more like button, so when you touch it, the keybord is not shown but instead the sliding drawer is opened. If sliding drawer is opened and you will press the normall edittext sliding drawer will hide.
I've tried adding OnClickListener and OnTouchListener (not in same tries) to both with condition if etButton was clicked/touched open sliding drawer, if not then close.
The outcome was strange. When it was OnTouchListener test it was more like toggle, so when I pressed one drawer opens and on another close. When it came to OnClickListener I needed to press each edtitext twice to get action done.
And to hide keybord in etButton I am using setInputType(InputType.TYPE_NULL);. I've tried also setEnabled(false); but then I was even unable to click/touch it. The one defect of currently used method is when I am changing click from etNormal to etButton, the keyboard is still shown and it doesn't hide.
So, can anyone tell me what I can do to achive my goal?
EDIT:
I've erad your current suggestions and modified a little my code, but still it is not working.
This is a part of it where I am assigning OnTouchListener:
OnTouchListener touchListener = new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent ev) {
if(v==etButton && ev.getAction()==MotionEvent.ACTION_DOWN) {
slidingDrawer.animateOpen();
}else {
slidingDrawer.animateClose();
}
return false;
}
};
etNormal1.setOnTouchListener(touchListener);
etNormal2.setOnTouchListener(touchListener);
etButton.setOnTouchListener(touchListener);
Also in etButton declaration in XML layout file I have:
android:focusable="false"
But now, on etButton touch nothing hapens (only sliding drawer hides if was opened), and when etNormal1 or 2 is touched sliding drawer shows up or hides depending what was first (in other words toggel).
Any idea, what is wrong here?
Got an editText working like that with
android:focusable="false"
android:clickable="true"
Then an OnClickListener to override the action
In addition to above answers, I hide cursor using cursorVisibility!
android:focusable="false"
android:clickable="true"
android:cursorVisible="false"
android:focusableInTouchMode="false"
cursorVisible To show/hide the cursor on clicking the EditText
focusable To gain focus when user is touching the view, like EditText
focusableInTouchMode To keep a view selected. (select and click are different)
For detailed understanding, refer here
In your layout, add the following attribute to the EditText
android:focusable="false"
android:focusableInTouchMode="false"
Next, write method to handle the click on the EditText and add your application logic .
If you are using onTouch event, when you click the edittext, you will get two events with action as MotionEvent.Action_down and action Up. so basically it will give the effect of clicking the edit text twice. can you please provide the code so that we can have a deep look.
ReWrite your code as :
OnTouchListener touchListener = new OnTouchListener() {
boolean isOpen=false;
#Override
public boolean onTouch(View v, MotionEvent ev) {
if(v==etButton && ev.getAction()==MotionEvent.ACTION_UP) {
if(!isOpen){
slidingDrawer.animateOpen();
}else{
slidingDrawer.animateClose();
}
isOpen=!isOpen;
}
return false;
}
};
If etButton needs to be an EditText (why not a button, if it should behave like one?), maybe you could set an onFocusChangeListener. Once it gets the focus, you can show the drawer...?
Not sure about not showing the keyboard...
EditTexts are tricky. The reason why you have to press twice when you have use an OnClickListener is that the first time around the EditText gets focus and this consumes the touch event, in that case the OnFocusListener is triggered. When you touch the second time, the EditText already has Focus so now a click event is triggered.
I would suggest you try to do this without EditTexts. That would in any case yield a cleaner and simpler solution. Why exactly do you want to use EditTexts instead of Buttons?

Android: Replace soft keyboard with custom layout (Wheels for date picking)

I have a EditText where user needs to enter date. For date picking I have a custom wheel view (like iOS). Now on click of date EditText, I want to open a soft keyboard like drawer from bottom & put that wheel view inside it.
So can I replace the soft keyboard with my wheel view ? I mean, the container which hold the keyboard should now hold my custom wheel view.
Is there any way to achieve that ? Or any other better option for my purpose ?
1) If you must use EditText, you can prevent keyboard coming up, by setting its input type correctly. Other answer already mentions that.
2) But why use EditText here, especially since you are not inputing any value using keyboard here. You can use a TextView, and its onClickListener you can animate a LinearLayout (containing date picker) upwards.
yourTextView.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v){
//Animate a LinearLayout containing a DatePicker
animateDatePickerView();
}
});
Depending on your requirements and how re-usable you want it to be.
For the simple way, you can create a view to host that wheel picker align it bottom of the root layout and just hide/show it with some animation.
First you would want to override the onTouchListener of your edit text, consume the event and do what you want there.
editText.setOnTouchListener(new OnTouchListener() {
public boolean onTouch (View v, MotionEvent event) {
//Show the wheely wheel.
return true; //Consume the event.
}
});
My personal idea (not tested)
prevent showing keyboard when edittext is focused.
E.g, setInputType(InputType.TYPE_NULL);
Use a customized activity which contains your wheel and show it as dialog ( set theme as dialog).

Custom Listview with EditText: Focus

I have a simple layout with EditText and a Listview. Implemented custom ArrayList adapter to fill in the listview and custom filter so user can search for items displayed in the listview.
When I run the application, the focus is initially set to EditText and the keyboard is displayed as expected. But here is what I want to do:
The focus should be initially set to ListView when the app is launched.
If the user wants to enter text by selecting edittext control, then the keyboard should appear.
( At this point as the user inputs text, the listview items will change - I already implmented this)
With the keyboard still open, if the user select an item in the listview, the keyboard should disappear and trigger the listview onItemClick function.
How can I accomplish this?
1.Add below attribute to your particular EditText in its layout-xml:
android:focusable="false"
android:focusableInTouchMode="true"
2.Then in your Activity add:
mEditText.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
v.setFocusable(true);
return false;
}
});
Hope this helps.

How to focus away from an EditText?

In my application I need to make something happen when an EditText loses its focus. When editing an EditText I can't make it lose its focus. In windows phone there is the this.Focus(); method but here in android it doesn't seem to be the same. How can I do???
To focus away from Edit Text one should use clearFocus();
Now comes if you do need to handle any particular event if the focus is changed then..
**use Focus Change listener on view.**
onFocusChange(View v, boolean hasFocus)
//Called when the focus state of a view has changed.
if(!hasfocus)
{
//Your piece of code if the focus is lost on text view..
}

Categories

Resources