G9MAUIControls.IntroCarousel
1.4.0
dotnet add package G9MAUIControls.IntroCarousel --version 1.4.0
NuGet\Install-Package G9MAUIControls.IntroCarousel -Version 1.4.0
<PackageReference Include="G9MAUIControls.IntroCarousel" Version="1.4.0" />
<PackageVersion Include="G9MAUIControls.IntroCarousel" Version="1.4.0" />
<PackageReference Include="G9MAUIControls.IntroCarousel" />
paket add G9MAUIControls.IntroCarousel --version 1.4.0
#r "nuget: G9MAUIControls.IntroCarousel, 1.4.0"
#:package G9MAUIControls.IntroCarousel@1.4.0
#addin nuget:?package=G9MAUIControls.IntroCarousel&version=1.4.0
#tool nuget:?package=G9MAUIControls.IntroCarousel&version=1.4.0
G9MAUIControls.IntroCarousel
Onboarding carousel with video slides, for G9MAUIControls.
dotnet add package G9MAUIControls.IntroCarousel
What it adds
G9IntroCarousel — the first-run walkthrough control: swipeable slides that can be an image or a
video, page indicators, a skip affordance, and paging that reverses correctly in RTL.
Why this is a separate package
Video playback needs CommunityToolkit.Maui.MediaElement, which pulls a platform media stack — ExoPlayer
on Android, AVPlayer on Apple. That is a large dependency to hand to somebody who only wanted a text
entry, so it lives here with the one control that needs it.
What you take on by installing this: CommunityToolkit.Maui.MediaElement and its platform players,
plus builder.UseMauiCommunityToolkitMediaElement() in MauiProgram.
The teardown order you must not "simplify"
The carousel disconnects the media handler itself, in a specific sequence, and the sequence is
load-bearing. On Android, if the native media view is disposed by the fragment's own onDestroyView
before the visual-diagnostics overlay is de-initialised, the overlay later calls RemoveView on a
disposed parent and the app crashes. The control therefore de-initialises the overlay first, while the
native view is still alive, then stops playback, then lets MAUI disconnect.
It is commented at the site. Read that comment before changing anything in the teardown path.
Usage
<intro:G9IntroCarousel
x:Name="Intro"
Slides="{Binding Slides}"
CurrentIndex="{Binding Index}"
CompleteCommand="{Binding FinishOnboardingCommand}"
LanguageCommand="{Binding SwitchLanguageCommand}"
UseGradientOverlay="True" />
Slides =
[
new G9IntroSlideItem
{
TitleResourceKey = "Intro_Welcome_Title",
SubtitleResourceKey = "Intro_Welcome_Body",
ImageSource = "slide1.png"
},
new G9IntroSlideItem
{
TitleResourceKey = "Intro_Scanning_Title",
SubtitleResourceKey = "Intro_Scanning_Body",
VideoAssetPath = "Onboarding/scan.mp4", // MauiAsset logical path
ImageSource = "slide2.png" // fallback if playback fails
}
];
Two things this control will not do for you.
1. Slide copy is resolved through your string catalogue, by key. TitleResourceKey and
SubtitleResourceKey go through G9Strings.Resolve, so wire the core's string hook —
G9Strings.UseResources(MyResources.ResourceManager) — or every slide renders blank. The carousel ships
no default copy, because onboarding text is the most app-specific content there is.
2. Nothing plays until you call BeginPresentation(). Media and chrome stay idle until then, on
purpose: onboarding usually sits behind a bootstrap or a login screen, and starting video decode while
the app is still starting up costs you the frames you least want to lose.
protected override void OnAppearing()
{
base.OnAppearing();
Intro.BeginPresentation();
}
Call StopAndReleaseMedia() when you navigate away. The FirstContentReady event fires when the first
slide has something on screen — useful for dismissing your own splash without a flash of empty carousel.
Video paths resolve through G9IntroMediaResolver, which copies a packaged asset out to a readable file
path — MediaElement cannot play straight out of the app package.
Requirements
.NET 10 · net10.0-android, net10.0-ios, net10.0-maccatalyst, net10.0-windows10.0.19041.0
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0-android36.0 is compatible. net10.0-ios26.0 is compatible. net10.0-maccatalyst26.0 is compatible. net10.0-windows10.0.19041 is compatible. |
-
net10.0-android36.0
- CommunityToolkit.Maui.Core (>= 15.0.0)
- CommunityToolkit.Maui.MediaElement (>= 10.0.0)
- G9MAUIControls (>= 1.4.0)
- Microsoft.Maui.Controls (>= 10.0.90)
-
net10.0-ios26.0
- CommunityToolkit.Maui.Core (>= 15.0.0)
- CommunityToolkit.Maui.MediaElement (>= 10.0.0)
- G9MAUIControls (>= 1.4.0)
- Microsoft.Maui.Controls (>= 10.0.90)
-
net10.0-maccatalyst26.0
- CommunityToolkit.Maui.Core (>= 15.0.0)
- CommunityToolkit.Maui.MediaElement (>= 10.0.0)
- G9MAUIControls (>= 1.4.0)
- Microsoft.Maui.Controls (>= 10.0.90)
-
net10.0-windows10.0.19041
- CommunityToolkit.Maui.Core (>= 15.0.0)
- CommunityToolkit.Maui.MediaElement (>= 10.0.0)
- G9MAUIControls (>= 1.4.0)
- Microsoft.Maui.Controls (>= 10.0.90)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.4.0 | 78 | 10/5/2026 |
| 1.3.0 | 84 | 10/3/2026 |
| 1.2.0 | 92 | 9/27/2026 |
| 1.1.0 | 101 | 9/21/2026 |
| 1.0.14 | 110 | 9/12/2026 |
| 1.0.13 | 114 | 9/8/2026 |
| 1.0.12 | 107 | 9/8/2026 |
| 1.0.10 | 116 | 9/7/2026 |
| 1.0.9 | 107 | 9/4/2026 |
| 1.0.8 | 106 | 9/4/2026 |
| 1.0.7 | 110 | 9/2/2026 |
| 1.0.6 | 106 | 9/1/2026 |
| 1.0.5 | 127 | 8/19/2026 |
| 1.0.4 | 126 | 8/18/2026 |
| 1.0.3 | 107 | 8/18/2026 |
| 1.0.2 | 123 | 8/17/2026 |
| 1.0.1 | 124 | 8/15/2026 |
| 1.0.0 | 118 | 8/14/2026 |
1.4.0
- G9TabBar: a second visual style, Sculpted (ADR-0030). New G9TabBarStyle (Classic, Sculpted) set
through the bindable G9TabBar.BarStyle (named so because Style is MAUI's own). Sculpted is an
opaque 68 dp bar with 24 dp corners, a wide S-shouldered cradle instead of the semicircle notch, a
flat 66 dp primary FAB disc centred 9 dp below the bar's top edge with a soft Skia drop shadow
(never a MAUI Shadow), 12 pt labels, and NO selection pill: the selected
item switches to its filled icon (new G9TabBarItem.SelectedIcon, plus a three-argument constructor)
and the primary colour. Behaviour (selection, FAB slot, sub-menu, overflow, events) is identical.
New public G9TabBarStyleMetrics (Classic / Sculpted / For(style)) and G9TabBar.CurrentMetrics: a
host that reserves the bar's height must read CurrentMetrics.BarHeight, because Sculpted is 68 dp
and the Classic constant G9TabBarMetrics.BarHeight stays 62. Sculpted is deliberately larger than
its Figma component (bar 64, disc 48) after device review; the cradle and the disc are sized
independently in G9TabBarStyleMetrics. The chrome and its Skia shadow now
trace ONE outline builder, so the shadow can no longer drift from the painted notch.
CONSUMER VISIBLE only when BarStyle is set: Classic renders exactly as in 1.3.0.
- G9NavCard: TitleAccessoryView (a small view on the title's line, right after the title; the
title truncates first) and UseFilledIconChip (a solid accent chip with an OnPrimary icon, for a
list's one primary row). Both default off; existing cards are unchanged.
- G9CultureDateTimeLabel: DisplayMode RelativeDay - "Today, 18:00" / Tomorrow / Yesterday for
values within a day, the ordinary date and time otherwise (a midnight value drops its 00:00).
"Today" is measured against the new static RelativeDayNow clock (device local time by default).
New G9StringKey.Tomorrow and Yesterday (G9StringKey.Today is reused).
Earlier versions: https://github.com/ImanKari/G9MAUIControls/blob/main/CHANGELOG.md