mirror of
https://github.com/Iconica-Development/flutter_introduction.git
synced 2025-05-18 19:43:44 +02:00
fix: feedback userstory
This commit is contained in:
parent
55727fa76d
commit
6808ee972d
16 changed files with 265 additions and 253 deletions
|
@ -1,3 +1,8 @@
|
||||||
|
## 3.1.0
|
||||||
|
|
||||||
|
* Introduction now uses `IntroductionScreenMode` to determine how often the introductions should be shown
|
||||||
|
* Added `dotSize` and `dotSpacing` to `IntroductionOptions` to allow for customization of the dots for the introduction
|
||||||
|
|
||||||
## 3.0.0
|
## 3.0.0
|
||||||
|
|
||||||
* Update default styling
|
* Update default styling
|
||||||
|
|
|
@ -56,7 +56,9 @@ class _IntroductionState extends State<Introduction> {
|
||||||
// ignore: discarded_futures
|
// ignore: discarded_futures
|
||||||
future: _service.shouldShow(),
|
future: _service.shouldShow(),
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.data == null || snapshot.data!) {
|
if (snapshot.data == null ||
|
||||||
|
snapshot.data! ||
|
||||||
|
widget.options.mode == IntroductionScreenMode.showAlways) {
|
||||||
return IntroductionScreen(
|
return IntroductionScreen(
|
||||||
options: widget.options,
|
options: widget.options,
|
||||||
onComplete: () async {
|
onComplete: () async {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_introduction
|
name: flutter_introduction
|
||||||
description: Combined Package of Flutter Introduction Widget and Flutter Introduction Service
|
description: Combined Package of Flutter Introduction Widget and Flutter Introduction Service
|
||||||
version: 3.0.0
|
version: 3.1.0
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
@ -13,12 +13,12 @@ dependencies:
|
||||||
flutter_introduction_widget:
|
flutter_introduction_widget:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_introduction
|
url: https://github.com/Iconica-Development/flutter_introduction
|
||||||
ref: 3.0.0
|
ref: 3.1.0
|
||||||
path: packages/flutter_introduction_widget
|
path: packages/flutter_introduction_widget
|
||||||
flutter_introduction_service:
|
flutter_introduction_service:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_introduction
|
url: https://github.com/Iconica-Development/flutter_introduction
|
||||||
ref: 3.0.0
|
ref: 3.1.0
|
||||||
path: packages/flutter_introduction_service
|
path: packages/flutter_introduction_service
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_introduction_firebase
|
name: flutter_introduction_firebase
|
||||||
description: Flutter Introduction Page that uses firebase for the pages and some settings
|
description: Flutter Introduction Page that uses firebase for the pages and some settings
|
||||||
version: 3.0.0
|
version: 3.1.0
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
@ -15,12 +15,12 @@ dependencies:
|
||||||
flutter_introduction_widget:
|
flutter_introduction_widget:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_introduction
|
url: https://github.com/Iconica-Development/flutter_introduction
|
||||||
ref: 3.0.0
|
ref: 3.1.0
|
||||||
path: packages/flutter_introduction_widget
|
path: packages/flutter_introduction_widget
|
||||||
flutter_introduction_service:
|
flutter_introduction_service:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_introduction
|
url: https://github.com/Iconica-Development/flutter_introduction
|
||||||
ref: 3.0.0
|
ref: 3.1.0
|
||||||
path: packages/flutter_introduction_service
|
path: packages/flutter_introduction_service
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_introduction_interface
|
name: flutter_introduction_interface
|
||||||
description: A new Flutter package project.
|
description: A new Flutter package project.
|
||||||
version: 3.0.0
|
version: 3.1.0
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_introduction_service
|
name: flutter_introduction_service
|
||||||
description: A new Flutter package project.
|
description: A new Flutter package project.
|
||||||
version: 3.0.0
|
version: 3.1.0
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
@ -13,7 +13,7 @@ dependencies:
|
||||||
flutter_introduction_interface:
|
flutter_introduction_interface:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_introduction
|
url: https://github.com/Iconica-Development/flutter_introduction
|
||||||
ref: 3.0.0
|
ref: 3.1.0
|
||||||
path: packages/flutter_introduction_interface
|
path: packages/flutter_introduction_interface
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_introduction_shared_preferences
|
name: flutter_introduction_shared_preferences
|
||||||
description: A new Flutter package project.
|
description: A new Flutter package project.
|
||||||
version: 3.0.0
|
version: 3.1.0
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
@ -13,7 +13,7 @@ dependencies:
|
||||||
flutter_introduction_interface:
|
flutter_introduction_interface:
|
||||||
git:
|
git:
|
||||||
url: https://github.com/Iconica-Development/flutter_introduction
|
url: https://github.com/Iconica-Development/flutter_introduction
|
||||||
ref: 3.0.0
|
ref: 3.1.0
|
||||||
path: packages/flutter_introduction_interface
|
path: packages/flutter_introduction_interface
|
||||||
shared_preferences: any
|
shared_preferences: any
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 61 KiB |
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 49 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 33 KiB |
|
@ -1,33 +1,16 @@
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_introduction_widget/flutter_introduction_widget.dart';
|
import 'package:flutter_introduction_widget/flutter_introduction_widget.dart';
|
||||||
|
|
||||||
const List<IntroductionPage> defaultIntroductionPages = [
|
const List<IntroductionPage> defaultIntroductionPages = [
|
||||||
IntroductionPage(
|
IntroductionPage(
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Color(0xffFAF9F6),
|
|
||||||
),
|
|
||||||
title: Column(
|
title: Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 100),
|
SizedBox(height: 50),
|
||||||
Text(
|
Text(
|
||||||
'welcome to iconinstagram',
|
'welcome to iconinstagram',
|
||||||
style: TextStyle(
|
|
||||||
color: Color(0xff71C6D1),
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 6),
|
SizedBox(height: 6),
|
||||||
Text(
|
|
||||||
'Welcome to the world of Instagram, where creativity'
|
|
||||||
' knows no bounds and connections are made'
|
|
||||||
' through captivating visuals.',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
graphic: Image(
|
graphic: Image(
|
||||||
|
@ -36,72 +19,46 @@ const List<IntroductionPage> defaultIntroductionPages = [
|
||||||
package: 'flutter_introduction_widget',
|
package: 'flutter_introduction_widget',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
text: Text(''),
|
text: Text(
|
||||||
|
'Welcome to the world of Instagram, where creativity'
|
||||||
|
' knows no bounds and connections are made'
|
||||||
|
' through captivating visuals.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
IntroductionPage(
|
IntroductionPage(
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Color(0xffFAF9F6),
|
|
||||||
),
|
|
||||||
title: Column(
|
title: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 100),
|
SizedBox(height: 50),
|
||||||
Text(
|
Text(
|
||||||
'discover iconinstagram',
|
'discover iconinstagram',
|
||||||
style: TextStyle(
|
|
||||||
color: Color(0xff71C6D1),
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 6),
|
SizedBox(height: 6),
|
||||||
Text(
|
|
||||||
'Dive into the vibrant world of'
|
|
||||||
' Instagram and discover endless possibilities.'
|
|
||||||
' From stunning photography to engaging videos,'
|
|
||||||
' Instagram offers a diverse range of content to explore and enjoy.',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
text: Text(
|
||||||
|
'Dive into the vibrant world of'
|
||||||
|
' Instagram and discover endless possibilities.'
|
||||||
|
' From stunning photography to engaging videos,'
|
||||||
|
' Instagram offers a diverse range of content to explore and enjoy.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
graphic: Image(
|
graphic: Image(
|
||||||
image: AssetImage(
|
image: AssetImage(
|
||||||
'assets/second.png',
|
'assets/second.png',
|
||||||
package: 'flutter_introduction_widget',
|
package: 'flutter_introduction_widget',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
text: Text(''),
|
|
||||||
),
|
),
|
||||||
IntroductionPage(
|
IntroductionPage(
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Color(0xffFAF9F6),
|
|
||||||
),
|
|
||||||
title: Column(
|
title: Column(
|
||||||
children: [
|
children: [
|
||||||
SizedBox(height: 100),
|
SizedBox(height: 50),
|
||||||
Text(
|
Text(
|
||||||
'elevate your experience',
|
'elevate your experience',
|
||||||
style: TextStyle(
|
|
||||||
color: Color(0xff71C6D1),
|
|
||||||
fontSize: 24,
|
|
||||||
fontWeight: FontWeight.w700,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
SizedBox(height: 6),
|
SizedBox(height: 6),
|
||||||
Text(
|
|
||||||
'Whether promoting your business, or connecting'
|
|
||||||
' with friends and family, Instagram provides the'
|
|
||||||
' tools and platform to make your voice heard.',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
fontWeight: FontWeight.w400,
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
graphic: Image(
|
graphic: Image(
|
||||||
|
@ -110,6 +67,11 @@ const List<IntroductionPage> defaultIntroductionPages = [
|
||||||
package: 'flutter_introduction_widget',
|
package: 'flutter_introduction_widget',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
text: Text(''),
|
text: Text(
|
||||||
|
'Whether promoting your business, or connecting'
|
||||||
|
' with friends and family, Instagram provides the'
|
||||||
|
' tools and platform to make your voice heard.',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
|
@ -63,7 +63,7 @@ class IntroductionOptions {
|
||||||
this.introductionButtonTextstyles = const IntroductionButtonTextstyles(),
|
this.introductionButtonTextstyles = const IntroductionButtonTextstyles(),
|
||||||
this.indicatorMode = IndicatorMode.dot,
|
this.indicatorMode = IndicatorMode.dot,
|
||||||
this.indicatorBuilder,
|
this.indicatorBuilder,
|
||||||
this.layoutStyle = IntroductionLayoutStyle.imageCenter,
|
this.layoutStyle = IntroductionLayoutStyle.imageBottom,
|
||||||
this.pages = defaultIntroductionPages,
|
this.pages = defaultIntroductionPages,
|
||||||
this.buttonMode = IntroductionScreenButtonMode.text,
|
this.buttonMode = IntroductionScreenButtonMode.text,
|
||||||
this.tapEnabled = false,
|
this.tapEnabled = false,
|
||||||
|
@ -73,6 +73,8 @@ class IntroductionOptions {
|
||||||
this.skippable = false,
|
this.skippable = false,
|
||||||
this.buttonBuilder,
|
this.buttonBuilder,
|
||||||
this.controlMode = IntroductionControlMode.previousNextButton,
|
this.controlMode = IntroductionControlMode.previousNextButton,
|
||||||
|
this.dotSize = 12,
|
||||||
|
this.dotSpacing = 24,
|
||||||
}) : assert(
|
}) : assert(
|
||||||
!(identical(indicatorMode, IndicatorMode.custom) &&
|
!(identical(indicatorMode, IndicatorMode.custom) &&
|
||||||
indicatorBuilder == null),
|
indicatorBuilder == null),
|
||||||
|
@ -204,6 +206,12 @@ class IntroductionOptions {
|
||||||
/// - Finish
|
/// - Finish
|
||||||
final IntroductionButtonTextstyles introductionButtonTextstyles;
|
final IntroductionButtonTextstyles introductionButtonTextstyles;
|
||||||
|
|
||||||
|
/// The size of the dots in the indicator. Default is 12
|
||||||
|
final double dotSize;
|
||||||
|
|
||||||
|
/// The distance between the center of each dot. Default is 24
|
||||||
|
final double dotSpacing;
|
||||||
|
|
||||||
IntroductionOptions copyWith({
|
IntroductionOptions copyWith({
|
||||||
IntroductionScreenMode? mode,
|
IntroductionScreenMode? mode,
|
||||||
List<IntroductionPage>? pages,
|
List<IntroductionPage>? pages,
|
||||||
|
@ -248,7 +256,7 @@ class IntroductionOptions {
|
||||||
|
|
||||||
class IntroductionTranslations {
|
class IntroductionTranslations {
|
||||||
const IntroductionTranslations({
|
const IntroductionTranslations({
|
||||||
this.skipButton = 'skip',
|
this.skipButton = 'Skip',
|
||||||
this.nextButton = 'Next',
|
this.nextButton = 'Next',
|
||||||
this.previousButton = 'Previous',
|
this.previousButton = 'Previous',
|
||||||
this.finishButton = 'Get Started',
|
this.finishButton = 'Get Started',
|
||||||
|
|
|
@ -155,10 +155,15 @@ class _MultiPageIntroductionScreenState
|
||||||
controller: _controller,
|
controller: _controller,
|
||||||
count: pages.length,
|
count: pages.length,
|
||||||
index: _currentPage.value,
|
index: _currentPage.value,
|
||||||
|
dotSize: widget.options.dotSize,
|
||||||
|
dotSpacing: widget.options.dotSpacing,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(32),
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 40,
|
||||||
|
horizontal: 20,
|
||||||
|
),
|
||||||
child: AnimatedBuilder(
|
child: AnimatedBuilder(
|
||||||
animation: _controller,
|
animation: _controller,
|
||||||
builder: (context, _) {
|
builder: (context, _) {
|
||||||
|
@ -270,14 +275,14 @@ class ExplainerPage extends StatelessWidget {
|
||||||
title: Padding(
|
title: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||||
child: DefaultTextStyle(
|
child: DefaultTextStyle(
|
||||||
style: theme.textTheme.displayMedium!,
|
style: theme.textTheme.titleMedium!,
|
||||||
child: page.title ?? Text('introduction.$index.title'),
|
child: page.title ?? Text('introduction.$index.title'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
text: Padding(
|
text: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 32),
|
padding: const EdgeInsets.symmetric(horizontal: 32),
|
||||||
child: DefaultTextStyle(
|
child: DefaultTextStyle(
|
||||||
style: theme.textTheme.bodyLarge!,
|
style: theme.textTheme.bodyMedium!,
|
||||||
child: page.text ?? Text('introduction.$index.description'),
|
child: page.text ?? Text('introduction.$index.description'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -340,116 +345,148 @@ class IntroductionTwoButtons extends StatelessWidget {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
if (options.buttonMode == IntroductionScreenButtonMode.text) ...[
|
if (options.buttonMode == IntroductionScreenButtonMode.text) ...[
|
||||||
if (previous) ...[
|
Flexible(
|
||||||
options.buttonBuilder?.call(
|
child: Padding(
|
||||||
context,
|
padding: const EdgeInsets.only(right: 6),
|
||||||
_previous,
|
child: ConstrainedBox(
|
||||||
Text(
|
constraints: const BoxConstraints(
|
||||||
translations.previousButton,
|
maxWidth: 180,
|
||||||
style: options
|
),
|
||||||
.introductionButtonTextstyles.previousButtonStyle,
|
child: Opacity(
|
||||||
),
|
opacity: previous ? 1 : 0,
|
||||||
IntroductionButtonType.previous,
|
child: IgnorePointer(
|
||||||
) ??
|
ignoring: !previous,
|
||||||
InkWell(
|
child: options.buttonBuilder?.call(
|
||||||
onTap: _previous,
|
context,
|
||||||
child: Container(
|
_previous,
|
||||||
width: 180,
|
Text(
|
||||||
decoration: BoxDecoration(
|
translations.previousButton,
|
||||||
borderRadius: BorderRadius.circular(20),
|
style: options.introductionButtonTextstyles
|
||||||
border: Border.all(
|
.previousButtonStyle,
|
||||||
color: const Color(
|
),
|
||||||
0xff979797,
|
IntroductionButtonType.previous,
|
||||||
|
) ??
|
||||||
|
InkWell(
|
||||||
|
onTap: _previous,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(
|
||||||
|
0xff979797,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: Text(
|
||||||
|
translations.previousButton,
|
||||||
|
style: options.introductionButtonTextstyles
|
||||||
|
.previousButtonStyle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
|
||||||
child: Text(
|
|
||||||
translations.previousButton,
|
|
||||||
style: options
|
|
||||||
.introductionButtonTextstyles.previousButtonStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
] else
|
),
|
||||||
const SizedBox.shrink(),
|
),
|
||||||
|
),
|
||||||
if (next) ...[
|
if (next) ...[
|
||||||
options.buttonBuilder?.call(
|
Flexible(
|
||||||
context,
|
child: Padding(
|
||||||
_next,
|
padding: const EdgeInsets.only(left: 6),
|
||||||
Text(
|
child: ConstrainedBox(
|
||||||
translations.nextButton,
|
constraints: const BoxConstraints(
|
||||||
style: options.introductionButtonTextstyles.nextButtonStyle,
|
maxWidth: 180,
|
||||||
),
|
),
|
||||||
IntroductionButtonType.next,
|
child: options.buttonBuilder?.call(
|
||||||
) ??
|
context,
|
||||||
InkWell(
|
_next,
|
||||||
onTap: _next,
|
Text(
|
||||||
child: Container(
|
|
||||||
width: 180,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
border: Border.all(
|
|
||||||
color: const Color(
|
|
||||||
0xff979797,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
|
||||||
child: Text(
|
|
||||||
translations.nextButton,
|
translations.nextButton,
|
||||||
style: options
|
style: options
|
||||||
.introductionButtonTextstyles.nextButtonStyle,
|
.introductionButtonTextstyles.nextButtonStyle,
|
||||||
),
|
),
|
||||||
),
|
IntroductionButtonType.next,
|
||||||
),
|
) ??
|
||||||
),
|
InkWell(
|
||||||
),
|
onTap: _next,
|
||||||
] else if (last) ...[
|
child: Container(
|
||||||
options.buttonBuilder?.call(
|
decoration: BoxDecoration(
|
||||||
context,
|
borderRadius: BorderRadius.circular(20),
|
||||||
() {
|
border: Border.all(
|
||||||
onFinish?.call();
|
color: const Color(
|
||||||
},
|
0xff979797,
|
||||||
Text(
|
),
|
||||||
translations.finishButton,
|
),
|
||||||
style:
|
),
|
||||||
options.introductionButtonTextstyles.finishButtonStyle,
|
child: Center(
|
||||||
),
|
child: Padding(
|
||||||
IntroductionButtonType.finish,
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
) ??
|
child: Text(
|
||||||
InkWell(
|
translations.nextButton,
|
||||||
onTap: () {
|
style: options.introductionButtonTextstyles
|
||||||
onFinish?.call();
|
.nextButtonStyle,
|
||||||
},
|
),
|
||||||
child: Container(
|
),
|
||||||
width: 180,
|
),
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
border: Border.all(
|
|
||||||
color: const Color(
|
|
||||||
0xff979797,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Center(
|
),
|
||||||
child: Padding(
|
),
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
] else if (last) ...[
|
||||||
child: Text(
|
Flexible(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 6),
|
||||||
|
child: ConstrainedBox(
|
||||||
|
constraints: const BoxConstraints(
|
||||||
|
maxWidth: 180,
|
||||||
|
),
|
||||||
|
child: options.buttonBuilder?.call(
|
||||||
|
context,
|
||||||
|
() {
|
||||||
|
onFinish?.call();
|
||||||
|
},
|
||||||
|
Text(
|
||||||
translations.finishButton,
|
translations.finishButton,
|
||||||
style: options
|
style: options
|
||||||
.introductionButtonTextstyles.finishButtonStyle,
|
.introductionButtonTextstyles.finishButtonStyle,
|
||||||
),
|
),
|
||||||
|
IntroductionButtonType.finish,
|
||||||
|
) ??
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
onFinish?.call();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(
|
||||||
|
0xff979797,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: Text(
|
||||||
|
translations.finishButton,
|
||||||
|
style: options.introductionButtonTextstyles
|
||||||
|
.finishButtonStyle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
] else ...[
|
] else ...[
|
||||||
const SizedBox.shrink(),
|
const SizedBox.shrink(),
|
||||||
],
|
],
|
||||||
|
@ -463,44 +500,51 @@ class IntroductionTwoButtons extends StatelessWidget {
|
||||||
maintainState: true,
|
maintainState: true,
|
||||||
maintainInteractivity: false,
|
maintainInteractivity: false,
|
||||||
child: Align(
|
child: Align(
|
||||||
child: options.buttonBuilder?.call(
|
child: Flexible(
|
||||||
context,
|
child: ConstrainedBox(
|
||||||
() {
|
constraints: const BoxConstraints(
|
||||||
onFinish?.call();
|
maxWidth: 180,
|
||||||
},
|
|
||||||
Text(
|
|
||||||
translations.finishButton,
|
|
||||||
style: options
|
|
||||||
.introductionButtonTextstyles.finishButtonStyle,
|
|
||||||
),
|
|
||||||
IntroductionButtonType.finish,
|
|
||||||
) ??
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
onFinish?.call();
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
width: 180,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
border: Border.all(
|
|
||||||
color: const Color(
|
|
||||||
0xff979797,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Center(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(vertical: 2.0),
|
|
||||||
child: Text(
|
|
||||||
translations.finishButton,
|
|
||||||
style: options.introductionButtonTextstyles
|
|
||||||
.finishButtonStyle,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
|
child: options.buttonBuilder?.call(
|
||||||
|
context,
|
||||||
|
() {
|
||||||
|
onFinish?.call();
|
||||||
|
},
|
||||||
|
Text(
|
||||||
|
translations.finishButton,
|
||||||
|
style: options
|
||||||
|
.introductionButtonTextstyles.finishButtonStyle,
|
||||||
|
),
|
||||||
|
IntroductionButtonType.finish,
|
||||||
|
) ??
|
||||||
|
InkWell(
|
||||||
|
onTap: () {
|
||||||
|
onFinish?.call();
|
||||||
|
},
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
border: Border.all(
|
||||||
|
color: const Color(
|
||||||
|
0xff979797,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets.symmetric(vertical: 4),
|
||||||
|
child: Text(
|
||||||
|
translations.finishButton,
|
||||||
|
style: options.introductionButtonTextstyles
|
||||||
|
.finishButtonStyle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
// SPDX-License-Identifier: BSD-3-Clause
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:math';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_introduction_widget/src/config/introduction.dart';
|
import 'package:flutter_introduction_widget/src/config/introduction.dart';
|
||||||
|
@ -16,6 +15,8 @@ class Indicator extends StatelessWidget {
|
||||||
required this.count,
|
required this.count,
|
||||||
required this.index,
|
required this.index,
|
||||||
required this.indicatorBuilder,
|
required this.indicatorBuilder,
|
||||||
|
required this.dotSize,
|
||||||
|
required this.dotSpacing,
|
||||||
super.key,
|
super.key,
|
||||||
}) : assert(
|
}) : assert(
|
||||||
!(mode == IndicatorMode.custom && indicatorBuilder == null),
|
!(mode == IndicatorMode.custom && indicatorBuilder == null),
|
||||||
|
@ -39,6 +40,12 @@ class Indicator extends StatelessWidget {
|
||||||
final Widget Function(BuildContext, PageController, int, int)?
|
final Widget Function(BuildContext, PageController, int, int)?
|
||||||
indicatorBuilder;
|
indicatorBuilder;
|
||||||
|
|
||||||
|
/// The size of the dots.
|
||||||
|
final double dotSize;
|
||||||
|
|
||||||
|
/// The distance between the center of each dot.
|
||||||
|
final double dotSpacing;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var theme = Theme.of(context);
|
var theme = Theme.of(context);
|
||||||
|
@ -47,9 +54,10 @@ class Indicator extends StatelessWidget {
|
||||||
return indicatorBuilder!.call(context, controller, index, count);
|
return indicatorBuilder!.call(context, controller, index, count);
|
||||||
case IndicatorMode.dot:
|
case IndicatorMode.dot:
|
||||||
return DotsIndicator(
|
return DotsIndicator(
|
||||||
|
dotSize: dotSize,
|
||||||
|
dotSpacing: dotSpacing,
|
||||||
controller: controller,
|
controller: controller,
|
||||||
color: theme.colorScheme.primary,
|
color: theme.colorScheme.secondary,
|
||||||
dotcolor: theme.colorScheme.secondary,
|
|
||||||
itemCount: count,
|
itemCount: count,
|
||||||
onPageSelected: (int page) {
|
onPageSelected: (int page) {
|
||||||
unawaited(
|
unawaited(
|
||||||
|
@ -153,16 +161,15 @@ class DotsIndicator extends AnimatedWidget {
|
||||||
const DotsIndicator({
|
const DotsIndicator({
|
||||||
required this.controller,
|
required this.controller,
|
||||||
this.color = Colors.white,
|
this.color = Colors.white,
|
||||||
this.dotcolor = Colors.green,
|
|
||||||
this.itemCount,
|
this.itemCount,
|
||||||
this.onPageSelected,
|
this.onPageSelected,
|
||||||
|
this.dotSize = 8.0,
|
||||||
|
this.dotSpacing = 24.0,
|
||||||
super.key,
|
super.key,
|
||||||
}) : super(
|
}) : super(
|
||||||
listenable: controller,
|
listenable: controller,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// The PageController that this DotsIndicator is representing.
|
|
||||||
final Color? dotcolor;
|
|
||||||
final PageController controller;
|
final PageController controller;
|
||||||
|
|
||||||
/// The number of items managed by the PageController
|
/// The number of items managed by the PageController
|
||||||
|
@ -177,47 +184,31 @@ class DotsIndicator extends AnimatedWidget {
|
||||||
final Color color;
|
final Color color;
|
||||||
|
|
||||||
// The base size of the dots
|
// The base size of the dots
|
||||||
static const double _kDotSize = 4.0;
|
final double dotSize;
|
||||||
|
final double dotSpacing;
|
||||||
|
|
||||||
// The increase in the size of the selected dot
|
Widget _buildDot(int index) => SizedBox(
|
||||||
static const double _kMaxZoom = 2.0;
|
width: dotSpacing,
|
||||||
|
child: Center(
|
||||||
// The distance between the center of each dot
|
child: Material(
|
||||||
static const double _kDotSpacing = 12.0;
|
color:
|
||||||
|
(((controller.page ?? controller.initialPage).round()) == index
|
||||||
Widget _buildDot(int index) {
|
? color
|
||||||
var selectedness = Curves.easeOut.transform(
|
: color.withAlpha(125)),
|
||||||
max(
|
type: MaterialType.circle,
|
||||||
0.0,
|
child: Container(
|
||||||
1.0 -
|
decoration: const BoxDecoration(
|
||||||
((controller.page ?? controller.initialPage).round() - index).abs(),
|
shape: BoxShape.circle,
|
||||||
),
|
),
|
||||||
);
|
width: dotSize,
|
||||||
var zoom = 1.0 + (_kMaxZoom - 1.0) * selectedness;
|
height: dotSize,
|
||||||
|
child: InkWell(
|
||||||
return SizedBox(
|
onTap: () => onPageSelected!.call(index),
|
||||||
width: _kDotSpacing,
|
),
|
||||||
child: Center(
|
|
||||||
child: Material(
|
|
||||||
color: (((controller.page ?? controller.initialPage).round()) == index
|
|
||||||
? color
|
|
||||||
: color.withAlpha(125)),
|
|
||||||
type: MaterialType.circle,
|
|
||||||
child: Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
shape: BoxShape.circle,
|
|
||||||
border: Border.all(width: 2, color: dotcolor!),
|
|
||||||
),
|
|
||||||
width: _kDotSize * 2 * zoom,
|
|
||||||
height: _kDotSize * 2 * zoom,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: () => onPageSelected!.call(index),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Row(
|
Widget build(BuildContext context) => Row(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: flutter_introduction_widget
|
name: flutter_introduction_widget
|
||||||
description: Flutter Introduction Widget for showing a list of introduction pages on a single scrollable page or horizontal pageview
|
description: Flutter Introduction Widget for showing a list of introduction pages on a single scrollable page or horizontal pageview
|
||||||
version: 3.0.0
|
version: 3.1.0
|
||||||
homepage: https://github.com/Iconica-Development/flutter_introduction_widget
|
homepage: https://github.com/Iconica-Development/flutter_introduction_widget
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name: flutter_introduction_workspace
|
name: flutter_introduction_workspace
|
||||||
version: 3.0.0
|
version: 3.1.0
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: '>=3.1.0 <4.0.0'
|
sdk: '>=3.1.0 <4.0.0'
|
||||||
|
|
Loading…
Reference in a new issue