CPVoiceControlTemplate constructor
CPVoiceControlTemplate({
- required List<
CPVoiceControlState> voiceControlStates, - VoidCallback? onDismiss,
- String? id,
Implementation
CPVoiceControlTemplate({
required List<CPVoiceControlState> voiceControlStates,
List<CPBarButton> leadingNavigationBarButtons = const [],
List<CPBarButton> trailingNavigationBarButtons = const [],
this.onDismiss,
String? id,
}) : uniqueId = id ?? const Uuid().v4(),
voiceControlStates = List.unmodifiable(voiceControlStates),
leadingNavigationBarButtons = List.unmodifiable(
leadingNavigationBarButtons,
),
trailingNavigationBarButtons = List.unmodifiable(
trailingNavigationBarButtons,
) {
if (uniqueId.trim().isEmpty) {
throw ArgumentError('Template identifier must not be empty.');
}
if (voiceControlStates.isEmpty ||
voiceControlStates.length > 5 ||
voiceControlStates.map((s) => s.identifier).toSet().length !=
voiceControlStates.length) {
throw ArgumentError(
'Provide one to five voice states with distinct identifiers.',
);
}
final bars = [
...leadingNavigationBarButtons,
...trailingNavigationBarButtons,
];
if (leadingNavigationBarButtons.length > 2 ||
trailingNavigationBarButtons.length > 2 ||
bars.any((b) => b.uniqueId.trim().isEmpty || b.title.trim().isEmpty) ||
bars.map((b) => b.uniqueId).toSet().length != bars.length) {
throw ArgumentError(
'Provide up to two distinct, nonempty navigation buttons per side.',
);
}
// A shared button may be reused in multiple states, but IDs must not name
// different callbacks or collide with navigation buttons.
final seen = <String, Object>{for (final b in bars) b.uniqueId: b};
for (final state in voiceControlStates) {
for (final button in state.actionButtons) {
final previous = seen[button.uniqueId];
if (previous != null && !identical(previous, button)) {
throw ArgumentError(
'Button identifiers must identify a single button.',
);
}
seen[button.uniqueId] = button;
}
}
}