### Basic Flutter ShowcaseView Example Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md A complete example demonstrating the basic setup of ShowcaseView, including registration, defining global keys, wrapping widgets, and starting the showcase on screen load. It also includes unregistering the view in the dispose method. ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'ShowCase Example', theme: ThemeData(primarySwatch: Colors.blue), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage(); @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { final GlobalKey _one = GlobalKey(); final GlobalKey _two = GlobalKey(); @override void initState() { super.initState(); // Register the showcase view ShowcaseView.register(); // Start showcase after the screen is rendered to ensure internal initialization. WidgetsBinding.instance.addPostFrameCallback( (_) => ShowcaseView.get().startShowCase([_one, _two]), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('ShowCase Example'), leading: Showcase( key: _one, title: 'Menu', description: 'Click here to see menu options', child: Icon(Icons.menu), ), ), floatingActionButton: Showcase( key: _two, title: 'Add', description: 'Click here to add new items', child: FloatingActionButton( onPressed: () {}, child: Icon(Icons.add), ), ), body: Center( child: Text('ShowCase Example'), ), ); } @override void dispose() { // Unregister the showcase view ShowcaseView.get().unregister(); super.dispose(); } } ``` -------------------------------- ### Basic Showcase Registration and Initialization in Dart Source: https://context7.com/simformsolutionspvtltd/flutter_showcaseview/llms.txt Demonstrates how to register ShowcaseView, define global keys for widgets to be showcased, and start a showcase sequence after the widget tree is built. This example shows initializing the showcase sequence by passing a list of GlobalKeys to `startShowCase`. It also includes unregistering the showcase instance in the `dispose` method. ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; class MyHomePage extends StatefulWidget { const MyHomePage({Key? key}) : super(key: key); @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { final GlobalKey _menuKey = GlobalKey(); final GlobalKey _searchKey = GlobalKey(); final GlobalKey _addKey = GlobalKey(); @override void initState() { super.initState(); // Register ShowcaseView with default configuration ShowcaseView.register(); // Start showcase after the widget tree is built WidgetsBinding.instance.addPostFrameCallback( (_) => ShowcaseView.get().startShowCase([_menuKey, _searchKey, _addKey]), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Showcase Example'), leading: Showcase( key: _menuKey, title: 'Menu', description: 'Click here to open the navigation menu', child: IconButton( icon: const Icon(Icons.menu), onPressed: () {}, ), ), actions: [ Showcase( key: _searchKey, title: 'Search', description: 'Tap to search for items', child: IconButton( icon: const Icon(Icons.search), onPressed: () {}, ), ), ], ), floatingActionButton: Showcase( key: _addKey, title: 'Add Item', description: 'Click here to add a new item', child: FloatingActionButton( onPressed: () {}, child: const Icon(Icons.add), ), ), body: const Center(child: Text('App Content')), ); } @override void dispose() { ShowcaseView.get().unregister(); super.dispose(); } } ``` -------------------------------- ### Flutter: Multi-Showcase and Manual Navigation with ShowcaseView Source: https://context7.com/simformsolutionspvtltd/flutter_showcaseview/llms.txt This Flutter code example demonstrates how to use the showcaseview package to display multiple showcases simultaneously and control navigation programmatically. It utilizes GlobalKeys to group showcases and provides buttons for starting sequential tours, multi-showcases, and manual navigation (previous, next, dismiss). The ShowcaseView.register method is used to configure the showcase behavior. ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; class MultiShowcaseExample extends StatefulWidget { const MultiShowcaseExample({Key? key}) : super(key: key); @override State createState() => _MultiShowcaseExampleState(); } class _MultiShowcaseExampleState extends State { final GlobalKey _multiKey = GlobalKey(); final GlobalKey _step1 = GlobalKey(); final GlobalKey _step2 = GlobalKey(); final GlobalKey _step3 = GlobalKey(); @override void initState() { super.initState(); ShowcaseView.register( autoPlay: false, disableBarrierInteraction: false, ); } void startTour() { ShowcaseView.get().startShowCase([_step1, _step2, _step3]); } void startMultiShowcase() { ShowcaseView.get().startShowCase([_multiKey]); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Multi-Showcase Example'), actions: [ IconButton( icon: const Icon(Icons.play_arrow), onPressed: startTour, tooltip: 'Start Sequential Tour', ), IconButton( icon: const Icon(Icons.apps), onPressed: startMultiShowcase, tooltip: 'Start Multi-Showcase', ), ], ), body: Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ // Multiple showcases with the same key will display simultaneously Showcase( key: _multiKey, title: 'Feature A', description: 'This is feature A', child: Container( width: 80, height: 80, color: Colors.red, child: const Center( child: Text('A', style: TextStyle(fontSize: 32, color: Colors.white)), ), ), ), Showcase( key: _multiKey, title: 'Feature B', description: 'This is feature B', child: Container( width: 80, height: 80, color: Colors.green, child: const Center( child: Text('B', style: TextStyle(fontSize: 32, color: Colors.white)), ), ), ), Showcase( key: _multiKey, title: 'Feature C', description: 'This is feature C', child: Container( width: 80, height: 80, color: Colors.blue, child: const Center( child: Text('C', style: TextStyle(fontSize: 32, color: Colors.white)), ), ), ), ], ), Showcase( key: _step1, title: 'Step 1', description: 'First step in sequential tour', child: ElevatedButton( onPressed: () {}, child: const Text('Button 1'), ), ), Showcase( key: _step2, title: 'Step 2', description: 'Second step in sequential tour', child: ElevatedButton( onPressed: () {}, child: const Text('Button 2'), ), ), Showcase( key: _step3, title: 'Step 3', description: 'Final step in sequential tour', child: ElevatedButton( onPressed: () {}, child: const Text('Button 3'), ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ElevatedButton.icon( onPressed: () => ShowcaseView.get().previous(), icon: const Icon(Icons.arrow_back), label: const Text('Previous'), ), ElevatedButton.icon( onPressed: () => ShowcaseView.get().next(), icon: const Icon(Icons.arrow_forward), label: const Text('Next'), ), ElevatedButton.icon( onPressed: () => ShowcaseView.get().dismiss(), icon: const Icon(Icons.close), label: const Text('Dismiss'), ) ] ) ] ) ) ); } } ``` -------------------------------- ### Start Showcase on Screen Load Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Automatically start the showcase sequence once the screen has finished rendering. This is achieved by using `WidgetsBinding.instance.addPostFrameCallback` within the `initState` method to ensure the UI is ready. ```dart @override void initState() { super.initState(); // Delayed execution to ensure the UI is fully rendered WidgetsBinding.instance.addPostFrameCallback( (_) => ShowcaseView.get().startShowCase([_one, _two, _three]), ); } ``` -------------------------------- ### Configure ShowcaseView with Event Callbacks (Dart) Source: https://context7.com/simformsolutionspvtltd/flutter_showcaseview/llms.txt This Dart code snippet demonstrates advanced configuration for ShowcaseView, including global settings such as autoplay, blur effects, and disabling barrier interactions. It also sets up custom event handlers for showcase start, completion, and dismissal, along with defining custom tooltip actions and a floating action widget for user control. This setup allows for highly interactive and customizable onboarding tours. ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; class AdvancedShowcasePage extends StatefulWidget { const AdvancedShowcasePage({Key? key}) : super(key: key); @override State createState() => _AdvancedShowcasePageState(); } class _AdvancedShowcasePageState extends State { final GlobalKey _firstKey = GlobalKey(); final GlobalKey _secondKey = GlobalKey(); final GlobalKey _lastKey = GlobalKey(); @override void initState() { super.initState(); ShowcaseView.register( autoPlay: true, autoPlayDelay: const Duration(seconds: 3), enableAutoPlayLock: true, enableAutoScroll: true, scrollDuration: const Duration(milliseconds: 500), blurValue: 2.5, disableBarrierInteraction: false, semanticEnable: true, onStart: (index, key) { print('Started showcase at index: $index'); }, onComplete: (index, key) { print('Completed showcase at index: $index'); }, onFinish: () { print('All showcases completed!'); // Navigate to next screen or save completion state }, onDismiss: (dismissedAt) { print('Showcase dismissed at key: $dismissedAt'); }, globalTooltipActionConfig: const TooltipActionConfig( position: TooltipActionPosition.inside, alignment: MainAxisAlignment.spaceBetween, actionGap: 20, ), globalTooltipActions: [ TooltipActionButton( type: TooltipDefaultActionType.previous, textStyle: const TextStyle(color: Colors.white), hideActionWidgetForShowcase: [_firstKey], ), TooltipActionButton( type: TooltipDefaultActionType.next, textStyle: const TextStyle(color: Colors.white), hideActionWidgetForShowcase: [_lastKey], ), ], globalFloatingActionWidget: (context) => FloatingActionWidget( bottom: 20, right: 20, child: ElevatedButton( onPressed: () => ShowcaseView.get().dismiss(), style: ElevatedButton.styleFrom(backgroundColor: Colors.red), child: const Text('Skip Tour', style: TextStyle(color: Colors.white)), ), ), ); WidgetsBinding.instance.addPostFrameCallback( (_) => ShowcaseView.get().startShowCase([_firstKey, _secondKey, _lastKey]), ); } @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Showcase( key: _firstKey, title: 'Welcome', description: 'This is the first step of your tour', child: Container( padding: const EdgeInsets.all(20), color: Colors.blue, child: const Text('Step 1'), ), ), Showcase( key: _secondKey, title: 'Features', description: 'Explore the main features here', child: Container( padding: const EdgeInsets.all(20), color: Colors.green, child: const Text('Step 2'), ), ), Showcase( key: _lastKey, title: 'Complete', description: 'You are all set!', child: Container( padding: const EdgeInsets.all(20), color: Colors.orange, child: const Text('Final Step'), ), ), ], ), ); } @override void dispose() { ShowcaseView.get().unregister(); super.dispose(); } } ``` -------------------------------- ### Start Showcase Sequence on Button Press Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Initiate the showcase sequence by calling `ShowcaseView.get().startShowCase()` within an `onPressed` callback of a button. Pass a list of GlobalKeys to define the order of widgets to be showcased. ```dart ElevatedButton( child: Text('Start Showcase'), onPressed: () { ShowcaseView.get().startShowCase([_one, _two, _three]); }, ) ``` -------------------------------- ### Basic ShowcaseView Implementation in Dart Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Demonstrates the basic implementation of ShowcaseView in a Flutter application. It includes importing the package, registering the view, defining global keys for showcases, wrapping widgets with Showcase, and starting the showcase sequence. ```dart // Import the package import 'package:showcaseview/showcaseview.dart'; // Register the showcase view ShowcaseView.register(); // Define global keys for your showcases GlobalKey _one = GlobalKey(); // Add showcases to widgets Showcase( key: _one, title: 'Menu', description: 'Click here to see menu options', child: Icon(Icons.menu), ), // Start the showcase void startShowcase() { ShowcaseView.get().startShowCase([_one]); } // Dispose the showcase view ShowcaseView.get().unregister(); ``` -------------------------------- ### Bundle Installation Configuration Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/example/linux/CMakeLists.txt Configures the installation process to create a relocatable application bundle. It sets up installation directories for data and libraries, and installs the main executable, Flutter ICU data, and the Flutter library. ```cmake # === Installation === # By default, "installing" just makes a relocatable bundle in the build # directory. set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() # Start with a clean build bundle directory every time. install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Apply Advanced Styling to Showcases (Dart) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Provides examples of how to customize the visual appearance of showcases, including title text style, description text style, tooltip background color, and padding/border radius for the target and tooltip. ```dart Showcase( key: _styleKey, title: 'Styled Showcase', description: 'This showcase has custom styling', titleTextStyle: TextStyle( color: Colors.red, fontSize: 20, fontWeight: FontWeight.bold, ), descTextStyle: TextStyle( color: Colors.green, fontSize: 16, fontStyle: FontStyle.italic, ), tooltipBackgroundColor: Colors.black87, targetPadding: EdgeInsets.all(8), targetBorderRadius: BorderRadius.circular(8), tooltipBorderRadius: BorderRadius.circular(16), child: MyWidget(), ) ``` -------------------------------- ### Basic CMake Project Setup Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/example/linux/CMakeLists.txt Initializes the CMake project, sets the minimum required version, project name, and programming language. It also defines application-specific variables like BINARY_NAME and APPLICATION_ID. ```cmake cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) set(BINARY_NAME "example") set(APPLICATION_ID "com.simform.example") cmake_policy(SET CMP0063 NEW) set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") ``` -------------------------------- ### CMake Installation Rules for Flutter Application Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/example/windows/CMakeLists.txt Defines how the built application and its components are installed. It sets up the installation directory, copies the executable, libraries, Flutter assets, and ICU data. This ensures that the application can be deployed and run correctly with all its dependencies. ```cmake # === Installation === # Support files are copied into place next to the executable, so that it can # run in place. This is done instead of making a separate bundle (as on Linux) # so that building and running from within Visual Studio will work. set(BUILD_BUNDLE_DIR "$") # Make the "install" step default, as it's required to run. set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) # Install the AOT library on non-Debug builds only. install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" CONFIGURATIONS Profile;Release COMPONENT Runtime) ``` -------------------------------- ### Plugin Bundled Libraries and Asset Installation Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/example/linux/CMakeLists.txt Installs any bundled libraries required by plugins and ensures the Flutter assets directory is fully re-copied on each build to prevent stale files. This ensures all necessary components are included in the installation bundle. ```cmake if(PLUGIN_BUNDLED_LIBRARIES) install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) ``` -------------------------------- ### Start Showcase After Animation Completion Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Trigger the showcase sequence after UI animations have completed. Similar to starting on screen load, `WidgetsBinding.instance.addPostFrameCallback` is used, potentially with a delay, to synchronize with animation completion. ```dart WidgetsBinding.instance.addPostFrameCallback( (_) => ShowcaseView.get().startShowCase( [_one, _two, _three], delay: Duration(milliseconds: 500), ), ); ``` -------------------------------- ### Execute Showcase Operations with Named Scope Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Demonstrates how to perform showcase operations like starting a showcase or dismissing it when a specific scope name has been provided during registration. Operations must use ShowcaseView.get(scope: 'scopeName') to target the correct configuration set. ```dart ShowcaseView.get(scope: 'profile').startShowCase([_one, _two, _three]); ``` -------------------------------- ### AOT Library Installation for Non-Debug Builds Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/example/linux/CMakeLists.txt Installs the Ahead-Of-Time (AOT) compiled library only for non-Debug builds (Profile and Release). This optimizes application performance by including pre-compiled code. ```cmake # Install the AOT library on non-Debug builds only. if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ``` -------------------------------- ### Dynamically Add/Remove OnComplete Callback (Dart) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Explains how to dynamically add and remove `onComplete` callbacks at runtime, which is useful for managing callbacks from deeper widget tree levels or when using named showcase scopes. Examples include adding a callback globally and for a specific named scope. ```dart // Add a callback for when each showcase step completes ShowcaseView.get().addOnCompleteCallback((index, key) { print('Showcase step $index completed with key: $key'); // Perform custom actions here }); // Remove a previously added callback ShowcaseView.get().removeOnCompleteCallback(callbackFunction); // Example with named scope: ShowcaseView.getNamed('profile').addOnCompleteCallback((index, key) { print('Profile showcase completed at step $index'); }); ``` -------------------------------- ### CMake Build Configuration and Settings Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/example/windows/CMakeLists.txt Configures the minimum CMake version, project name, binary name, and installation path. It also sets up build types (Debug, Profile, Release) and applies standard compilation settings for C++17, warning levels, exception handling, and debug definitions. This section ensures consistent build behavior across different configurations. ```cmake cmake_minimum_required(VERSION 3.15) project(example LANGUAGES CXX) set(BINARY_NAME "example") cmake_policy(SET CMP0063 NEW) set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") # Configure build options. get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(IS_MULTICONFIG) set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" CACHE STRING "" FORCE) else() if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() endif() set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") # Use Unicode for all projects. add_definitions(-DUNICODE -D_UNICODE) # Compilation settings that should be applied to most targets. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_17) target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") target_compile_options(${TARGET} PRIVATE /EHsc) target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") target_compile_definitions(${TARGET} PRIVATE "<$:_DEBUG>") endfunction() set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") # Flutter library and tool build rules. add_subdirectory(${FLUTTER_MANAGED_DIR}) # Application build add_subdirectory("runner") # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) ``` -------------------------------- ### Custom Widget Tooltip with Complex Layout (Dart) Source: https://context7.com/simformsolutionspvtltd/flutter_showcaseview/llms.txt This Dart code defines a Flutter widget that uses Showcase.withWidget to display a complex, custom-designed tooltip. It includes features like gradients, icons, text, and a button, attached to a target widget. Dependencies include 'flutter/material.dart' and 'showcaseview/showcaseview.dart'. It registers and starts the showcase view, allowing for custom UI elements within the showcase. The custom tooltip has specific dimensions and a circular target shape. ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; class CustomWidgetShowcase extends StatefulWidget { const CustomWidgetShowcase({Key? key}) : super(key: key); @override State createState() => _CustomWidgetShowcaseState(); } class _CustomWidgetShowcaseState extends State { final GlobalKey _customKey = GlobalKey(); final GlobalKey _imageKey = GlobalKey(); @override void initState() { super.initState(); ShowcaseView.register(); WidgetsBinding.instance.addPostFrameCallback( (_) => ShowcaseView.get().startShowCase([_customKey, _imageKey]), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Custom Widget Showcase')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Showcase.withWidget( key: _customKey, height: 200, width: 280, targetShapeBorder: const CircleBorder(), overlayOpacity: 0.85, container: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Colors.blue, Colors.purple], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 10, offset: const Offset(0, 5), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: const [ Icon(Icons.star, color: Colors.yellow, size: 28), SizedBox(width: 8), Text( 'Premium Feature', style: TextStyle( color: Colors.white, fontSize: 20, fontWeight: FontWeight.bold, ), ), ], ), const SizedBox(height: 12), const Text( 'This is a completely custom tooltip widget with gradients, icons, and complex layouts!', style: TextStyle(color: Colors.white, fontSize: 14), ), const SizedBox(height: 16), ElevatedButton( onPressed: () { ShowcaseView.get().next(force: true); }, style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: Colors.purple, ), child: const Text('Got it!'), ), ], ), ), child: Container( padding: const EdgeInsets.all(20), decoration: const BoxDecoration( color: Colors.amber, shape: BoxShape.circle, ), child: const Icon(Icons.notifications, size: 40), ), ), const SizedBox(height: 60), Showcase.withWidget( key: _imageKey, height: 150, width: 250, targetBorderRadius: BorderRadius.circular(12), container: Card( color: Colors.green.shade700, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), child: Padding( padding: const EdgeInsets.all(12), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text( 'Tap to upload photos', style: TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 8), const Text( 'Support JPG, PNG, GIF formats', style: TextStyle(color: Colors.white70, fontSize: 12), ), ], ), ), ), child: const Icon(Icons.image, size: 50, color: Colors.black), ) ], ), ), ); } } ``` -------------------------------- ### Handle Showcase Event Callbacks (Dart) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Demonstrates how to register callback functions for key showcase events like `onStart`, `onComplete`, `onFinish`, and `onDismiss`. These callbacks allow for custom logic to be executed at different stages of the showcase lifecycle. ```dart ShowcaseView.register( onStart: (index, key) { print('Started showcase $index'); }, onComplete: (index, key) { print('Completed showcase $index'); }, onFinish: () { print('All showcases completed'); }, onDismiss: (reason) { print('Showcase dismissed because: $reason'); }, ) ``` -------------------------------- ### Register ShowcaseView with Custom Configurations Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Shows how to register ShowcaseView with advanced global configurations. This includes setting autoplay delay, enabling semantic support, defining a global floating action widget, and configuring tooltip actions and styling. ```dart ShowcaseView.register( autoPlayDelay: const Duration(seconds: 3), semanticEnable: true, // Enable accessibility support globally globalFloatingActionWidget: (showcaseContext) => FloatingActionWidget( left: 16, bottom: 16, child: Padding( padding: const EdgeInsets.all(16.0), child: ElevatedButton( onPressed: () => ShowcaseView.get().dismiss(), style: ElevatedButton.styleFrom( backgroundColor: const Color(0xffEE5366), ), child: const Text( 'Skip', style: TextStyle( color: Colors.white, fontSize: 15, ), ), ), ), ), ), globalTooltipActionConfig: const TooltipActionConfig( position: TooltipActionPosition.inside, alignment: MainAxisAlignment.spaceBetween, actionGap: 20, ), globalTooltipActions: [ TooltipActionButton( type: TooltipDefaultActionType.previous, textStyle: const TextStyle( color: Colors.white, ), // Here we don't need previous action for the first showcase widget // so we hide this action for the first showcase widget hideActionWidgetForShowcase: [_firstShowcaseWidget], ), TooltipActionButton( type: TooltipDefaultActionType.next, textStyle: const TextStyle( color: Colors.white, ), // Here we don't need next action for the last showcase widget so we // hide this action for the last showcase widget hideActionWidgetForShowcase: [_lastShowcaseWidget], ), ], ); ``` -------------------------------- ### Create Custom Tooltip Widget with Showcase.withWidget (Dart) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Illustrates how to create a fully custom tooltip widget using `Showcase.withWidget`. This allows for complete control over the tooltip's appearance and content, overriding the default tooltip. ```dart Showcase.withWidget( key: _customKey, height: 80, width: 140, targetShapeBorder: CircleBorder(), container: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Custom Tooltip', style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold)), SizedBox(height: 5), Text('This is a completely custom tooltip widget', style: TextStyle(color: Colors.white)), ], ), child: Icon(Icons.star), ) ``` -------------------------------- ### Flutter ShowcaseView: Context-based to Direct Control (v5.0.0+) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Demonstrates the shift in controlling ShowcaseView from context-based access (ShowCaseWidget.of(context)) to a direct registration and retrieval method (ShowcaseView.register/get). This change simplifies initialization and management of showcase sequences. It shows the 'before' (pre-5.0.0) and 'after' (5.0.0+) implementations. ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: ShowCaseWidget( // Prior to 5.x.x, you wrapped your page with ShowCaseWidget builder: (context) => const MyPage(), ), ); } } class MyPage extends StatefulWidget { const MyPage({super.key}); @override State createState() => MyPageState(); } class MyPageState extends State { final _one = GlobalKey(); final _two = GlobalKey(); @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { // Context-based control ShowCaseWidget.of(context).startShowCase([_one, _two]); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Legacy ShowCase Usage')), body: Center( child: Showcase( key: _one, title: 'Legacy', description: 'Context-based control via ShowCaseWidget.of(context)', child: const Icon(Icons.info), ), ), floatingActionButton: FloatingActionButton( onPressed: onClose, child: const Icon(Icons.close), ), ); } void onClose() { ShowCaseWidget.of(context).dismiss(); } } ``` ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: const MyPage(), ); } } class MyPage extends StatefulWidget { const MyPage({super.key}); @override State createState() => MyPageState(); } class MyPageState extends State { final _one = GlobalKey(); final _two = GlobalKey(); @override void initState() { super.initState(); // Register once and (optionally) provide global configs ShowcaseView.register( autoPlayDelay: const Duration(seconds: 3), onStart: (index, key) => debugPrint('Started $index'), onComplete: (index, key) => debugPrint('Completed $index'), ); // Start after the first frame to ensure layout is ready WidgetsBinding.instance.addPostFrameCallback((_) { ShowcaseView.get().startShowCase([_one, _two]); }); } @override void dispose() { // Always unregister to clean up ShowcaseView.get().unregister(); super.dispose(); } void onClose() { ShowcaseView.get().dismiss(); } } ``` -------------------------------- ### Add Action Buttons to Tooltips (Dart) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Shows how to integrate action buttons like 'Previous', 'Next', and 'Skip' into the tooltips using the `tooltipActions` and `tooltipActionConfig` properties. This enhances user interaction within the showcase flow. ```dart Showcase( key: _actionKey, title: 'With Actions', description: 'This showcase has action buttons', tooltipActions: [ TooltipActionButton( type: TooltipActionButtonType.previous, backgroundColor: Colors.blue, textStyle: TextStyle(color: Colors.white), name: 'Previous', ), TooltipActionButton( type: TooltipActionButtonType.next, backgroundColor: Colors.green, textStyle: TextStyle(color: Colors.white), name: 'Next', ), TooltipActionButton( type: TooltipActionButtonType.skip, backgroundColor: Colors.red, textStyle: TextStyle(color: Colors.white), name: 'Skip', ), ], tooltipActionConfig: TooltipActionConfig( alignment: MainAxisAlignment.spaceEvenly, position: TooltipActionPosition.outside, ), child: MyWidget(), ) ``` -------------------------------- ### Flutter ShowcaseView: Builder Widget Removal (v3.0.0) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Shows the API simplification in ShowCaseWidget starting from v3.0.0. The requirement for a nested Builder widget within ShowCaseWidget has been removed, allowing the builder property to accept a function directly. This streamlines the widget tree structure. ```dart ShowCaseWidget( builder: Builder( builder: (context) => SomeWidget() ), ), ``` ```dart ShowCaseWidget( builder: (context) => SomeWidget(), ), ``` -------------------------------- ### Programmatically Control Showcase Flow (Dart) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Illustrates methods for programmatically controlling the showcase sequence, such as navigating to the next or previous showcase, and dismissing all active showcases using static methods on `ShowcaseView`. ```dart // Navigate to next showcase ShowcaseView.get().next(); // Navigate to previous showcase ShowcaseView.get().previous(); // Dismiss all showcases ShowcaseView.get().dismiss(); ``` -------------------------------- ### Dart Showcase with Custom Styling and Tooltip - Flutter ShowcaseView Source: https://context7.com/simformsolutionspvtltd/flutter_showcaseview/llms.txt This Dart snippet showcases how to implement custom styling for showcase views and their tooltips in a Flutter application. It demonstrates configuring text styles, background colors, shapes, animations, and touch gestures for tooltips. Dependencies include `flutter/material.dart` and `showcaseview/showcaseview.dart`. ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; class CustomStyledShowcase extends StatefulWidget { const CustomStyledShowcase({Key? key}) : super(key: key); @override State createState() => _CustomStyledShowcaseState(); } class _CustomStyledShowcaseState extends State { final GlobalKey _profileKey = GlobalKey(); final GlobalKey _settingsKey = GlobalKey(); @override void initState() { super.initState(); ShowcaseView.register(); WidgetsBinding.instance.addPostFrameCallback( (_) => ShowcaseView.get().startShowCase([_profileKey, _settingsKey]), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Custom Showcase')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Showcase( key: _profileKey, title: 'Your Profile', description: 'View and edit your profile information here', titleTextStyle: const TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.bold, ), descTextStyle: const TextStyle( color: Colors.white70, fontSize: 16, ), tooltipBackgroundColor: Colors.purple, overlayColor: Colors.black, overlayOpacity: 0.8, targetShapeBorder: const CircleBorder(), targetPadding: const EdgeInsets.all(10), targetBorderRadius: BorderRadius.circular(100), tooltipBorderRadius: BorderRadius.circular(16), tooltipPadding: const EdgeInsets.all(16), showArrow: true, tooltipPosition: TooltipPosition.bottom, disableMovingAnimation: false, movingAnimationDuration: const Duration(milliseconds: 1500), onTargetClick: () { print('Profile icon clicked!'); }, disposeOnTap: false, child: const CircleAvatar( radius: 40, backgroundColor: Colors.purple, child: Icon(Icons.person, size: 40, color: Colors.white), ), ), const SizedBox(height: 40), Showcase( key: _settingsKey, title: 'Settings', description: 'Customize your app preferences', tooltipBackgroundColor: Colors.teal, textColor: Colors.white, targetShapeBorder: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), blurValue: 3.0, scaleAnimationDuration: const Duration(milliseconds: 400), scaleAnimationCurve: Curves.elasticOut, toolTipSlideEndDistance: 10, disableDefaultTargetGestures: false, onTargetLongPress: () { print('Settings long pressed'); }, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.teal, borderRadius: BorderRadius.circular(12), ), child: const Icon(Icons.settings, color: Colors.white, size: 32), ), ), ], ), ), ); } @override void dispose() { ShowcaseView.get().unregister(); super.dispose(); } } ``` -------------------------------- ### Define Global Keys for Showcase Widgets Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Create unique GlobalKey instances for each widget that will be part of the showcase. These keys are used to identify and target specific widgets when initiating the showcase sequence. ```dart final GlobalKey _one = GlobalKey(); final GlobalKey _two = GlobalKey(); final GlobalKey _three = GlobalKey(); ``` -------------------------------- ### Register Showcase View Global Configuration Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Shows how to set global configurations for all showcases using ShowcaseView.register(). When a scope name is not provided, a default scope is used. This method is used to establish the initial or default showcase view settings. ```dart ShowcaseView.register( // appropriate configurations ) ``` -------------------------------- ### Wrap Widgets with Showcase for Tooltips Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Use the Showcase widget to wrap the target UI element. Configure the key, title, and description for the tooltip that will appear when this widget is showcased. The child property holds the actual widget to be displayed. ```dart Showcase( key: _one, title: 'Menu', description: 'Click here to see menu options', child: Icon( Icons.menu, color: Colors.black45, ), ) ``` -------------------------------- ### Scoped Showcases with Dynamic Callbacks in Dart Source: https://context7.com/simformsolutionspvtltd/flutter_showcaseview/llms.txt This Dart code demonstrates setting up and managing scoped showcases in a Flutter application. It covers registering default and named scopes with custom configurations, adding dynamic callbacks for showcase events (completion, dismissal), and triggering showcases programmatically. The `ShowcaseView.register` method is used for scope configuration, while `ShowcaseView.get().addOnCompleteCallback` and `ShowcaseView.getNamed('profile').addOnDismissCallback` handle dynamic event listeners. ```dart import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; class ScopedShowcaseExample extends StatefulWidget { const ScopedShowcaseExample({Key? key}) : super(key: key); @override State createState() => _ScopedShowcaseExampleState(); } class _ScopedShowcaseExampleState extends State { final GlobalKey _mainFeature = GlobalKey(); final GlobalKey _profileFeature = GlobalKey(); @override void initState() { super.initState(); // Register default scope for main app showcase ShowcaseView.register( blurValue: 1.0, autoPlayDelay: const Duration(seconds: 2), onFinish: () { print('Main showcase finished'); }, ); // Register named scope for profile section with different configuration ShowcaseView.register( scope: 'profile', blurValue: 3.0, autoPlayDelay: const Duration(seconds: 4), globalTooltipActionConfig: const TooltipActionConfig( position: TooltipActionPosition.outside, ), onFinish: () { print('Profile showcase finished'); }, ); // Add dynamic callbacks at runtime ShowcaseView.get().addOnCompleteCallback((index, key) { print('Dynamic callback: Completed step $index'); }); ShowcaseView.getNamed('profile').addOnDismissCallback((dismissedAt) { print('Profile showcase dismissed at: $dismissedAt'); }); ShowcaseView.get().addOnFinishCallback(() { print('Additional onFinish callback executed'); // Could navigate to another screen or save completion status }); } void startMainShowcase() { ShowcaseView.get().startShowCase([_mainFeature]); } void startProfileShowcase() { ShowcaseView.getNamed('profile').startShowCase([_profileFeature]); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Scoped Showcase'), actions: [ IconButton( icon: const Icon(Icons.help_outline), onPressed: startMainShowcase, ), ], ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Showcase( key: _mainFeature, title: 'Main Feature', description: 'This uses the default scope configuration', tooltipBackgroundColor: Colors.blue, textColor: Colors.white, child: Container( padding: const EdgeInsets.all(20), color: Colors.blue.shade100, child: const Text('Main App Feature'), ), ), const SizedBox(height: 40), Showcase( key: _profileFeature, scope: 'profile', title: 'Profile Feature', description: 'This uses the profile scope configuration', tooltipBackgroundColor: Colors.purple, textColor: Colors.white, child: ElevatedButton.icon( onPressed: startProfileShowcase, icon: const Icon(Icons.person), label: const Text('View Profile Showcase'), style: ElevatedButton.styleFrom( backgroundColor: Colors.purple, foregroundColor: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), ), ), ), const SizedBox(height: 40), Text( 'Different scopes allow separate configurations\nfor different parts of your app', textAlign: TextAlign.center, style: TextStyle(color: Colors.grey[600]), ), ], ), ), ); } @override void dispose() { ShowcaseView.get().unregister(); ShowcaseView.getNamed('profile').unregister(); super.dispose(); } } ``` -------------------------------- ### Display Multiple Showcases Simultaneously (Dart) Source: https://github.com/simformsolutionspvtltd/flutter_showcaseview/blob/master/doc/documentation.md Demonstrates how to display multiple showcase widgets at the same time by assigning them the same unique key. Note that auto-scrolling is not supported in this mode, and common properties are dictated by the first initialized showcase. ```dart Showcase( key: _multiKey, title: 'First Widget', description: 'This is the first widget', child: Icon(Icons.star), ), Showcase( key: _multiKey, title: 'Second Widget', description: 'This is the second widget', child: Icon(Icons.favorite), ) ```