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.dataCount} 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.
For a production-ready configuration (including safe-area handling and controller-driven playback), review the Showcase MomentsScreen.
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.
Calls made before the platform view is created are ignored (the embedded clips controller does not queue commands). Prefer invoking controller methods after the widget is on screen (for example, after the first frame) or in response to user interaction.