Android list - edittext in header of list - android

I have a List in Monodroid which has a header with an EditText. The problem is that EditText not getting focus properly. Here is how it works:
If you touch the EditText, the keyboard comes up correctly, but if you press any key, nothing happens.
Hide the keyboard with the back button
If you touch the EditText again it works correctly
I tried to debug it and first time FocusChange event fires twice, first with the HasFocus = true, and second time with HasFocus = false.
Any suggestions what am I doing wrong?
UPDATE
Here is what solved my problem:
I set this to my ListView in XML:
android:descendantFocusability="afterDescendants"
And to my ListView in code:
ListView.ItemsCanFocus = true;
And this to my EditText:
android:focusableInTouchMode="true"
android:focusable="true"
And Voilá it works like a charm. Thank you Bradley!

I would suggest putting the EditText above your ListView in the layout xml instead of adding it to the header.
I have ran into this situation before and could never get 100% reliability out of a single solution. If a brute force approach is the only solution, try different combinations of the following properties on the ListView object: DescendantFocusability, ItemsCanFocus, Focusable.

Related

TextBox loses focus in listview when first character is typed

I am stuck with a strange problem for quite a while now. I am using listview to populate my screen. When I type anything in any text box it loses focus when the first element is typed. If I click on the textbox again then everything goes fine and I can type continuously. From the logs I can see that when the first element is typed in any EditText getView() gets called. Once I select the text field again then beforeTextChanged-onTextChanged-afterTextChanged are called continuously which is correct. Can someone help out please. I have tried solutions like making list view height to "fill_parent" and adding android:windowSoftInputMode="adjustPan" to my manifest.xml. Nothing works.
Thanks in advance!
I found the solution. getView() gets invoked internally whenever the screen dimensions are to be ascertained. In my case I had a hidden textview above the editText box. Whenever I was typing something in the editText box I was changing the visibility of the textView from GONE to VISIBLE. That is why the screen placement was changing and so getView() was getting invoked, resulting in the focus being lost. I changed the hidden textView from GONE to INVISIBLE. This way it kept its place in the display and hence even when it became VISIBLE, getView() didnt get invoked.

EditText inside list view android loses focus and data getting copied into another records

I am working on a custom listView which contains editText in every list item.
My listItem is in fragment, and its activity has already adjustResize property which i can not change to adjustPan. Problem is when I click the edittext it is losing focus and even after two three clicks if it gains focus , then upon scrolling that value gets copied into another records and keyboard gets hanged.
I am using
android:descendantFocusability="beforeDescendants"
on my listView. Also i am using ViewHolder pattern in my adapter . Any tested links or working piece of code is really appreciated.
I had a similar issue dealing with RecyclerView with EditText's in the rows recently so this might help you.
When the keyboard comes up your list resizes and maybe the row that caused the keyboard to come up is not visible any more. You need to scroll to it and give it focus back.
How would you know that the keyboard is up? There is no elegant way, I do it by setting GlobalLayoutListener on the recyclerView, saving it's original size, and listening for a smaller size being reported. Search for "android keyboard listener" and you'll find some code.
When user taps on a EditText save the position of the row.
Listen for global layout changes to figure out that the keyboard is up.
Scroll to the row with the saved position.
Give the EditText focus. (probably in a posted Runnable to wait for the scroll to actually happen)

Android RecyclerView Edittext issue

I'm creating a list of editable items (received from backend). I'm using the "new" recyclerview for this. There a couple of possible viewTypes in my recyclerview:
checkbox
spinner
edittext
The problem I'm having is with the EditText gaining focus. AdjustResize kicks in fine and my keyboard is shown. But the EditText that has gained focus isn't visible anymore in the list. (position in the list in the now resized portion is below the visible positions). I don't want to be using AdjustPan in this case because on top there is a pager & stuff I would like to keep fixed there..
This is happening because, at the time the keyboard is shown, your EditText does not exist anymore. I have made several attempts to find a clean solution to this problem maintaining adjustResize input mode and good user experience. Here's what I ended up with:
To ensure that EditText is visible before the keyboard is shown, you will have to scroll the RecyclerView manually and then focus your EditText.
You can do so by overriding focus and click handling in your code.
Firstly, disable focus on the EditText by setting android:focusableInTouchMode property to false:
<EditText
android:id="#+id/et_review"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:focusableInTouchMode="false"/>
Then you have to set a click listener for the EditText where you will manually scroll the RecyclerView and then show the keyboard. You will have to know the position of your ViewHolder which contains the EditText:
editText.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
// you may want to play with the offset parameter
layoutManager.scrollToPositionWithOffset(position, 0);
editText.setFocusableInTouchMode(true);
editText.post(() -> {
editText.requestFocus();
UiUtils.showKeyboard(editText);
});
}
});
And finally, you must make sure that the EditText is made not focusable again when it naturally looses focus:
editText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
editText.setFocusableInTouchMode(false);
UiUtils.hideKeyboard();
}
}
});
This is far from a simple and clean solution, but hope it will help the way it helped me.
I've had the same issue. Long story short - there is no right and elegant solution. Focus handling was always a big pain in Android.
There multiple reasons why you are loosing focus:
Keyboard hides the descendant EditText views
Next EditText is not rendered, because RecycleView hasn't even created a ViewHolder for it. Example: you have 10 views, and 5 of them are on screen and others aren't visible, because those are below.
Some other view consumes focus, in example CheckBox or some DatePicker
RecyclerView due to scroll events consumes focus
Bunch of other hidden under-the-hood stuff
Few words in terms of architecture and structural approach in my solution:
Everything works with Data binding
RecyclerView works with Adapter that supports AdapterDelegate approach
Each EditText, Spinner, DatePicker, CheckBox or RadioButton group is a separate ViewModel which is a separate unit and handles a lot of stuff on its own.
I've used a lot of tricks and mixed them together. As someone already mentioned, the first step would be to add those params to your RecyclerView:
android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true"
Base view model for all possible inputs has defined interface, let's call it SingleInputViewModel, among that interface you can have defined next functions/methods:
void onFocusGained();
void onFocusLost();
boolean isFocusable();
In each particular input item implementation you are able to control focus, for example you are able to implement CheckBox as non-focusable and focus will jump to next isFocusable() == true item. Also you will be able to control the state and action depending on consuming/gaining focus on particular view.
Next step for fixing some of the focus passing issues - was scrolling RecyclerView when IME_ACTION_NEXT occurs. In such case you need to delegate your scroll logic to LayoutManager.scrollHorizontallyBy() or LayoutManager.scrollToPosition() with calculating appropriate offset or position.
Hard and elegant approach is to override logic inside LayoutManager, which is also responsible for focus handling. LinearLayoutManager has a lot of hidden logic, which you won't be able to override, so probably you will need to write a lot of code from scratch.
And the last and the most complex way to fix that is to extend RecyclerView and override focus search related funs/methods:
RecyclerView.focusSearch()
RecyclerView.isPreferredNextFocus()
RecyclerView.onRequestFocusInDescendants()
RecyclerView.onFocusSearchFailed()
RecyclerView.onInterceptFocusSearch()
RecyclerView.onRequestChildFocus()
P.S. Have a look at the FocusFinder and it's usage, just for general knowledge. Now you have few option to choose. I hope you will find something helpful. Good luck!
Using this in layout worked :
android:descendantFocusability="beforeDescendants"
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:descendantFocusability="beforeDescendants"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/extrasLayout"
android:layout_below="#+id/anchorView"
android:layout_marginTop="#dimen/margin5"
android:fastScrollEnabled="false"
/>
Manifest file : Add this to the activity section android:windowSoftInputMode="stateHidden|adjustPan"
<activity
android:name=".activites.CartActivity"
android:label="#string/title_activity_cart"
android:exported="true"
android:windowSoftInputMode="stateHidden|adjustPan"
android:parentActivityName=".activites.HomeActivity"
android:screenOrientation="portrait">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activites.HomeActivity"/>
</activity>
Ok
I found a solution for this problem
I'm using a library for that and it solved easily.
when you make your recyclerView by this template, it solves this problem automatically.
NOTE: for checkbox and radiobutton only
use this
https://github.com/TakeoffAndroid/RecyclerViewTemplate
I'm going to post my solution because after 2 days being blocked by this I hope that it could help someone else.
My issue was that the RecyclerView was a wrap_content on the height, meaning it didn't have a fixed height, and every time i clicked for the first time on one of the edit text inside it, it wasn't giving the focus on the first tap, but it was just showing the keyboard, on the second tap it was gaining the focus.
The fix was to make sure the RecyclerView has a fixed height or match_parent, i don't really know why but this worked for me!
Hope it helps
I put all these three things in recyclerview finally it stopped recyclerview edittext gaining focus
android:descendantFocusability="beforeDescendants"
android:focusable="true"
android:focusableInTouchMode="true"
This is happening because from the android 9.0 you have to write post()-> to gain focus of edittext in Previous versions you can just put
edittext.requestFocus();
but from 9.0 you have to run thread to gain focus of edittext like this
et.post(() -> {et.requestFocus();});
You can scroll recyclerview to selected recycler item position on edit text focus change listener . Have a look at link to use scroll option How to use RecyclerView.scrollToPosition() to move the position to the top of current view?

ListView row with EditText, clickability, and context menu -- how to put it together?

I have a ListActivity-based activity that uses a context menu for the items. After adding an EditText to the row of a ListView, the context menu stopped working, and also the item does not react on a click. It seems that it is blocked somehow by the focus of the EditText. I can enter the EditText value, but I cannot get the earlier context menu, and I cannot start another activity via clicking the item.
I have possibly found the related comment that says:
Android doesn't allow to select list items that have focusable elements (buttons). Modify the button's xml attribute to:
android:focusable="false"
It should still be clickable, just won't gain focus...
... so I did the same for the EditText (I am not sure if the button case can be generalized for the EditText). Anyway, the item is clickable again, the context menu appears... However, the EditText part of the text stopped working now. (Actually, I did not implement the reaction to the EditText -- the keyboard simply does not appear.)
Is it possible to have the clickability of the list item and also make the EditText work the expected way?
I don't know if this would help you but it is a post I've found when I was trying to use a ListView with buttons inside.
ListView Tips & Tricks #4: Add Several Clickable Areas
Hope this helps.

Android GridView focus order

Help me, please! How can I set an order to changing focus in gridview with edittexts?
Now it looks like this:
(1)(2)(3)
(4)(5)(6)
(7)(8)(9)
When I press "Next" on keyboard, focus move 1-4-7 finish 2-5-8 finish 3-6-9. I need 1-2-3-4-5-6-7-8-9... items adding dynamically.
Get an instance of your EditText in the code, then call edittext1.setNextFocusDownId(R.id.edittext2); and hence do this for all youre EditText.

Categories

Resources