Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 31 additions & 14 deletions lib/components/animation/gf_animation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,15 @@ class GFAnimation extends StatefulWidget {
this.fontWeight,
this.changedWidth,
this.changedHeight,
this.reverseDuration,
}) : super(key: key);

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

/// The duration for animations of the type[Size].
final Duration reverseDuration;

/// Defines how the animated widget is aligned within the Animation.
final Alignment alignment;

Expand Down Expand Up @@ -203,27 +207,40 @@ class _GFAnimationState extends State<GFAnimation>
child: AnimatedAlign(
curve: widget.curve ?? Curves.linear,
alignment: selected
? widget.alignment ?? Alignment.center
: Alignment.topCenter,
? widget.activeAlignment ?? Alignment.center
: widget.alignment ?? Alignment.topCenter,
duration: widget.duration ?? const Duration(seconds: 2),
child: widget.child,
),
),
);

Widget buildAnimatedSizeWidget() => GestureDetector(
onTap: widget.onTap,
child: Container(
margin: widget.margin ?? const EdgeInsets.all(0),
padding: widget.padding ?? const EdgeInsets.all(0),
color: widget.color ?? Colors.white,
child: AnimatedSize(
alignment: widget.alignment ?? Alignment.center,
curve: widget.curve ?? Curves.linear,
vsync: this,
duration: widget.duration ?? const Duration(milliseconds: 2000),
child: widget.child,
),
onTap: () {
if (widget.onTap == null) {
if (mounted) {
setState(() {
selected = !selected;
});
}
} else {
widget.onTap();
}
},
child: AnimatedSize(
alignment: widget.alignment ?? Alignment.center,
curve: widget.curve ?? Curves.linear,
vsync: this,
reverseDuration:
widget.reverseDuration ?? const Duration(milliseconds: 2000),
duration: widget.duration ?? const Duration(milliseconds: 2000),
child: Container(
margin: widget.margin ?? const EdgeInsets.all(0),
padding: widget.padding ?? const EdgeInsets.all(0),
color: widget.color ?? Colors.white,
height: selected ? widget.height ?? 200 : widget.height ?? 100,
width: selected ? widget.width ?? 200 : widget.width ?? 100,
child: widget.child),
),
);

Expand Down
160 changes: 160 additions & 0 deletions lib/components/intro_screen/gf__intro_bottom_navigation.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

class GFIntroBottomNavigation extends StatelessWidget {
const GFIntroBottomNavigation({
Key key,
this.rightText = 'NEXT',
this.pageNumber = 0,
this.onNext,
this.showDivider = true,
this.dividerColor = Colors.grey,
this.dividerHeight = 1,
this.dividerThickness = 0.0,
this.child,
this.padding = const EdgeInsets.all(8),
this.margin = const EdgeInsets.all(8),
this.pagesCount = 0,
this.skipText = 'SKIP',
this.onSkipTap,
this.skipWidget,
this.rightWidget,
this.dotShape = BoxShape.circle,
this.defaultColor,
this.activeColor,
this.dotHeight,
this.dotWidth,
this.dotMargin,
this.skipStyle,
this.rightStyle,
this.onDoneTap,
this.doneText = 'GO',
}) : super(key: key);

final String rightText;
final int pageNumber;
final VoidCallback onNext;
final bool showDivider;
final double dividerHeight;
final double dividerThickness;
final Color dividerColor;
final Widget child;
final int pagesCount;
final String skipText;
final VoidCallback onSkipTap;
final VoidCallback onDoneTap;
final EdgeInsets padding;
final EdgeInsets margin;
final Widget skipWidget;
final Widget rightWidget;
final TextStyle skipStyle;
final TextStyle rightStyle;
final String doneText;

///dot
final BoxShape dotShape;
final Color defaultColor;
final Color activeColor;
final double dotHeight;
final double dotWidth;
final EdgeInsets dotMargin;

@override
Widget build(BuildContext context) => Container(
child: DefaultTextStyle(
style: const TextStyle(
color: Colors.black,
fontSize: 16,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
showDivider
? Divider(
height: dividerHeight,
thickness: dividerThickness,
color: dividerColor,
)
: Container(),
Container(
padding: padding,
margin: margin,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
GestureDetector(
behavior: HitTestBehavior.translucent,
child: Padding(
padding: const EdgeInsets.only(
top: 8,
bottom: 8,
left: 24,
right: 32,
),
child: skipWidget ??
Text(
skipText,
style: skipStyle ??
const TextStyle(
color: Colors.black,
fontSize: 16,
),
)),
onTap: onSkipTap,
),
Expanded(
child: Container(
child: Stack(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: getDotsList(),
)
],
),
),
),
GestureDetector(
behavior: HitTestBehavior.translucent,
child: Padding(
padding: const EdgeInsets.only(
top: 8, bottom: 8, left: 32, right: 24),
child: rightWidget ??
Text(
pageNumber == pagesCount - 1
? doneText
: rightText,
style: rightStyle ??
const TextStyle(
color: Colors.black,
fontSize: 16,
)),
),
onTap: pageNumber == pagesCount - 1 ? onDoneTap : onNext,
),
],
),
)
],
),
),
);

List<Widget> getDotsList() {
final List<Widget> list = [];
for (int i = 0; i < pagesCount; i++) {
list.add(Container(
width: dotWidth ?? 12,
height: dotHeight ?? 12,
margin: dotMargin ?? const EdgeInsets.symmetric(horizontal: 4),
decoration: BoxDecoration(
shape: dotShape,
color: pageNumber == i
? activeColor ?? Colors.blue
: defaultColor ?? Colors.grey.withOpacity(0.5),
),
));
}
return list;
}
}
108 changes: 108 additions & 0 deletions lib/components/intro_screen/gf_intro_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import 'package:flutter/material.dart';
import 'package:getwidget/components/intro_screen/gf__intro_bottom_navigation.dart';
import 'package:getwidget/components/intro_screen/gf_intro_slide.dart';
import 'package:getwidget/types/gf_intro_type.dart';

class GFIntroScreen extends StatefulWidget {
const GFIntroScreen(
{Key key,
this.slides,
this.pageController,
this.gfIntroBottomNavigation,
this.type,
this.color = Colors.white})
: super(key: key);

/// if the type as [GFIntroType.fullWidth],[GFIntroType.half],[GFIntroType.rounded] use [GFIntroSlide]'s or customWidgets
final List<Widget> slides;

/// type of [GFIntroType] which takes the type ie, fullWidth, half,rounded and bubble for the [GFIntroScreen]
final GFIntroType type;

/// default controller for the [GFIntroScreen] component
final PageController pageController;

/// [GFIntroScreen] bottom navigation will be used as [GFIntroBottomNavigation] component
final GFIntroBottomNavigation gfIntroBottomNavigation;

/// background color of the [GFIntroScreen] component
final Color color;

@override
_GFIntroScreenState createState() => _GFIntroScreenState();
}

class _GFIntroScreenState extends State<GFIntroScreen> {
PageController _pageController = PageController(initialPage: 0);
int page = 0;
List<Widget> pages;

@override
void initState() {
if (widget.pageController != null) {
_pageController = widget.pageController;
}
_pageController.addListener(() {
if (mounted) {
setState(() {
page = _pageController.page.round();
});
}
});
super.initState();
}

@override
Widget build(BuildContext context) => Center(
child: Container(
width: widget.type == GFIntroType.fullWidth
? MediaQuery.of(context).size.width
: MediaQuery.of(context).size.width * 0.885,
height: widget.type != GFIntroType.fullWidth
? MediaQuery.of(context).size.height / 2
: MediaQuery.of(context).size.height,
margin: widget.type != GFIntroType.fullWidth
? const EdgeInsets.only(left: 20, right: 20)
: const EdgeInsets.only(left: 0, right: 0),
padding: widget.type == GFIntroType.fullWidth
? const EdgeInsets.all(0)
: const EdgeInsets.all(0),
decoration: BoxDecoration(
color: widget.color,
borderRadius: widget.type == GFIntroType.fullWidth
? BorderRadius.circular(0)
: widget.type == GFIntroType.rounded
? BorderRadius.circular(24)
: BorderRadius.zero,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Expanded(
child: ClipRRect(
borderRadius: widget.type == GFIntroType.rounded
? const BorderRadius.only(
topLeft: Radius.circular(24),
topRight: Radius.circular(24))
: BorderRadius.zero,
child: PageView(
controller: _pageController,
children: widget.slides,
),
)),
widget.gfIntroBottomNavigation ??
GFIntroBottomNavigation(
onNext: () {
_pageController.nextPage(
duration: const Duration(milliseconds: 500),
curve: Curves.linear);
},
pagesCount: widget.slides.length,
pageNumber: page,
)
],
),
),
);
}
55 changes: 55 additions & 0 deletions lib/components/intro_screen/gf_intro_slide.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import 'package:flutter/material.dart';
import 'package:getwidget/colors/gf_color.dart';
import 'package:getwidget/components/image/gf_image_overlay.dart';

class GFIntroSlide extends StatelessWidget {
const GFIntroSlide({
Key key,
@required this.image,
this.imageHeight = 100,
this.imageWidth = 100,
this.title,
this.subTitle,
this.titleStyle = const TextStyle(fontSize: 20, color: GFColors.DARK),
this.subTitleStyle = const TextStyle(fontSize: 16, color: GFColors.DARK),
this.backgroundColor = GFColors.PRIMARY,
}) : super(key: key);
final double imageHeight;
final double imageWidth;
final ImageProvider image;
final String title;
final TextStyle titleStyle;
final String subTitle;
final TextStyle subTitleStyle;
final Color backgroundColor;

@override
Widget build(BuildContext context) => Container(
color: backgroundColor,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
GFImageOverlay(
height: imageHeight,
colorFilter: const ColorFilter.mode(null, null),
width: imageWidth,
image: image),
const SizedBox(
height: 20,
),
Text(
title ?? 'Title',
style: titleStyle,
),
const SizedBox(
height: 40,
),
Text(
subTitle ?? 'Sub Title',
style: subTitleStyle,
)
],
),
);
}
1 change: 1 addition & 0 deletions lib/types/gf_intro_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
enum GFIntroType { fullWidth, half, rounded }
Loading