Skip to content

Commit 5f1b49a

Browse files
Merge pull request #183 from srinivasPaidisetti/GFIntroScreen
Gf intro screen
2 parents d78126a + d20e9d4 commit 5f1b49a

File tree

6 files changed

+356
-15
lines changed

6 files changed

+356
-15
lines changed

lib/components/animation/gf_animation.dart

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,15 @@ class GFAnimation extends StatefulWidget {
3131
this.fontWeight,
3232
this.changedWidth,
3333
this.changedHeight,
34+
this.reverseDuration,
3435
}) : super(key: key);
3536

3637
/// The duration for animations of the [Decoration].
3738
final Duration duration;
3839

40+
/// The duration for animations of the type[Size].
41+
final Duration reverseDuration;
42+
3943
/// Defines how the animated widget is aligned within the Animation.
4044
final Alignment alignment;
4145

@@ -203,27 +207,40 @@ class _GFAnimationState extends State<GFAnimation>
203207
child: AnimatedAlign(
204208
curve: widget.curve ?? Curves.linear,
205209
alignment: selected
206-
? widget.alignment ?? Alignment.center
207-
: Alignment.topCenter,
210+
? widget.activeAlignment ?? Alignment.center
211+
: widget.alignment ?? Alignment.topCenter,
208212
duration: widget.duration ?? const Duration(seconds: 2),
209213
child: widget.child,
210214
),
211215
),
212216
);
213217

214218
Widget buildAnimatedSizeWidget() => GestureDetector(
215-
onTap: widget.onTap,
216-
child: Container(
217-
margin: widget.margin ?? const EdgeInsets.all(0),
218-
padding: widget.padding ?? const EdgeInsets.all(0),
219-
color: widget.color ?? Colors.white,
220-
child: AnimatedSize(
221-
alignment: widget.alignment ?? Alignment.center,
222-
curve: widget.curve ?? Curves.linear,
223-
vsync: this,
224-
duration: widget.duration ?? const Duration(milliseconds: 2000),
225-
child: widget.child,
226-
),
219+
onTap: () {
220+
if (widget.onTap == null) {
221+
if (mounted) {
222+
setState(() {
223+
selected = !selected;
224+
});
225+
}
226+
} else {
227+
widget.onTap();
228+
}
229+
},
230+
child: AnimatedSize(
231+
alignment: widget.alignment ?? Alignment.center,
232+
curve: widget.curve ?? Curves.linear,
233+
vsync: this,
234+
reverseDuration:
235+
widget.reverseDuration ?? const Duration(milliseconds: 2000),
236+
duration: widget.duration ?? const Duration(milliseconds: 2000),
237+
child: Container(
238+
margin: widget.margin ?? const EdgeInsets.all(0),
239+
padding: widget.padding ?? const EdgeInsets.all(0),
240+
color: widget.color ?? Colors.white,
241+
height: selected ? widget.height ?? 200 : widget.height ?? 100,
242+
width: selected ? widget.width ?? 200 : widget.width ?? 100,
243+
child: widget.child),
227244
),
228245
);
229246

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
import 'package:flutter/cupertino.dart';
2+
import 'package:flutter/material.dart';
3+
4+
class GFIntroBottomNavigation extends StatelessWidget {
5+
const GFIntroBottomNavigation({
6+
Key key,
7+
this.rightText = 'NEXT',
8+
this.pageNumber = 0,
9+
this.onNext,
10+
this.showDivider = true,
11+
this.dividerColor = Colors.grey,
12+
this.dividerHeight = 1,
13+
this.dividerThickness = 0.0,
14+
this.child,
15+
this.padding = const EdgeInsets.all(8),
16+
this.margin = const EdgeInsets.all(8),
17+
this.pagesCount = 0,
18+
this.skipText = 'SKIP',
19+
this.onSkipTap,
20+
this.skipWidget,
21+
this.rightWidget,
22+
this.dotShape = BoxShape.circle,
23+
this.defaultColor,
24+
this.activeColor,
25+
this.dotHeight,
26+
this.dotWidth,
27+
this.dotMargin,
28+
this.skipStyle,
29+
this.rightStyle,
30+
this.onDoneTap,
31+
this.doneText = 'GO',
32+
}) : super(key: key);
33+
34+
final String rightText;
35+
final int pageNumber;
36+
final VoidCallback onNext;
37+
final bool showDivider;
38+
final double dividerHeight;
39+
final double dividerThickness;
40+
final Color dividerColor;
41+
final Widget child;
42+
final int pagesCount;
43+
final String skipText;
44+
final VoidCallback onSkipTap;
45+
final VoidCallback onDoneTap;
46+
final EdgeInsets padding;
47+
final EdgeInsets margin;
48+
final Widget skipWidget;
49+
final Widget rightWidget;
50+
final TextStyle skipStyle;
51+
final TextStyle rightStyle;
52+
final String doneText;
53+
54+
///dot
55+
final BoxShape dotShape;
56+
final Color defaultColor;
57+
final Color activeColor;
58+
final double dotHeight;
59+
final double dotWidth;
60+
final EdgeInsets dotMargin;
61+
62+
@override
63+
Widget build(BuildContext context) => Container(
64+
child: DefaultTextStyle(
65+
style: const TextStyle(
66+
color: Colors.black,
67+
fontSize: 16,
68+
),
69+
child: Column(
70+
mainAxisAlignment: MainAxisAlignment.end,
71+
children: <Widget>[
72+
showDivider
73+
? Divider(
74+
height: dividerHeight,
75+
thickness: dividerThickness,
76+
color: dividerColor,
77+
)
78+
: Container(),
79+
Container(
80+
padding: padding,
81+
margin: margin,
82+
child: Row(
83+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
84+
children: <Widget>[
85+
GestureDetector(
86+
behavior: HitTestBehavior.translucent,
87+
child: Padding(
88+
padding: const EdgeInsets.only(
89+
top: 8,
90+
bottom: 8,
91+
left: 24,
92+
right: 32,
93+
),
94+
child: skipWidget ??
95+
Text(
96+
skipText,
97+
style: skipStyle ??
98+
const TextStyle(
99+
color: Colors.black,
100+
fontSize: 16,
101+
),
102+
)),
103+
onTap: onSkipTap,
104+
),
105+
Expanded(
106+
child: Container(
107+
child: Stack(
108+
children: [
109+
Row(
110+
mainAxisAlignment: MainAxisAlignment.center,
111+
children: getDotsList(),
112+
)
113+
],
114+
),
115+
),
116+
),
117+
GestureDetector(
118+
behavior: HitTestBehavior.translucent,
119+
child: Padding(
120+
padding: const EdgeInsets.only(
121+
top: 8, bottom: 8, left: 32, right: 24),
122+
child: rightWidget ??
123+
Text(
124+
pageNumber == pagesCount - 1
125+
? doneText
126+
: rightText,
127+
style: rightStyle ??
128+
const TextStyle(
129+
color: Colors.black,
130+
fontSize: 16,
131+
)),
132+
),
133+
onTap: pageNumber == pagesCount - 1 ? onDoneTap : onNext,
134+
),
135+
],
136+
),
137+
)
138+
],
139+
),
140+
),
141+
);
142+
143+
List<Widget> getDotsList() {
144+
final List<Widget> list = [];
145+
for (int i = 0; i < pagesCount; i++) {
146+
list.add(Container(
147+
width: dotWidth ?? 12,
148+
height: dotHeight ?? 12,
149+
margin: dotMargin ?? const EdgeInsets.symmetric(horizontal: 4),
150+
decoration: BoxDecoration(
151+
shape: dotShape,
152+
color: pageNumber == i
153+
? activeColor ?? Colors.blue
154+
: defaultColor ?? Colors.grey.withOpacity(0.5),
155+
),
156+
));
157+
}
158+
return list;
159+
}
160+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:getwidget/components/intro_screen/gf__intro_bottom_navigation.dart';
3+
import 'package:getwidget/components/intro_screen/gf_intro_slide.dart';
4+
import 'package:getwidget/types/gf_intro_type.dart';
5+
6+
class GFIntroScreen extends StatefulWidget {
7+
const GFIntroScreen(
8+
{Key key,
9+
this.slides,
10+
this.pageController,
11+
this.gfIntroBottomNavigation,
12+
this.type,
13+
this.color = Colors.white})
14+
: super(key: key);
15+
16+
/// if the type as [GFIntroType.fullWidth],[GFIntroType.half],[GFIntroType.rounded] use [GFIntroSlide]'s or customWidgets
17+
final List<Widget> slides;
18+
19+
/// type of [GFIntroType] which takes the type ie, fullWidth, half,rounded and bubble for the [GFIntroScreen]
20+
final GFIntroType type;
21+
22+
/// default controller for the [GFIntroScreen] component
23+
final PageController pageController;
24+
25+
/// [GFIntroScreen] bottom navigation will be used as [GFIntroBottomNavigation] component
26+
final GFIntroBottomNavigation gfIntroBottomNavigation;
27+
28+
/// background color of the [GFIntroScreen] component
29+
final Color color;
30+
31+
@override
32+
_GFIntroScreenState createState() => _GFIntroScreenState();
33+
}
34+
35+
class _GFIntroScreenState extends State<GFIntroScreen> {
36+
PageController _pageController = PageController(initialPage: 0);
37+
int page = 0;
38+
List<Widget> pages;
39+
40+
@override
41+
void initState() {
42+
if (widget.pageController != null) {
43+
_pageController = widget.pageController;
44+
}
45+
_pageController.addListener(() {
46+
if (mounted) {
47+
setState(() {
48+
page = _pageController.page.round();
49+
});
50+
}
51+
});
52+
super.initState();
53+
}
54+
55+
@override
56+
Widget build(BuildContext context) => Center(
57+
child: Container(
58+
width: widget.type == GFIntroType.fullWidth
59+
? MediaQuery.of(context).size.width
60+
: MediaQuery.of(context).size.width * 0.885,
61+
height: widget.type != GFIntroType.fullWidth
62+
? MediaQuery.of(context).size.height / 2
63+
: MediaQuery.of(context).size.height,
64+
margin: widget.type != GFIntroType.fullWidth
65+
? const EdgeInsets.only(left: 20, right: 20)
66+
: const EdgeInsets.only(left: 0, right: 0),
67+
padding: widget.type == GFIntroType.fullWidth
68+
? const EdgeInsets.all(0)
69+
: const EdgeInsets.all(0),
70+
decoration: BoxDecoration(
71+
color: widget.color,
72+
borderRadius: widget.type == GFIntroType.fullWidth
73+
? BorderRadius.circular(0)
74+
: widget.type == GFIntroType.rounded
75+
? BorderRadius.circular(24)
76+
: BorderRadius.zero,
77+
),
78+
child: Column(
79+
mainAxisAlignment: MainAxisAlignment.center,
80+
crossAxisAlignment: CrossAxisAlignment.center,
81+
children: <Widget>[
82+
Expanded(
83+
child: ClipRRect(
84+
borderRadius: widget.type == GFIntroType.rounded
85+
? const BorderRadius.only(
86+
topLeft: Radius.circular(24),
87+
topRight: Radius.circular(24))
88+
: BorderRadius.zero,
89+
child: PageView(
90+
controller: _pageController,
91+
children: widget.slides,
92+
),
93+
)),
94+
widget.gfIntroBottomNavigation ??
95+
GFIntroBottomNavigation(
96+
onNext: () {
97+
_pageController.nextPage(
98+
duration: const Duration(milliseconds: 500),
99+
curve: Curves.linear);
100+
},
101+
pagesCount: widget.slides.length,
102+
pageNumber: page,
103+
)
104+
],
105+
),
106+
),
107+
);
108+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:getwidget/colors/gf_color.dart';
3+
import 'package:getwidget/components/image/gf_image_overlay.dart';
4+
5+
class GFIntroSlide extends StatelessWidget {
6+
const GFIntroSlide({
7+
Key key,
8+
@required this.image,
9+
this.imageHeight = 100,
10+
this.imageWidth = 100,
11+
this.title,
12+
this.subTitle,
13+
this.titleStyle = const TextStyle(fontSize: 20, color: GFColors.DARK),
14+
this.subTitleStyle = const TextStyle(fontSize: 16, color: GFColors.DARK),
15+
this.backgroundColor = GFColors.PRIMARY,
16+
}) : super(key: key);
17+
final double imageHeight;
18+
final double imageWidth;
19+
final ImageProvider image;
20+
final String title;
21+
final TextStyle titleStyle;
22+
final String subTitle;
23+
final TextStyle subTitleStyle;
24+
final Color backgroundColor;
25+
26+
@override
27+
Widget build(BuildContext context) => Container(
28+
color: backgroundColor,
29+
child: Column(
30+
mainAxisAlignment: MainAxisAlignment.center,
31+
crossAxisAlignment: CrossAxisAlignment.center,
32+
children: <Widget>[
33+
GFImageOverlay(
34+
height: imageHeight,
35+
colorFilter: const ColorFilter.mode(null, null),
36+
width: imageWidth,
37+
image: image),
38+
const SizedBox(
39+
height: 20,
40+
),
41+
Text(
42+
title ?? 'Title',
43+
style: titleStyle,
44+
),
45+
const SizedBox(
46+
height: 40,
47+
),
48+
Text(
49+
subTitle ?? 'Sub Title',
50+
style: subTitleStyle,
51+
)
52+
],
53+
),
54+
);
55+
}

lib/types/gf_intro_type.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
enum GFIntroType { fullWidth, half, rounded }

0 commit comments

Comments
 (0)