Skip to content

Add support for custom accessibility actions to android and iOS.#18882

Merged
jonahwilliams merged 24 commits intoflutter:masterfrom
jonahwilliams:contextAction2
Jul 20, 2018
Merged

Add support for custom accessibility actions to android and iOS.#18882
jonahwilliams merged 24 commits intoflutter:masterfrom
jonahwilliams:contextAction2

Conversation

@jonahwilliams
Copy link
Contributor

@jonahwilliams jonahwilliams commented Jun 27, 2018

Fixes #18432

@jonahwilliams jonahwilliams requested a review from goderbauer July 18, 2018 19:15
@jonahwilliams
Copy link
Contributor Author

  • @Hixie @goderbauer this PR is blocking customer mulligan from having accessibility for the reorder-able list.

config.onDidLoseAccessibilityFocus = _performDidLoseAccessibilityFocus;
if (customAccessibilityActions != null) {
config.customAccessibilityActions = _customAccessibilityActions;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please be consistent with nearby code regarding braces, to make the code easier to read

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

String toString() => '$runtimeType($name)';
}

/// A custom accessibility action.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not a helpful description since it's exactly the class name. :-)

The first line should be a brief but still useful description. It appears in documentation summaries (e.g. in the library-level docs).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

});
}


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove extra line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

return new Semantics(
customAccessibilityActions: <CustomAccessibilityAction, VoidCallback>{
const CustomAccessibilityAction(label: 'Archive'): () {
setState(() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe factor this out into a method so the same code can be used for the dismisable (when the user swipes) and the custom a11y action?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

)
)
)
),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: is formatting off here somehow? Looks strange to have to closing ) with the same indentation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


/// A map from each supported [CustomAccessibilityAction] to a provided handler.
///
/// The handler associated with each custom action is invoked whenever a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc comment seems to describe impl details? Maybe rephrase it a little and focus on what I as a user of this could do with it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

/// Custom accessibility actions can be provided to make complex user
/// interactions more accessible. A drag and drop list, for example, may
/// require a user to press and hold an item to move it. This may be
/// difficult for a user interacting with your app using a hardware switch. A
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

avoid refering to "your" app; the reader may not be the person whose app they're trying to understand
Prefer something like "For instance, if an application has a drag-and-drop list that requires the user to press and hold an item to move it, users interacting with the application using a hardware switch may have difficulty."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I incorporated this suggestion and did a pass on the entire doc comment.

/// interactions more accessible. A drag and drop list, for example, may
/// require a user to press and hold an item to move it. This may be
/// difficult for a user interacting with your app using a hardware switch. A
/// custom accessibility action allows you to specifiy actions such as
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, "allows the application to specify..."

(also, typo on specify)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

/// In Android, these actions are presented in the local context menu. In iOS,
/// these are in the radial context menu.
class CustomAccessibilityAction {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: extraneous blank line

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


/// Creates a new [CustomAccessibilityAction].
///
/// [label] must not be null or the empty string.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider starting with "The [label] argument must..." to avoid starting with a lowercase letter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

///
/// [label] must not be null or the empty string.
const CustomAccessibilityAction({@required this.label})
: assert(label != null && label != '');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer splitting asserts into multiple asserts rather than chaining expressions with &&, it makes it easier to see what went wrong when they fire

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

static int getIdentifier(CustomAccessibilityAction action) {
int result = _ids[action];
if (result == null) {
result =_nextId++;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: missing space after =

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

&& typedOther.scrollExtentMin == scrollExtentMin
&& typedOther.transform == transform;
&& typedOther.transform == transform
&& setEquals(typedOther.customAccessibilityActions, customAccessibilityActions);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yikes, this is one expensive == method

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think replacing the set of custom actions with a sorted list of ints will make this faster...

///
/// See also:
///
/// * [CustomAccessibilityAction], for an explaination of custom actions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: explanation

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

/// A map from each supported [CustomAccessibilityAction] to a provided handler.
///
/// The handler associated with each custom action is invoked whenever a
/// semantics event of type [SemanticsEvent.customEvent] is recieved. The
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: received

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed


/// A map from each supported [CustomAccessibilityAction] to a provided handler.
///
/// The handler associated with each custom action is invoked whenever a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: prefer "called" over "invoked" (see style guide)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@jonahwilliams
Copy link
Contributor Author

I think I addressed most of the comments, PTAL

@jonahwilliams
Copy link
Contributor Author

Since we're going to tie these in with renaming hint text for actions on Android (in a future PR), i've updated the name to CustomSemanticsAction to make the relationship with SemanticsAction more obvious.

Copy link
Member

@goderbauer goderbauer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM


@override
int get hashCode => ui.hashValues(flags, actions, label, value, increasedValue, decreasedValue, hint, textDirection, rect, tags, textSelection, scrollPosition, scrollExtentMax, scrollExtentMin, transform);
int get hashCode => ui.hashValues(flags, actions, label, value, increasedValue, decreasedValue, hint, textDirection, rect, tags, textSelection, scrollPosition, scrollExtentMax, scrollExtentMin, transform, customSemanticsActionIds);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe its time to add some line breaks to this line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


/// A map from each supported [CustomSemanticsAction] to a provided handler.
///
/// The handler associated with each custom action is called whenever a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this doc also be updated to the version you are using above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean the CustomSemanticsAction doc comment?

' mergeAllDescendantsIntoThisNode: false\n'
' Rect.fromLTRB(0.0, 0.0, 0.0, 0.0)\n'
' actions: []\n'
' customActions: []\n'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a test that ensures that custom actions are properly printed when the Semantics tree is printed out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@jonahwilliams jonahwilliams merged commit d2d17ab into flutter:master Jul 20, 2018
@jonahwilliams jonahwilliams deleted the contextAction2 branch July 20, 2018 03:47
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 10, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Accessibility support for custom actions

4 participants