mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
a11y: expose max character count for text fields (#12269)
This commit is contained in:
parent
3b6c08d572
commit
ef7bcafd5c
@ -618,9 +618,16 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 {
|
||||
/// string describes what result an action performed on this node has. The
|
||||
/// reading direction of all these strings is given by `textDirection`.
|
||||
///
|
||||
/// The fields 'textSelectionBase' and 'textSelectionExtent' describe the
|
||||
/// The fields `textSelectionBase` and `textSelectionExtent` describe the
|
||||
/// currently selected text within `value`.
|
||||
///
|
||||
/// The field `maxValueLength` is used to indicate that an editable text field
|
||||
/// has a limit on the number of characters entered. If it is -1 there is
|
||||
/// no limit on the number of characters entered. The field
|
||||
/// `currentValueLength` indicates how much of that limit has already been
|
||||
/// used up. When `maxValueLength` is set, `currentValueLength` must also be
|
||||
/// set.
|
||||
///
|
||||
/// The field `platformViewId` references the platform view, whose semantics
|
||||
/// nodes will be added as children to this node. If a platform view is
|
||||
/// specified, `childrenInHitTestOrder` and `childrenInTraversalOrder` must be
|
||||
@ -652,6 +659,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 {
|
||||
int id,
|
||||
int flags,
|
||||
int actions,
|
||||
int maxValueLength,
|
||||
int currentValueLength,
|
||||
int textSelectionBase,
|
||||
int textSelectionExtent,
|
||||
int platformViewId,
|
||||
@ -683,6 +692,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 {
|
||||
id,
|
||||
flags,
|
||||
actions,
|
||||
maxValueLength,
|
||||
currentValueLength,
|
||||
textSelectionBase,
|
||||
textSelectionExtent,
|
||||
platformViewId,
|
||||
@ -713,6 +724,8 @@ class SemanticsUpdateBuilder extends NativeFieldWrapperClass2 {
|
||||
int id,
|
||||
int flags,
|
||||
int actions,
|
||||
int maxValueLength,
|
||||
int currentValueLength,
|
||||
int textSelectionBase,
|
||||
int textSelectionExtent,
|
||||
int platformViewId,
|
||||
|
||||
@ -93,6 +93,8 @@ struct SemanticsNode {
|
||||
int32_t id = 0;
|
||||
int32_t flags = 0;
|
||||
int32_t actions = 0;
|
||||
int32_t maxValueLength = -1;
|
||||
int32_t currentValueLength = -1;
|
||||
int32_t textSelectionBase = -1;
|
||||
int32_t textSelectionExtent = -1;
|
||||
int32_t platformViewId = -1;
|
||||
|
||||
@ -40,6 +40,8 @@ void SemanticsUpdateBuilder::updateNode(
|
||||
int id,
|
||||
int flags,
|
||||
int actions,
|
||||
int maxValueLength,
|
||||
int currentValueLength,
|
||||
int textSelectionBase,
|
||||
int textSelectionExtent,
|
||||
int platformViewId,
|
||||
@ -74,6 +76,8 @@ void SemanticsUpdateBuilder::updateNode(
|
||||
node.id = id;
|
||||
node.flags = flags;
|
||||
node.actions = actions;
|
||||
node.maxValueLength = maxValueLength;
|
||||
node.currentValueLength = currentValueLength;
|
||||
node.textSelectionBase = textSelectionBase;
|
||||
node.textSelectionExtent = textSelectionExtent;
|
||||
node.platformViewId = platformViewId;
|
||||
|
||||
@ -26,6 +26,8 @@ class SemanticsUpdateBuilder
|
||||
void updateNode(int id,
|
||||
int flags,
|
||||
int actions,
|
||||
int maxValueLength,
|
||||
int currentValueLength,
|
||||
int textSelectionBase,
|
||||
int textSelectionExtent,
|
||||
int platformViewId,
|
||||
|
||||
@ -35,6 +35,8 @@ class SemanticsNodeUpdate {
|
||||
this.id,
|
||||
this.flags,
|
||||
this.actions,
|
||||
this.maxValueLength,
|
||||
this.currentValueLength,
|
||||
this.textSelectionBase,
|
||||
this.textSelectionExtent,
|
||||
this.platformViewId,
|
||||
@ -67,6 +69,12 @@ class SemanticsNodeUpdate {
|
||||
/// See [ui.SemanticsUpdateBuilder.updateNode].
|
||||
final int actions;
|
||||
|
||||
/// See [ui.SemanticsUpdateBuilder.updateNode].
|
||||
final int maxValueLength;
|
||||
|
||||
/// See [ui.SemanticsUpdateBuilder.updateNode].
|
||||
final int currentValueLength;
|
||||
|
||||
/// See [ui.SemanticsUpdateBuilder.updateNode].
|
||||
final int textSelectionBase;
|
||||
|
||||
|
||||
@ -648,6 +648,8 @@ class SemanticsUpdateBuilder {
|
||||
int id,
|
||||
int flags,
|
||||
int actions,
|
||||
int maxValueLength,
|
||||
int currentValueLength,
|
||||
int textSelectionBase,
|
||||
int textSelectionExtent,
|
||||
int platformViewId,
|
||||
@ -676,6 +678,8 @@ class SemanticsUpdateBuilder {
|
||||
id: id,
|
||||
flags: flags,
|
||||
actions: actions,
|
||||
maxValueLength: maxValueLength,
|
||||
currentValueLength: currentValueLength,
|
||||
textSelectionBase: textSelectionBase,
|
||||
textSelectionExtent: textSelectionExtent,
|
||||
scrollChildren: scrollChildren,
|
||||
|
||||
@ -564,6 +564,14 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
|
||||
granularities |= AccessibilityNodeInfo.MOVEMENT_GRANULARITY_WORD;
|
||||
}
|
||||
result.setMovementGranularities(granularities);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && semanticsNode.maxValueLength >= 0) {
|
||||
// Account for the fact that Flutter is counting Unicode scalar values and Android
|
||||
// is counting UTF16 words.
|
||||
final int length = semanticsNode.value == null ? 0 : semanticsNode.value.length();
|
||||
int a = length - semanticsNode.currentValueLength + semanticsNode.maxValueLength;
|
||||
result.setMaxTextLength(length - semanticsNode.currentValueLength + semanticsNode.maxValueLength);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// These are non-ops on older devices. Attempting to interact with the text will cause Talkback to read the
|
||||
@ -1719,6 +1727,8 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
|
||||
|
||||
private int flags;
|
||||
private int actions;
|
||||
private int maxValueLength;
|
||||
private int currentValueLength;
|
||||
private int textSelectionBase;
|
||||
private int textSelectionExtent;
|
||||
private int platformViewId;
|
||||
@ -1858,6 +1868,8 @@ public class AccessibilityBridge extends AccessibilityNodeProvider {
|
||||
|
||||
flags = buffer.getInt();
|
||||
actions = buffer.getInt();
|
||||
maxValueLength = buffer.getInt();
|
||||
currentValueLength = buffer.getInt();
|
||||
textSelectionBase = buffer.getInt();
|
||||
textSelectionExtent = buffer.getInt();
|
||||
platformViewId = buffer.getInt();
|
||||
|
||||
@ -227,7 +227,7 @@ void PlatformViewAndroid::DispatchSemanticsAction(JNIEnv* env,
|
||||
void PlatformViewAndroid::UpdateSemantics(
|
||||
flutter::SemanticsNodeUpdates update,
|
||||
flutter::CustomAccessibilityActionUpdates actions) {
|
||||
constexpr size_t kBytesPerNode = 39 * sizeof(int32_t);
|
||||
constexpr size_t kBytesPerNode = 41 * sizeof(int32_t);
|
||||
constexpr size_t kBytesPerChild = sizeof(int32_t);
|
||||
constexpr size_t kBytesPerAction = 4 * sizeof(int32_t);
|
||||
|
||||
@ -261,6 +261,8 @@ void PlatformViewAndroid::UpdateSemantics(
|
||||
buffer_int32[position++] = node.id;
|
||||
buffer_int32[position++] = node.flags;
|
||||
buffer_int32[position++] = node.actions;
|
||||
buffer_int32[position++] = node.maxValueLength;
|
||||
buffer_int32[position++] = node.currentValueLength;
|
||||
buffer_int32[position++] = node.textSelectionBase;
|
||||
buffer_int32[position++] = node.textSelectionExtent;
|
||||
buffer_int32[position++] = node.platformViewId;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user