Embedded Clips#
StorytellerEmbeddedClipsView lets you place the native Storyteller clips experience inline within your Flutter UI while keeping full control of layout, scrolling, and lifecycle.
Basic usage#
class InlineClips extends StatelessWidget {
const InlineClips({super.key});
@override
Widget build(BuildContext context) {
return SizedBox(
height: 420,
child: StorytellerEmbeddedClipsView(
collectionId: 'featured-highlights',
shouldPlay: true,
topLevelBack: false,
onDataLoadStarted: () => debugPrint('Loading clips...'),
onDataLoadComplete: (result) {
debugPrint('Loaded ${result.totalClips} clips');
},
),
);
}
}
Key parameters:
collectionId(required) – the Storyteller collection to play.clipId– start playback at a specific clip.initialCategory– open the embedded UI within a category.shouldPlay– autoplay behaviour (defaults totrue).topLevelBack– whether to expose a back button for nested navigation.theme– apply aStorytellerThemeoverride.context– attach analytics context metadata.topInset/bottomInset– provide safe area values in logical pixels. Available on Android only.
React to embedded callbacks#
Three callbacks surface native lifecycle events:
onDataLoadStarted()– when Storyteller begins loading collection data.onDataLoadComplete(StorytellerEmbeddedClipsLoadResult result)– includes status and counts; inspectresult.errorwhenresult.successisfalse.onUserActivityOccurred(Map<String, dynamic> payload)– emits the same payloads you see on the globalonUserActivityOccurredstream, scoped to this embedded instance.
Control playback programmatically#
Attach a StorytellerEmbeddedClipsController to pause/resume playback, reload data, or propagate inset changes after creation.
class ControllableEmbeddedClips extends StatefulWidget {
const ControllableEmbeddedClips({super.key});
@override
State<ControllableEmbeddedClips> createState() =>
_ControllableEmbeddedClipsState();
}
class _ControllableEmbeddedClipsState
extends State<ControllableEmbeddedClips> {
final _controller = StorytellerEmbeddedClipsController();
@override
Widget build(BuildContext context) {
return Column(
children: [
Expanded(
child: StorytellerEmbeddedClipsView(
collectionId: 'live-stream',
controller: _controller,
shouldPlay: false,
),
),
FilledButton(
onPressed: () async {
await _controller.setShouldPlay(true);
},
child: const Text('Play clips'),
),
],
);
}
}
Available controller actions:
reloadData()– refreshes the native data source.goBack()/canGoBack()– traverse nested embedded navigation.setShouldPlay(bool)– toggle playback.updateInsets({int top, int bottom})– sync safe areas when your layout changes.
If the controller receives a command before the platform view is ready, the SDK safely ignores it until the view attaches.