Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(android): ListView tap not working after setting children as focusable #10522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 19, 2024

Conversation

CatchABus
Copy link
Contributor

PR Checklist

What is the current behavior?

We had reports that android ListView itemTap event stopped working at core 8.7 and later.
The problem seemed to be that ListView proxy views became focusable due to some a11y calls, thus breaking native item click listener. A thread in StackOverflow explains why ListView does not operate well if list items become focusable: https://stackoverflow.com/questions/11610023/click-is-not-working-on-the-listitem-listview-android

What is the new behavior?

Views will become focusable or non-focusable only when needed.

This is a continuation of the previous fix related to WebView accessibility focus: 92b2ff8

@farfromrefug Let me know if there's room for any improvements.

@cla-bot cla-bot bot added the cla: yes label Apr 18, 2024
@CatchABus CatchABus changed the title fix(android): ListView tap not working after setting layout children as focusable fix(android): ListView tap not working after setting children as focusable Apr 18, 2024
@farfromrefug
Copy link
Collaborator

farfromrefug commented Apr 18, 2024

@CatchABus only issue I see is that it is not synced with isUserInteractionEnabled.if accessibility is disabled then focusable seems to not be linked to isUserInteractionEnabled
EDIT: Thinking about this more. So if i understand correctly the issue with ListView is that isUserInteractionEnabled is bound in N to setFocusable, and setFocusable breaks itemTap event?
So what i personally see:

  • this PR breaks setFocusable sync with accessibilityEnabled/isUserInteracationEnabled for other views (which was broken already in my first PR)
  • we need a way to "prevent" setFocusable call on ListView content view WITHOUT changing any behavior when views are outside ListView => the fix should be in ListView component
  • i am starting to wonder is setting default to false for accessibilityEnabledProperty here is not the right way to set the default. Doing so seems to implies a call to accessibilityEnabledProperty.setNative for all views with the default (which i seem to have thought it would not)
  • just as a remark i remove itemTap event in CollectionView because it was simply not consistent. Now users simply needs to use tap event on templates. Same results, less complications

@CatchABus
Copy link
Contributor Author

CatchABus commented Apr 18, 2024

@CatchABus only issue I see is that it is not synced with isUserInteractionEnabled.if accessibility is disabled then focusable seems to not be linked to isUserInteractionEnabled

We still have the following scenario. We have this view:

<stacklayout></stacklayout>

Even though isUserInteraction is true by default, the native view of this layout will still be non-focusable on initialization.
So we have a lack of sync regardless of accessible value.
What we might need to check this correctly is:

this.isUserInteractionEnabled && this.nativeViewProtected.isFocusable()

So if we keep isUserInteractionEnabled and considering all the points above, it's possible to reduce changes to:

[accessibilityEnabledProperty.setNative](value) {
        // ensure `accessibilityEnabled=false` does not disable focus for view with `isUserInteractionEnabled=true`
        this.nativeViewProtected.setFocusable(!!value || this.isUserInteractionEnabled && this.nativeViewProtected.isFocusable());
        if (value) {
            updateAccessibilityProperties(this);
        }
    }

What do you think?

@CatchABus CatchABus marked this pull request as draft April 18, 2024 07:21
@CatchABus CatchABus marked this pull request as ready for review April 18, 2024 07:37
@farfromrefug
Copy link
Collaborator

@CatchABus You are right. Feels like a lot of things need to be fixed there.
So what about in the way you did it, store isFocusable default (in createNativeView cause initNativeView is too late as it can be modified by us), then use that default to know if we want to setFocusable when setting isUserInteractionEnabled/accessibilityEnabled to true (or anywhere else really). It could even be cached on a native class bases like Ammar did it for padding?
I still believe we should not go through accessibilityEnabledProperty.setNative for the default value. Will check this

@CatchABus CatchABus marked this pull request as draft April 18, 2024 08:26
@CatchABus CatchABus force-pushed the android-a11y-focusable-fix branch from 6e10d9b to 87a5a92 Compare April 18, 2024 12:11
@CatchABus CatchABus marked this pull request as ready for review April 18, 2024 15:36
@NathanWalker NathanWalker merged commit 03268cc into NativeScript:main Apr 19, 2024
3 checks passed
@dangrima90
Copy link

@CatchABus @farfromrefug @NathanWalker The change done here https://github.com/NativeScript/NativeScript/pull/10522/files#diff-ff996ba7476badc71c6c2ce6924be412385d3ea43a8785248a28159b3f7d203eR19 is breaking Maestro tests on Android.

For example I have a test where a StackLayout has a test id, however it is not being applied.

<StackLayout :testID="item.testId" class="mt-10">
   <!-- .... -->
 </StackLayout>

I understand that there's a TODO comment to update this eventually, but in the meantime is there a way to workaround this? With this update Android is untestable.

@dangrima90
Copy link

Update in relation to my above comment:

Adding :accessible="true" on the element seems to solve the issue:

<StackLayout :testID="item.testId" :accessible="true" class="mt-10">
   <!-- .... -->
 </StackLayout>

Of course this would mean that we'd need to go through all of our code and see where this is needed.

@CatchABus
Copy link
Contributor Author

Update in relation to my above comment:

Adding :accessible="true" on the element seems to solve the issue:

<StackLayout :testID="item.testId" :accessible="true" class="mt-10">
   <!-- .... -->
 </StackLayout>

Of course this would mean that we'd need to go through all of our code and see where this is needed.

This PR along with the referenced one are attempts to keep things stable with changes in #10482.
@farfromrefug I wonder whether we should find an appropriate fix or revert the whole update until we find a better way.

@farfromrefug
Copy link
Collaborator

@CatchABus Here i will let N team decide what to do. In my fork i decided to disable accessibility by default on views so i dont have that commit https://github.com/NativeScript/NativeScript/pull/10522/files#diff-ff996ba7476badc71c6c2ce6924be412385d3ea43a8785248a28159b3f7d203eR19.
You can either revert or try to fix it. Maybe a solution would be to set accessible to true when testID is set? It kind of make sense to enforce

@dangrima90
Copy link

@NathanWalker @CatchABus, any ideas on a way forward here please?

As a summary with the above changes I see two main issues:

  1. Android app cannot be tested via Maestro unless each and every element that is to be accessed during testing has accessible set to true.
  2. It's important to also keep in mind that if changes are made the focus shouldn't only be in relation to getting end-to-end tests working, but also keep accessibility in mind. Not sure if you are aware but in the EU soon it will be mandated for software to offer accessibility features and be transparent as to which areas of the application are accessible friendly. (Short article about the impact of the change: https://vaimo.com/blog/the-european-accessibility-act-2025-what-businesses-need-to-do/; Full EU Document: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32019L0882)

@CatchABus
Copy link
Contributor Author

@NathanWalker @CatchABus, any ideas on a way forward here please?

As a summary with the above changes I see two main issues:

  1. Android app cannot be tested via Maestro unless each and every element that is to be accessed during testing has accessible set to true.
  2. It's important to also keep in mind that if changes are made the focus shouldn't only be in relation to getting end-to-end tests working, but also keep accessibility in mind. Not sure if you are aware but in the EU soon it will be mandated for software to offer accessibility features and be transparent as to which areas of the application are accessible friendly. (Short article about the impact of the change: https://vaimo.com/blog/the-european-accessibility-act-2025-what-businesses-need-to-do/; Full EU Document: https://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX%3A32019L0882)

These points are definitely important but not connected to the current PR as it's a fix addition on top of another 2 PRs and doesn't implement optional a11y focus itself.
Please create an issue so that we can keep track of it.

@CatchABus
Copy link
Contributor Author

@CatchABus Here i will let N team decide what to do. In my fork i decided to disable accessibility by default on views so i dont have that commit https://github.com/NativeScript/NativeScript/pull/10522/files#diff-ff996ba7476badc71c6c2ce6924be412385d3ea43a8785248a28159b3f7d203eR19. You can either revert or try to fix it. Maybe a solution would be to set accessible to true when testID is set? It kind of make sense to enforce

@farfromrefug @dangrima90 @NathanWalker I believe we should proceed with reverting all recent a11y changes related to this until we come with a good solution that's tested thoroughly.

@farfromrefug
Copy link
Collaborator

@CatchABus i say yes.

@CatchABus
Copy link
Contributor Author

@dangrima90 Core 8.8.6 should take care of it. Let us know.

@dangrima90
Copy link

Hi @CatchABus I can confirm that I was able to successfully access elements via testID when using 8.8.6 on Android.

@CatchABus
Copy link
Contributor Author

Hi @CatchABus I can confirm that I was able to successfully access elements via testID when using 8.8.6 on Android.

Thank you so much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants