flutter_tour_guide 0.1.2 copy "flutter_tour_guide: ^0.1.2" to clipboard
flutter_tour_guide: ^0.1.2 copied to clipboard

A lightweight, themeable Flutter tour guide with spotlight cutouts, auto-scroll, tab/page navigation, and per-screen persistence.

flutter_tour_guide #

A lightweight, themeable Flutter onboarding tour with spotlight cutouts, animated tooltips, auto-scroll, tab/page navigation support, and per-screen persistence.

Screenshots #

Step 1 — FAB Step 2 — Search Step 3 — Tabs Step 4 — Settings
Step 1 Step 2 Step 3 Step 4

Features #

  • Spotlight cutout — dims the entire screen except the target widget
  • Auto-scroll — calls Scrollable.ensureVisible before each step so items inside lists are always in view
  • Tab & page navigationonBefore hook lets you switch tabs or navigate before a step renders
  • Persistent "seen" state — uses shared_preferences so tours don't re-appear after the first view
  • Fully themeable — override accent color, scrim opacity, card styles, spotlight shape, and more
  • Restart / reset API — reset one tour or all tours (e.g., from a settings screen)
  • Prev / Next navigation — back button appears automatically from step 2 onward
  • Fade animations — smooth entrance/exit between steps

Getting started #

Add the package to your pubspec.yaml:

dependencies:
  flutter_tour_guide: ^0.1.2

Then run:

flutter pub get

Usage #

Basic tour #

import 'package:flutter_tour_guide/flutter_tour_guide.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final _fabKey = GlobalKey();
  final _listKey = GlobalKey();

  @override
  void initState() {
    super.initState();
    // Start the tour after the first frame so all keys are attached.
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Tour.show(
        context: context,
        id: 'home_screen_v1', // unique ID for persistence
        steps: [
          TourStep(
            targetKey: _fabKey,
            title: 'Create something new',
            body: 'Tap here to add a new item to your list.',
          ),
          TourStep(
            targetKey: _listKey,
            title: 'Your items',
            body: 'Everything you create appears here.',
          ),
        ],
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        key: _fabKey,
        onPressed: () {},
        child: const Icon(Icons.add),
      ),
      body: ListView(
        children: [
          ListTile(key: _listKey, title: const Text('First item')),
        ],
      ),
    );
  }
}

Theming #

Override any part of the visual style via TourTheme:

Tour.show(
  context: context,
  id: 'branded_tour',
  theme: TourTheme(
    accentColor: Colors.deepPurple,
    scrimOpacity: 0.75,
    cardColor: Colors.grey.shade900,
    titleStyle: const TextStyle(
      color: Colors.white,
      fontSize: 16,
      fontWeight: FontWeight.bold,
    ),
    bodyStyle: const TextStyle(color: Colors.white70, fontSize: 13),
    spotlightRadius: 16,
    spotlightPadding: 12,
    cardRadius: 20,
  ),
  steps: [ /* … */ ],
);

Tab / page navigation with onBefore #

Use TourStep.onBefore to switch tabs or navigate before the step is shown:

TourStep(
  targetKey: _searchBarKey,
  title: 'Search anything',
  body: 'Use the search bar to find items instantly.',
  onBefore: () async {
    _tabController.animateTo(1); // switch to the Search tab
    await Future.delayed(const Duration(milliseconds: 300));
  },
),

Callbacks #

Tour.show(
  context: context,
  id: 'settings_tour',
  steps: [ /* … */ ],
  onEnd: () async {
    // Called when tour completes OR is skipped.
    print('Tour finished');
  },
  onSkip: () async {
    // Called only when the user taps "Skip tour".
    print('User skipped');
  },
);

Forcing a tour to re-show #

Tour.show(
  context: context,
  id: 'home_screen_v1',
  force: true, // ignores the "already seen" flag
  steps: [ /* … */ ],
);

Reset tours #

// Reset a single tour so it shows again on the next visit.
await Tour.reset('home_screen_v1');

// Reset every tour in the app (e.g., from a "Replay tutorials" settings toggle).
await Tour.resetAll();

API reference #

Tour.show #

Parameter Type Required Description
context BuildContext The overlay context.
id String Unique key for SharedPreferences persistence.
steps List<TourStep> Ordered list of steps.
theme TourTheme Visual config. Defaults to a neutral green theme.
force bool Show even if already seen. Default false.
onEnd Future<void> Function()? Called after any tour ending.
onSkip Future<void> Function()? Called only on explicit skip.

TourStep #

Field Type Description
targetKey GlobalKey Attach this to the widget you want spotlighted.
title String Headline shown in the card.
body String Explanatory text below the title.
padding double? Per-step spotlight padding (overrides theme).
radius double? Per-step spotlight corner radius (overrides theme).
onBefore Future<void> Function()? Async action run before this step renders.

TourTheme #

Field Default Description
accentColor 0xFF00B140 (green) Button and progress-dot color.
scrimOpacity 0.65 Background dimming.
cardColor white Tooltip card background.
titleStyle bold, 15 pt Card headline style.
bodyStyle 13 pt, 1.4 height Card body style.
captionStyle 12 pt, grey Step counter and skip label.
cardRadius 14 Tooltip card corner radius.
spotlightRadius 12 Cutout corner radius.
spotlightPadding 8 Extra space around the target widget.

Additional information #

2
likes
160
points
50
downloads
screenshot

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A lightweight, themeable Flutter tour guide with spotlight cutouts, auto-scroll, tab/page navigation, and per-screen persistence.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, shared_preferences

More

Packages that depend on flutter_tour_guide