Introduction Screen allows you to have a screen on an app's first launch to, for example, explain your app. This widget is very customizable with a great design.
introduction_screen uses another package, dots_indicator, that I also created.
You just need to add introduction_screen as a dependency in your pubspec.yaml file.
dependencies:
introduction_screen: ^4.0.0Not all of the many parameters in each class are used in these examples. See Parameter Lists for the complete documentation for each class.
Note: if you want to display IntroductionScreen only once, like on the first start of your app, use
shared_preferences (or a similar strategy)
to save the status of whether it has been already displayed or not.
It's not responsibility of this package to handle this.
A list of PageViewModels is used for IntroductionScreen's pages parameter.
This example only defines the title, body, and image parameters.
(You can define image as any widget.)
PageViewModel(
title: "Title of introduction page",
body: "Welcome to the app! This is a description of how it works.",
image: const Center(
child: Icon(Icons.waving_hand, size: 50.0),
),
)This example defines the color of the page using the decoration parameter.
The image link does not exist and is only for example.
PageViewModel(
title: "Title of blue page",
body: "Welcome to the app! This is a description on a page with a blue background.",
image: Center(
child: Image.network("https://example.com/image.png", height: 175.0),
),
decoration: const PageDecoration(
pageColor: Colors.blue,
),
)This example defines custom TextStyles in the decoration parameter for the title and body.
PageViewModel(
title: "Title of orange text and bold page",
body: "This is a description on a page with an orange title and bold, big body.",
image: const Center(
child: Text("đź‘‹", style: TextStyle(fontSize: 100.0)),
),
decoration: const PageDecoration(
titleTextStyle: TextStyle(color: Colors.orange),
bodyTextStyle: TextStyle(fontWeight: FontWeight.w700, fontSize: 20.0),
),
)This example defines a footer for the page with a button.
The image does not exist and is only for example.
PageViewModel(
title: "Title of custom button page",
body: "This is a description on a page with a custom button below.",
image: Image.asset("res/images/logo.png", height: 175.0),
footer: ElevatedButton(
onPressed: () {
// On button pressed
},
child: const Text("Let's Go!"),
),
)This example defines the page body using bodyWidget and a Widget, rather than with body and a String.
Only use body or bodyWidget.
The titleWidget parameter does the same thing for the title.
PageViewModel(
title: "Title of custom body page",
bodyWidget: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text("Click on "),
Icon(Icons.edit),
Text(" to edit a post"),
],
),
image: const Center(child: Icon(Icons.android)),
)The IntroductionScreen Widget is the single object that holds all pages and related navigation and settings.
In these examples, listPagesViewModel is a list of pages.
A page is a PageViewModel object, like the examples in the previous section.
Note:
- If you not provide the
nextparameter, the "Next" button will be not displayed. The parametershowNextButtonmust then be set tofalse. - If you want to display the "Skip" button, you must add a
skipparameter and setshowSkipButtontotrue. - The
doneparameter is only required ifshowDoneButtonistrue.
This example only defines the pages, showNextButton, done, and onDone parameters.
IntroductionScreen(
pages: listPagesViewModel,
showNextButton: false,
done: const Text("Done"),
onDone: () {
// On button pressed
},
)This example defines showSkipButton and skip to show the "Skip" button on all pages except the last one.
IntroductionScreen(
pages: listPagesViewModel,
showSkipButton: true,
showNextButton: false,
skip: const Text("Skip"),
done: const Text("Done"),
onDone: () {
// On button pressed
},
)This example defines showBackButton and back to show the "Back" button on all pages except the first one.
IntroductionScreen(
pages: listPagesViewModel,
showBackButton: true,
showNextButton: false,
back: const Icon(Icons.arrow_back),
done: const Text("Done"),
onDone: () {
// On button pressed
},
)This example defines dotsDecorator to show a custom implementation of the page progress dots.
This example also uses a custom style for the "Done" button, bolding it.
IntroductionScreen(
pages: listPagesViewModel,
showSkipButton: true,
skip: const Icon(Icons.skip_next),
next: const Text("Next"),
done: const Text("Done", style: TextStyle(fontWeight: FontWeight.w700)),
onDone: () {
// On Done button pressed
},
onSkip: () {
// On Skip button pressed
},
dotsDecorator: DotsDecorator(
size: const Size.square(10.0),
activeSize: const Size(20.0, 10.0),
activeColor: Theme.of(context).colorScheme.secondary,
color: Colors.black26,
spacing: const EdgeInsets.symmetric(horizontal: 3.0),
activeShape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25.0)
),
),
)A custom style will be applied to all buttons using the baseBtnStyle parameter ("Back", "Skip", "Next", "Done").
Specific button style parameters may also be used: backStyle, skipStyle, nextStyle, doneStyle.
If both baseBtnStyle and a specific button style are defined, the baseBtnStyle will be merge with specific style.
The following is the default button style:
TextButton.styleFrom(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8.0),
),
)This example will override the default in the following ways:
- All buttons have a light grey background
- The "Skip" button is red
- The "Done" button is green
- The "Next" button is blue
IntroductionScreen(
pages: listPagesViewModel,
showSkipButton: true,
skip: const Text("Skip"),
next: const Text("Next"),
done: const Text("Done"),
onDone: () {
// When done button is press
},
baseBtnStyle: TextButton.styleFrom(
backgroundColor: Colors.grey.shade200,
),
skipStyle: TextButton.styleFrom(primary: Colors.red),
doneStyle: TextButton.styleFrom(primary: Colors.green),
nextStyle: TextButton.styleFrom(primary: Colors.blue),
)To change page manually / programatically, in response to user input or another event:
- Define a
GlobalKeyas part of the parent widget's state - Pass that key to the
IntroductionScreenkeyparam - Use the
currentStatemember to access functions defined inIntroductionScreenStatee.g.next()previous()skipToEnd()animateScroll()
This example moves to the next page after a delay:
class IntroScreenDemo extends StatefulWidget {
@override
State<IntroScreenDemo> createState() => _IntroScreenDemoState();
}
class _IntroScreenDemoState extends State<IntroScreenDemo> {
// 1. Define a `GlobalKey` as part of the parent widget's state
final _introKey = GlobalKey<IntroductionScreenState>();
String _status = 'Waiting...';
@override
Widget build(BuildContext context) {
return IntroductionScreen(
// 2. Pass that key to the `IntroductionScreen` `key` param
key: _introKey,
pages: [
PageViewModel(
title: 'Page One',
bodyWidget: Column(
children: [
Text(_status),
ElevatedButton(
onPressed: () {
setState(() => _status = 'Going to the next page...');
// 3. Use the `currentState` member to access functions defined in `IntroductionScreenState`
Future.delayed(const Duration(seconds: 3),
() => _introKey.currentState?.next());
},
child: const Text('Start'))
],
)),
PageViewModel(
title: 'Page Two', bodyWidget: const Text('That\'s all folks'))
],
showNextButton: false,
showDoneButton: false,
);
}
}Many parameters can be used to customize your app introduction like you want! This is the full list:
- Page that will be display (
PageViewModel), by addingpages: [..]parameter. - Use your own pages (Widget) without using those predefined, by adding
rawPages: [..]parameter.- If you provide both
rawPagesandpagesparameter,pageswill be used.
- If you provide both
- Set a custom callback when done button is pressed, by adding
onDone: () {}parameter.- This param is required if you define
doneparam, EXCEPT if you setshowDoneButton: false - If you set
overrideDoneparam, it will be ignored.
- This param is required if you define
- Set a custom callback when skip button is pressed, by adding
onSkip: () {}parameter.- By default, it will go to the last page
- If you set
overrideSkipparam, it will be ignored.
- Add callback to listen page changes, by adding
onChange: (page) {}parameter.
- Define pre-made Done button child (Widget), by adding
done: Text('Done')- This param or
overrideDoneare required, EXCEPT if you setshowDoneButton: false - By providing
done, the parameteronDoneis also required.
- This param or
- Define pre-made Next button child (Widget), by adding
next: Text('Next')- This param is required, EXCEPT if you set
showNextButton: false
- This param is required, EXCEPT if you set
- Define pre-made Skip button child (Widget), by adding
skip: Text('Skip')- This param is required if you set
showSkipButton: true
- This param is required if you set
- Define pre-made Back button child (Widget), by adding
back: Text('Back')- This param is required if you set
showBackButton: true
- This param is required if you set
If you want to control pages, you can use key param. Search this repo's Issues for more detailed information.
- Define your custom Done button (Widget), by using
overrideDone- This param or
doneare required, EXCEPT if you setshowDoneButton: false - This parameter has priority over the
doneparameter.
- This param or
- Define your custom Next button (Widget), by using
overrideNext- This param or
nextare required, EXCEPT if you setshowNextButton: false - This parameter has priority over the
nextparameter.
- This param or
- Define your custom Skip button (Widget), by using
overrideSkip- This param or
skipare required if you setshowSkipButton: true - This parameter has priority over the
skipparameter.
- This param or
- Define your custom Back button (Widget), by using
overrideBack- This param or
backare required if you setshowBackButton: true - This parameter has priority over the
skipparameter.
- This param or
- Define your custom dots widget (or the widget that you want on that position), by using
customProgress
- Hide/show Skip button, by adding
showSkipButton: falseparameter.- Default
false
- Default
- Hide/show Next button, by adding
showNextButton: falseparameter.- Default
true
- Default
- Hide/show Done button, by adding
showDoneButton: falseparameter.- Default
true
- Default
- Hide/show Back button, by adding
showBackButton: falseparameter.- Default
false
- Default
- Display or not the progress dots, by adding
isProgress: falseparameter.- Default
true
- Default
- Enable or disable dots progress tap, by adding
isProgressTap: falseparameter.- Default
true
- Default
- Freeze the scroll, by adding
freeze: trueparameter.- Default
false
- Default
- Duration of scrolling animation, by adding
animationDuration: 400parameter.- Default
350
- Default
- Initial page, by adding
initialPage: 2parameter.- Default
0
- Default
- You can provide a ScrollController for each page by adding
scrollControllers: [..]parameter.- If you have 5 pages, you can provide 5 differents ScrollController.
- If you want to have only one ScrollController for page 1, you can provide:
scrollControllers: [controller1] - If you want to have only one ScrollController for page 3, you can provide:
scrollControllers: [null, null, controller1] - Will be ignored for page(s) if
useScrollViewis set tofalsein PageViewModel(s)
- Global background color, by adding
globalBackgroundColor: Colors.blueparameter.- Tips: use
Colors.transparentto display an image as background (using Stack with IntroductionScreen inside for example)
- Tips: use
- Customize dots (progression) by adding
dotsDecorator: DotsDecorator(...)- You can customize dots size, shape, colors, spacing.
- Customize dots container by adding
dotsContainerDecorator: BoxDecorator(...)- You can customize container that contain controls.
- Skip/Back button flex, by adding
skipOrBackFlex: 1parameter.- Set 0 to disable Expanded behaviour, default
1
- Set 0 to disable Expanded behaviour, default
- Dots indicator flex, by adding
dotsFlex: 1parameter.- Set 0 to disable Expanded behaviour, default
1
- Set 0 to disable Expanded behaviour, default
- Next/Done button flex, by adding
nextFlex: 1parameter.- Set 0 to disable Expanded behaviour, default
1
- Set 0 to disable Expanded behaviour, default
- Animation curve between pages, by adding
curve: Curves.elasticInparameter.- Default
Curves.easeIn
- Default
- Change global style of buttons (for skip, next, done, back), by adding
baseBtnStyleparameter. - Change skip button style, by adding
skipStyle: TextButton.styleFrom(alignment: Alignment.centerLeft)parameter. - Change next button style, by adding
nextStyle: TextButton.styleFrom(alignment: Alignment.centerRight)parameter. - Change done button style, by adding
doneStyle: TextButton.styleFrom(splashFactory: NoSplash.splashFactory)parameter. - Change back button style, by adding
backStyle: TextButton.styleFrom(primary: Colors.red)parameter.
- Change skip button semantic label, by adding
skipSemantic: 'Skip introduction'parameter. - Change next button semantic label, by adding
nextSemantic: 'Go to next page'parameter. - Change done button semantic label, by adding
doneSemantic: 'Exit introduction'parameter. - Change back button semantic label, by adding
backSemantic: 'Go to previous page'parameter.
- Show the bottom part of the page, that include skip, next, done buttons by setting
showBottomPart: trueparameter. - Hide the bottom part of the page when the keyboard is open with
hideBottomOnKeyboardparameter. - Customize controls position on screen, by adding
controlsPosition: const Position(left: 0, right: 0, bottom: 100)parameter.- Default
const Position(left: 0, right: 0, bottom: 0)
- Default
- Customize margin of controls's container, by adding
controlsMargin: EdgeInsets.all(16.0)parameter.- Default
EdgeInsets.zero
- Default
- Customize padding of controls's container, by adding
controlsPadding: EdgeInsets.all(8.0)parameter.- Default
EdgeInsets.all(16.0)
- Default
- Add global header (top), static and displayed above pages, by adding
globalHeader: Image.asset(...)parameter. - Add global footer below controls/dots, by adding
globalFooter: ElevatedButton(...)parameter. - Change axis of scroll by adding
pagesAxis: Axis.vertical.- Default
Axis.horizontal
- Default
- Change default scroll physics of PageView by adding
scrollPhysics: ClampingScrollPhysics().- Default
BouncingScrollPhysics()
- Default
- You can also enable right-to-left behavior by adding
rtl: true.- Default
false
- Default
- Change default implicit scrolling behavior by adding
allowImplicitScrolling: true- Default
false - Reference: PageView's
allowImplicitScrollingparameter
- Default
- Activate the SafeArea by setting
safeAreaList: [true,true,true,true]parameter.
You can provide many parameters to customize each pages:
title: "Title of the page"ortitleWidget: Text("Custom widget for title")body: "Body of the page"orbodyWidget: Text("Custom widget for body")image: Image.asset(...)image of the page.- It's expecting a Widget, so if you want to pass a Video, Text, or anything else, you can.
backgroundImage: 'assets/fullscreen.jpg'background image of the page (optional).- It's expecting a String with a path to an image asset. Works just like the
imageparameter under the hood while making an asset span all over the screen. - Doesn't affect the
imagenorfullscreenparameters: can be used together with them to build more complex layouts.
- It's expecting a String with a path to an image asset. Works just like the
footer: ElevatedButton(...), display a widget below body- Like image param, it's expecting a Widget, you can pass what you want.
decoration: PageDecoration(...), page decoration to customize page- See next section for all parameters you can pass
reverse: true, reverse order of image and content (title/body). (Default:false)useScrollView: false, by default pages use a Scrollview to handle small screen or long body text. You can remove ScrollView by setting to false.scrollViewKeyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.manual, by default the keyboard dismiss behavious is manual, you can change it.- Only used if useScrollView not set to false.
pageColor: Colors.white, background color of the page- You cannot use both pageColor and boxDecoration params
titleTextStyle: TextStyle(...), TextStyle of the titlebodyTextStyle: TextStyle(...), TextStyle of the bodyboxDecoration: BoxDecoration(...), BoxDecoration of page container- You cannot use both pageColor and boxDecoration params
imageFlex: 2, flex ratio of the imagebodyFlex: 3, flex ratio of the content (title/body)footerFlex: 1, flex ratio of the content (title/body)footerFit: FlexFit.loose, flex ratio of the content (title/body)imagePadding: EdgeInsets.only(bottom: 12.0), padding of the image Widget. (DefaultEdgeInsets.only(bottom: 24.0))contentPadding: EdgeInsets.only(all: 24.0), padding of the content (title/body/footer) Widget. (DefaultEdgeInsets.all(16))titlePadding: EdgeInsets.only(bottom: 24.0), padding of the title text/Widget. (DefaultEdgeInsets.only(top: 16.0, bottom: 24.0))descriptionPadding: EdgeInsets.only(bottom: 24.0), padding of the body text/Widget. (DefaultEdgeInsets.zero)footerPadding: EdgeInsets.only(top: 24.0), padding of the footer text/Widget. (DefaultEdgeInsets.symmetric(vertical: 24.0))bodyAlignment: Align.center, content (title, body, footer) alignment. (DefaultAlign.topCenter)imageAlignment: Align.center, image alignment. (DefaultAlign.bottomCenter)fullScreen: true, Set image as fullscreen (background). (Defaultfalse)
