Android Accessibility issues - android

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.

Related

Android - requestFocus to off screen element in recyclerView

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.

Android Spinner does not close after using setSelection()

I have a scenario where I want to programmatically change the value of my spinner using setSelection(). This works great, except that if the spinner is open (expanded?) an the time, the spinner does not close. Eg, the menu stays up, despite calling setSelection().
How can I programmatically close the spinner? I have tried performClick() to no avail.
edit: more details:
The reason I'm trying to do this is that my spinner actually uses a compound layout for each selection row. Namely, I have a linearlayout which contains an image, text, and button. The idea was that the button serves as an "edit" button (which opens an activity), while pressing on the image/text select the row (per usual).
The problem came when I added the button. Suddenly, the image & text no longer captured the press event to change the combo. In other words, adding a button to the row destroyed the touch-handling capacity of the entire row. So I tried to manually implement a click handler for the image/text, which subsequently executed a setSelection... which is where I ran into this problem.
You say that after adding the button you lost the click handle on the entire row. Try adding this android:descendantFocusability="blocksDescendants" to your row layout, and see if you can get the clicks to work properly.

Android - Trackball, ListView Visibility Gone Error

I have a listview that displays a list of profiles added by a user. If no profiles exist, I set the listview visibility to "gone".
I have a context menu on the listview that allows a user to delete a profile. When doing this, I display a dialog window to confirm they want to delete the profile.
If the user selects "Yes" on the dialog by touching the button, everything works fine.
If the user selects "Yes" using the trackball, then touches the screen, the app crashes.
I can prevent the crash by commenting out the line of code that sets the listview visibility to "gone". I'm curious what's causing the crash (want to understand).
The error seems misleading to me, which is:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread
The adapter that the ListView was using just needed to be notified that the data changed (notifyDataSetChanged()). Still not sure why the behavior is different between using the trackball vs touch, but I have a better understanding of how the adapter works now.

On Android, click to expand list -and- click on a button?

I have just started my career as an android programmer, and am currently relying heavily on the sample code and api examples. I have been working with this api example, to produce an expandable list of items (note this example does not use the ExpadableListView).
In playing with the example, I tried to add another widget that would become visible and be gone at the same time as the text (mDialogue in the sample code). This works well with another TextView, but as soon as I tried to add a button widget, it stopped working. The list would expand on first click, showing my hidden TextView and Button, but it will not disappear on further clicks. The button is however, clickable, and I was able to set up an onClick listener to change the button text back and forth.
I'm starting to wonder, is it just not possible to have a clickable item inside a clickable list item? Or is there some kind of work around? Would it solve my problem if I used ExpandableListView?
You have two options of how to handle focus within a ListView controlled by ListView#setItemsCanFocus(boolean). If you want individual Views within a list item to focus so that the user can interact with them individually instead of with the list item as a whole, call it passing true. false is the default behavior.
The default behavior where ListView manages item focus and clicks is basically a shortcut/optimization for the common case where the whole item acts as a single unit from an interaction standpoint, but its layout may be complex. When you tell ListView that its items can focus it disables this special behavior and you should use the more traditional mechanisms of handling events on the Views within the list items. (Listeners, overridden on* methods, etc.)
But why do your list items stop taking clicks when your ListView isn't set up for focusable items? ListView will only generate item click events if the list item view returns false from View#hasFocusable(). This means no children of the list item can be focusable if you want to receive item click events for it. As soon as your button becomes visible, the list item has a focusable child and will no longer receive list item click events.

How do I programmatically select an item in a listview in Android

I am displaying a radio schedule in a List View and would like to highlight the currently playing program. I also want to allow the user to click on any program and get more details for the program. I have tried the following:
radioView.setSelection(adapter.getCurrentProgramIndex());
radioView.setSelected(true);
This does scroll the list down to the selection which is good, but it does not highlight the selection. I understand this is because the device is not in touch mode, but how then would I go about highlighting the current program?
how then would I go about highlighting
the current program?
Change something in that list row. For example, perhaps you have an icon you can switch to be a "playing" icon, or have an icon that is formerly INVISIBLE become VISIBLE, or something.
Bear in mind that you will need to have these smarts in your row binding code, so that if the user scrolls, you correct undo and redo that setting -- otherwise, row recycling will make it appear that other programs are playing.

Categories

Resources