0

I enabled the Talkback feature on the phone.

The user makes a touch wipe gesture to the right to select/highlight/etc the next item in the list. I want to have the index of this newly selected element in the list.

I am trying to get the index of the new selected Item from a ListView.

listView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
        @Override
        public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {
            if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
                int selectedItemPosition = event.getSelectedItemPosition(); // doesn't work, returns always -1
                  }
        }
});

Edit 1: listView.getSelectedItemPosition() returns -1 all the time after selecting another element with TalkBack.

Quonux
  • 2,975
  • 1
  • 24
  • 32

1 Answers1

1

Nothing about this problem (the problem of getting the ListView selected item index) is particular to, nor should be accomplished by, use of the accessibility apis.

Documentation for the "getToIndex()" function:

Gets the index of text selection end or the index of the last visible item when scrolling.

It seems from your clarification and your code, namely this line:

event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) 

That what you're really looking for is the view that just received ACCESSIBILITY_FOCUS, and NOT the view that is "selected". These are very different. I would definitely recommend changing this

int selectedItemPosition = ...

To

int a11yFocusedItemPosition = ...

Which is MUCH more clear. "Selected" means something very specific in terms of list views, and this is confusing things. Assuming Accessibility Focus is in fact the thing that you're looking for, this should do nicely:

listView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
    @Override
    public boolean onRequestSendAccessibilityEvent(ViewGroup host, View child, AccessibilityEvent event) {

        if (event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
            int accessibilityFocusedItemIndex = -1;

            for (int i = 0; i < host.getChildCount(); i++) {
                if (host.getChildAt(i) == child) {
                    accessibilityFocusedItemIndex = i;
                    break;
                }
            }

            Log.d("LogTag", "Accessibility Focused Item Index: " + accessibilityFocusedItemIndex);
        }

        return super.onRequestSendAccessibilityEvent(host, child, event);
    }
});

Note that list view is a special case where a function like this manages to work, because the focusable child is usually a direct descendant of the host view. This may not be true for individual active elements not wrapped within the list view cell.

MobA11y
  • 18,425
  • 3
  • 49
  • 76
  • nice try but see my edit, it returns the same, which is -1...I just guessed the method name... – Quonux Sep 08 '17 at 17:10
  • That is likely because there is no selected item, which again brings me back to wording your post to be more "purposely" oriented. What are you trying to accomplish? Because as far as I'm concerned, -1 is probably what you should expect, you just don't know why you should expect it, so it is confusing you. Edit your question to be in terms of what user facing change you're trying to accomplish, what is you're going to do with the "selectedItemPosition" should you find it and that value make sense to you. – MobA11y Sep 08 '17 at 17:18
  • Note: a view being "accessibility_focused" and "selected" are SUPER DIFFERENT. Are you looking for the view that just got focused, or the view that just got selected? Note that a view is not "selected" until it has been activated, which is why you're getting -1. – MobA11y Sep 08 '17 at 17:20
  • Which brings me back to... wording your question in terms of user experience, and not code. Because you are DEFINITELY using Android code specific terms in here non-idiomatically. – MobA11y Sep 08 '17 at 17:21
  • I suspect that you might want to change "selectedItemPosition" to "focusedItemPosition" but this is only a guess. ALthough again, focus is an input mechanism. So you probably ACTUALLY mean "accessibilityFocusedItemPosition" but even THEN why you would care about this and what you would do with it is not clear. – MobA11y Sep 08 '17 at 17:24
  • I have no idea. The user (in this case just me for now) makes a touch wipe gesture to the right to select/highlight/etc the next item in the list. I want to have the index of this stupid thing in the list. – Quonux Sep 08 '17 at 17:45
  • listView.focusedItemPosition(); this doesn't exist, what do you mean? – Quonux Sep 08 '17 at 17:57
  • Of course that function doesn't exist. I mean in your question it is NOT clear what you're actually looking for. The "selected" item, the "focused" item, or the "AccessibilityFocused" item. – MobA11y Sep 08 '17 at 19:09
  • Not only this, but it is not clear what you intend on doing with this information once you have it. I find it likely that you're trying to do something in a silly way, and there might be a much easier way to accomplish what you want, outside of this silly mechanism you're attempting to implement. – MobA11y Sep 08 '17 at 19:10
  • I am designing an application for visually impaired people. I must send the input on the phone to a Computer over Bluetooth. On the Computer is another program running which decides whats done with the input. It can push another Activity or update the list (which is listView). The input to the Computer is the action of the user. If the user switches the highlight I/the computer/host has to know it. It is that simple. If we don't find a solution to this, fine. – Quonux Sep 09 '17 at 00:51
  • It's not a hard problem. You're question is not clear, I believe I understand now. Check out my edits. – MobA11y Sep 09 '17 at 02:48
  • Why not this method? https://developer.android.com/reference/android/view/accessibility/AccessibilityRecord.html#getCurrentItemIndex() – OneCricketeer Sep 09 '17 at 02:54
  • That method is designed for AccessibilityServices to use, and the accuracy of the information cannot be relied upon application side. In fact, at this point in the accessibility event cycle, an AccessibilityEvent won't even have an AccessibilityRecord associated with it. – MobA11y Sep 09 '17 at 02:59