Android - requestFocus to off screen element in recyclerView - android

I am trying to scroll and request focus to an off screen element from a recycler view. I have a list of 15 languages. When app starts the user can select one language from the recycler. Then if the app starts again the recycler scrolls and request focusto that item.
But imagine the user selects the last language from the list which is not showed in the recycler when the app starts. How to scroll and therefore reqeust focus to that element which is not currently showed in the recycler?
I expected to do something like recycler.scrollToPosition(14) and then scrollToPosition(14) , but the index is outof bunds... I guess thats because the element is not created yet. Any idea?

I had similar scenario and below code worked for me:
(rv_your_recycler_view.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(position, offset)
Just set offset to 0 and position to 14, this will get you last item.
P.S. If it doesn't work check if your recyclerview's bottom constraint tied up to parent's bottom.
app:layout_constraintBottom_toBottomOf="parent"

If you try to scroll and set the focus at the same time then it may fail. While the scrolling will proceed, the request for the focus will fail if the item is not yet present in the RecyclerView. (As you state.)
The solution is to separate the two activities. Scroll to the position as you do now, but set the focus when the item is bound to the view holder in the adapter. This will require you to keep track of which item has the focus so that it can be referenced in the adapter.

Related

Android EditText in RecyclerView

I want to implement a search. But unfortunately edit text must be in recycler view. I have multiple types of items.
When user enters a letter I refresh whole adapter, searching is done locally. That means that keyboard disappears and edit text is losing focus, because of this constant updating.
I managed to fix it showing keyboard and focus an edit manually while binding.
if (item.inEditableMode) {
edit_text.requestFocus()
showKeyboard(edit_text)
}
But edit text works not that good as I expect. A problem can be seen when user types fast or wants to clear input.
Thanks for help.
Layout:
"unfortunately edit text must be in recycler view" - I bet it do NOT have to be a part of RecyclerView not part of Adapter list item View. better inspect your layout architecture instead of posted workarounds with hiding-showing (blinking) keyboard
besides that even when it must be then don't notify whole Adapter with notifyDataSetChanged(), instead use notifyItemChanged(...) - notify range of of your items, but not list item with EditText - it won't be redrawn, so keyboard should stay visible and focus kept on that field. still this isn't good approach, your EditText should be separated from RecyclerView almost for shure

Android Accessibility issues

I have couple of issues in the process of making my app accessibility compliant.
I have a spinner with some items in it, after I select one of the item, spinner closes and focus is moving to the top of the page action bar but I want the focus to remain on the last used element i.e, the spinner. Tried:
spinnerId.requestfocus(); or spinnerId.performAccessibilityAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS,null); in the code but nothing worked.
2.How can I set the focus to last accessed element even if onResume(); is called to refresh the data ?
3.Page reverse order doesn't work all the time when I scroll back through the elements.
4.I have a listview with elements populated dynamically, accessibility doesn't scroll the page all the times instead it goes to right fragment( i have left and right fragments in my tablet) skipping the elements below the screen.
As your spinner is already focus, you have to clear this focus, send this event to Accessibility and request it again:
yourView.clearFocus();
yourView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
yourView.requestFocus();
yourView.setFocusableInTouchMode(true);
He took me awhile to find this tricks, but we used it in few different place in our app, and it work well.

How to identify if a row is visible in a listview

I have a situation involving animation of listview's item appearances.
I have a few views in a ScollView , the last of which is the listview. I have attached an appearence animation of the row (a fade in animation).
The problem I have is that when the screen is loaded , the getView() of listview already executes for the initial items , even though the listview is not currently in view.
Hence when a user scroll downs , he sees the list plainly.
I am unsure how to go about this situation . Is there any callback that can be invoked when a row from a listview becomes visible on screen ? .
Yes there is a callback (OnScrollChangeListener), first visible index and last visible index etc. You can achieve what you are trying to using combination of these.
But you need to try that yourself first. No one can simply write a code for you.
You can learn about listview here

knowing what elements of a list view are currently displayed on screen

I would know if there is a way to know if an element of a list view gets out of the list, (i want to know if the fist element is seen on screen or isn't)
in fact what I want to do with that, is that i want the second element of my list (which is the title of the fragment where the list is) to stay blocked as a header when it goes up (like an letter in the contact app).
So what i thought about is to add a hidden clone of the second element above the listview (in the relative layout parent), and set it to visible when the first element goes away of the screen (when the second element is the first element of the seen list).
But maybe is it a native way to do so !
Thanks,
Renaud
You can obtain the first and last visible position in the list at any time using the methods getFirstVisiblePosition() and getLastVisiblePosition() on ListView
HTH

how does scrolling in android listview work?

I have an android-app with a listview in an activity. The listview has, if I call it so, three data states.
no data loaded from inet -> only one dummy item is visible, saying that data is loading;
data is loaded and shown in list;
one listitem is clicked and now shows more information for this listitem (so it is increased in its height).
On every state change (1 -> 2, 2 -> 3), I call notifyDataSetChanged() on this ListAdapater.
This causes the listview to scroll down to the last item. This is ugly in the first transition and even more ugly in the second because the clicked list item is now out of focus.
As I can see, this happens with a google g1 with android 1.6. An htc touch with the same sdk acts like desired (I will try to figure it out with some more devices).
To avoid this, I tried to read out getScrollY() and set this value back. but this returns 0. The reason for this return value I already found on stackoverflow in other questions.
Has anyone else seen this problem? Why does the listview scroll to the last item? It was mentioned that listview keeps track of the scroll position. but it seems that it does not in my case.
Or maybe I am calling the wrong refresh method? Is notifyDataSetChanged the correct one?
I believe you want:
listview.setTranscriptMode(ListView.TRANSCRIPT_MODE_DISABLED);

Categories

Resources