feat: improved example

This commit is contained in:
TimIconica 2022-09-20 16:14:09 +02:00
parent 11c8fcde73
commit 2741be487c
14 changed files with 167 additions and 148 deletions

View file

@ -19,6 +19,8 @@ class AgePage {
amountOfPages: amountOfPages, amountOfPages: amountOfPages,
shellFormWidgets: [ shellFormWidgets: [
ShellFormInputNumberPicker( ShellFormInputNumberPicker(
minValue: 12,
maxValue: 120,
controller: ShellFormInputNumberPickerController( controller: ShellFormInputNumberPickerController(
id: "age", id: "age",
checkPageTitle: (dynamic amount) { checkPageTitle: (dynamic amount) {

View file

@ -11,14 +11,14 @@ class CheckPageExample {
return CheckPage( return CheckPage(
title: Container( title: Container(
margin: const EdgeInsets.only( margin: const EdgeInsets.only(
top: 60, top: 70,
bottom: 10, bottom: 10,
), ),
padding: const EdgeInsets.symmetric(horizontal: 40), padding: const EdgeInsets.symmetric(horizontal: 40),
child: Text( child: const Text(
checkPageText, "Check answers",
style: TextStyle( style: TextStyle(
fontSize: fontSize, fontSize: 25,
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
), ),
), ),
@ -30,7 +30,7 @@ class CheckPageExample {
await onPressed(); await onPressed();
}, },
child: Container( child: Container(
width: size.width * 0.9, width: MediaQuery.of(context).size.width * 0.9,
padding: const EdgeInsets.only( padding: const EdgeInsets.only(
top: 18, top: 18,
bottom: 16, bottom: 16,
@ -80,7 +80,7 @@ class CheckPageExample {
if (description != null) if (description != null)
Text( Text(
description, description,
style: TextStyle(fontSize: fontSize / 1.3), style: const TextStyle(fontSize: 16),
) )
], ],
), ),

View file

@ -18,6 +18,19 @@ class NamePage {
amountOfPages: amountOfPages, amountOfPages: amountOfPages,
title: "Please enter your name", title: "Please enter your name",
shellFormWidgets: [ shellFormWidgets: [
// Padding(
// padding: const EdgeInsets.fromLTRB(40, 0, 40, 40),
// child: ShellFormInputPlainText(
// label: const Text("Name"),
// controller: ShellFormInputPlainTextController(
// mandatory: true,
// id: "name",
// checkPageTitle: (dynamic name) {
// return "Name: $name";
// },
// ),
// ),
// ),
Padding( Padding(
padding: const EdgeInsets.fromLTRB(40, 0, 40, 40), padding: const EdgeInsets.fromLTRB(40, 0, 40, 40),
child: ShellFormInputPlainText( child: ShellFormInputPlainText(
@ -31,19 +44,19 @@ class NamePage {
), ),
), ),
), ),
Padding( // Padding(
padding: const EdgeInsets.fromLTRB(40, 0, 40, 0), // padding: const EdgeInsets.fromLTRB(40, 0, 40, 0),
child: ShellFormInputPlainText( // child: ShellFormInputPlainText(
label: const Text("Last Name"), // label: const Text("Last Name"),
controller: ShellFormInputPlainTextController( // controller: ShellFormInputPlainTextController(
mandatory: true, // mandatory: true,
id: "lastName", // id: "lastName",
checkPageTitle: (dynamic lastName) { // checkPageTitle: (dynamic lastName) {
return "Last Name: $lastName"; // return "Last Name: $lastName";
}, // },
), // ),
), // ),
), // ),
], ],
), ),
); );

View file

@ -24,85 +24,88 @@ class _FormExampleState extends ConsumerState<FormExample> {
var size = MediaQuery.of(context).size; var size = MediaQuery.of(context).size;
var fontSize = size.height / 40; var fontSize = size.height / 40;
return Scaffold( return GestureDetector(
body: Center( onTap: () => FocusScope.of(context).unfocus(),
child: ShellForm( child: Scaffold(
formController: formController, body: Center(
options: ShellFormOptions( child: ShellForm(
onFinished: (Map<int, Map<String, dynamic>> results) { formController: formController,
print("Totale resultaten: $results"); options: ShellFormOptions(
Navigator.of(context).pushNamed('/thanks'); onFinished: (Map<int, Map<String, dynamic>> results) {
}, print("Final full results: $results");
onNext: (int pageNumber, Map<String, dynamic> results) { Navigator.of(context).pushNamed('/thanks');
print("Resultaten pagina $pageNumber: $results"); },
}, onNext: (int pageNumber, Map<String, dynamic> results) {
nextButton: (int pageNumber, bool checkingPages) { print("Results page $pageNumber: $results");
return Align( },
alignment: Alignment.bottomCenter, nextButton: (int pageNumber, bool checkingPages) {
child: Padding( return Align(
padding: EdgeInsets.only( alignment: Alignment.bottomCenter,
bottom: size.height / 20, child: Padding(
), padding: EdgeInsets.only(
child: SizedBox( bottom: size.height * 0.05,
height: size.height / 15, ),
width: size.width / 1.5, child: SizedBox(
child: ElevatedButton( height: size.height * 0.07,
style: ElevatedButton.styleFrom( width: size.width * 0.7,
shape: RoundedRectangleBorder( child: ElevatedButton(
borderRadius: BorderRadius.circular(5), style: ElevatedButton.styleFrom(
), shape: RoundedRectangleBorder(
backgroundColor: Colors.black, borderRadius: BorderRadius.circular(5),
textStyle: TextStyle( ),
fontSize: fontSize, backgroundColor: Colors.black,
fontWeight: FontWeight.w600, textStyle: TextStyle(
color: Colors.white, fontSize: fontSize,
fontWeight: FontWeight.w600,
color: Colors.white,
),
), ),
onPressed: () {
formController.autoNextStep();
},
child: Text(checkingPages ? "Save" : "Next Page"),
), ),
onPressed: () {
formController.autoNextStep();
},
child: Text(checkingPages ? "Save" : "Next Page"),
), ),
), ),
), );
); },
}, backButton: (int pageNumber, bool checkingPages, int pageAmount) {
backButton: (int pageNumber, bool checkingPages, int pageAmount) { if (pageNumber != 0) {
if (pageNumber != 0) { if (!checkingPages || pageNumber >= pageAmount) {
if (!checkingPages || pageNumber >= pageAmount) { return Align(
return Align( alignment: Alignment.topLeft,
alignment: Alignment.topLeft, child: Container(
child: Container( margin: EdgeInsets.only(
margin: EdgeInsets.only( top: size.height * 0.045,
top: size.height / 20, left: size.width * 0.07,
left: size.width / 15, ),
), width: size.width * 0.08,
width: 30, height: size.width * 0.08,
height: 30, decoration: BoxDecoration(
decoration: BoxDecoration( borderRadius: BorderRadius.circular(90),
borderRadius: BorderRadius.circular(90), color: const Color(0xFFD8D8D8).withOpacity(0.50),
color: const Color(0xFFD8D8D8).withOpacity(0.50), ),
), child: IconButton(
child: IconButton( padding: EdgeInsets.zero,
padding: EdgeInsets.zero, splashRadius: size.width * 0.06,
splashRadius: 29, onPressed: () {
onPressed: () { formController.previousStep();
formController.previousStep(); },
}, icon: const Icon(Icons.chevron_left),
icon: const Icon(Icons.chevron_left), )),
)), );
); }
} }
} return Container();
return Container(); },
}, pages: [
pages: [ AgePage().returnPage(size, fontSize, 1, 3),
AgePage().returnPage(size, fontSize, 1, 3), // NamePage().returnPage(size, fontSize, 2, 3),
NamePage().returnPage(size, fontSize, 2, 3), CarouselPage().returnPage(size, fontSize, 3, 3),
CarouselPage().returnPage(size, fontSize, 3, 3), ],
], checkPage: CheckPageExample()
checkPage: CheckPageExample() .showCheckpage(context, size, fontSize, checkPageText),
.showCheckpage(context, size, fontSize, checkPageText), ),
), ),
), ),
), ),

View file

@ -20,50 +20,47 @@ class TemplatePage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return GestureDetector( return Column(
onTap: () => FocusScope.of(context).unfocus(), mainAxisAlignment: MainAxisAlignment.center,
child: Column( children: [
mainAxisAlignment: MainAxisAlignment.center, Align(
children: [ alignment: Alignment.centerLeft,
Align( child: Padding(
alignment: Alignment.centerLeft, padding: EdgeInsets.symmetric(horizontal: size.width / 10),
child: Padding( child: Column(
padding: EdgeInsets.symmetric(horizontal: size.width / 10), crossAxisAlignment: CrossAxisAlignment.start,
child: Column( children: [
crossAxisAlignment: CrossAxisAlignment.start, SizedBox(
children: [ height: size.height / 10,
SizedBox( ),
height: size.height / 10, Text(
"$pageNumber / $amountOfPages",
style: TextStyle(
fontSize: fontSize,
), ),
Text( ),
"$pageNumber / $amountOfPages", SizedBox(
style: TextStyle( height: size.height / 80,
fontSize: fontSize, ),
), Text(
title,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.w900,
), ),
SizedBox( ),
height: size.height / 80, ],
),
Text(
title,
style: TextStyle(
fontSize: fontSize,
fontWeight: FontWeight.w900,
),
),
],
),
), ),
), ),
const Spacer(), ),
for (var widget in shellFormWidgets) ...[ const Spacer(),
widget, for (var widget in shellFormWidgets) ...[
], widget,
const Spacer(
flex: 2,
),
], ],
), const Spacer(
flex: 2,
),
],
); );
} }
} }

View file

@ -43,8 +43,8 @@ class ShellFormPage {
}); });
} }
/// CheckPage is used to set a check page at the end of a [ShellForm]. /// [CheckPage] is used to set a check page at the end of a [ShellForm].
/// A CheckPage is a page where the user can check all input values before commiting. /// A [CheckPage] is a page where the user can check all input values before commiting.
/// ///
/// [title] is the widget shown at the top of the page. /// [title] is the widget shown at the top of the page.
/// ///

View file

@ -25,7 +25,7 @@ import 'src/utils/formstate.dart' as fs;
/// // print(results); /// // print(results);
/// }, /// },
/// onNext: (int pageNumber, Map<String, dynamic> results) { /// onNext: (int pageNumber, Map<String, dynamic> results) {
/// // print("Resultaten pagina $pageNumber: $results"); /// // print("Results page $pageNumber: $results");
/// }, /// },
/// nextButton: (int pageNumber, bool checkingPages) { /// nextButton: (int pageNumber, bool checkingPages) {
/// return Align( /// return Align(
@ -38,7 +38,7 @@ import 'src/utils/formstate.dart' as fs;
/// onPressed: () { /// onPressed: () {
/// shellFormController.autoNextStep(); /// shellFormController.autoNextStep();
/// }, /// },
/// child: Text(checkingPages ? "Opslaan" : "Volgende stap"), /// child: Text(checkingPages ? "Save" : "Next Page"),
/// ), /// ),
/// ), /// ),
/// ); /// );
@ -100,7 +100,7 @@ import 'src/utils/formstate.dart' as fs;
/// ], /// ],
/// checkPage: CheckPage( /// checkPage: CheckPage(
/// title: const Text( /// title: const Text(
/// "Hier zijn je wensen voor het afscheidsfeestje", /// "All entered info: ",
/// style: TextStyle( /// style: TextStyle(
/// fontSize: 25, /// fontSize: 25,
/// fontWeight: FontWeight.w900, /// fontWeight: FontWeight.w900,

View file

@ -73,7 +73,7 @@ class CarouselSliderState extends State<CarouselSlider>
PageController? pageController; PageController? pageController;
/// [mode] is related to why the page is being changed /// [mode] is related to why the page is being changed.
CarouselPageChangedReason mode = CarouselPageChangedReason.controller; CarouselPageChangedReason mode = CarouselPageChangedReason.controller;
CarouselSliderState(); CarouselSliderState();
@ -87,14 +87,14 @@ class CarouselSliderState extends State<CarouselSlider>
carouselState!.options = options; carouselState!.options = options;
carouselState!.itemCount = widget.itemCount; carouselState!.itemCount = widget.itemCount;
// pageController needs to be re-initialized to respond to state changes /// [pageController] needs to be re-initialized to respond to state changes.
pageController = PageController( pageController = PageController(
viewportFraction: options.viewportFraction, viewportFraction: options.viewportFraction,
initialPage: carouselState!.realPage, initialPage: carouselState!.realPage,
); );
carouselState!.pageController = pageController; carouselState!.pageController = pageController;
// handle autoplay when state changes /// handle autoplay when state changes
handleAutoPlay(); handleAutoPlay();
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
@ -296,13 +296,13 @@ class CarouselSliderState extends State<CarouselSlider>
: widget.itemBuilder!(context, index, idx), : widget.itemBuilder!(context, index, idx),
builder: (BuildContext context, child) { builder: (BuildContext context, child) {
double distortionValue = 1.0; double distortionValue = 1.0;
// if `enlargeCenterPage` is true, we must calculate the carousel item's height // if [enlargeCenterPage] is true, we must calculate the carousel item's height
// to display the visual effect // to display the visual effect
if (widget.options.enlargeCenterPage != null && if (widget.options.enlargeCenterPage != null &&
widget.options.enlargeCenterPage == true) { widget.options.enlargeCenterPage == true) {
// pageController.page can only be accessed after the first build, // [pageController.page] can only be accessed after the first build,
// so in the first build we calculate the itemoffset manually // so in the first build we calculate the [itemOffset] manually
double itemOffset = 0; double itemOffset = 0;
var position = carouselState?.pageController?.position; var position = carouselState?.pageController?.position;
if (position != null && if (position != null &&

View file

@ -6,7 +6,7 @@
/// ///
/// For example; We have a Carousel of 10000(simulating infinity) but only 6 images. /// For example; We have a Carousel of 10000(simulating infinity) but only 6 images.
/// We need to repeat the images to give the illusion of a never ending stream. /// We need to repeat the images to give the illusion of a never ending stream.
/// By calling _getRealIndex with position and base we get an offset. /// By calling [getRealIndex] with position and base we get an offset.
/// This offset modulo our length, 6, will return a number between 0 and 5, which represent the image /// This offset modulo our length, 6, will return a number between 0 and 5, which represent the image
/// to be placed in the given position. /// to be placed in the given position.
int getRealIndex(int position, int base, int? length) { int getRealIndex(int position, int base, int? length) {

View file

@ -8,7 +8,7 @@ import 'carousel_form.dart';
/// Input for a carousel of items used in a [ShellForm]. /// Input for a carousel of items used in a [ShellForm].
/// ///
/// items will be the [Widget]s to be displayed in the carousel. /// [items] will be the [Widget]s to be displayed in the carousel.
/// ///
/// Standard controller is [ShellFormInputCarouselController]. /// Standard controller is [ShellFormInputCarouselController].
class ShellFormInputCarousel extends ShellFormInputWidget { class ShellFormInputCarousel extends ShellFormInputWidget {
@ -37,7 +37,7 @@ class ShellFormInputCarousel extends ShellFormInputWidget {
} }
} }
/// Controller for the carousel used by a [ShellFormInputWidget] used in a [ShellFrom]. /// Controller for the carousel used by a [ShellFormInputWidget] used in a [ShellForm].
/// ///
/// Mainly used by [ShellFormInputCarousel]. /// Mainly used by [ShellFormInputCarousel].
class ShellFormInputCarouselController class ShellFormInputCarouselController

View file

@ -39,7 +39,7 @@ class ShellFormInputEmail extends ShellFormInputWidget {
} }
} }
/// Controller for emails used by a [ShellFormInputWidget] used in a [ShellFrom]. /// Controller for emails used by a [ShellFormInputWidget] used in a [ShellForm].
/// ///
/// Mainly used by [ShellFormInputEmail]. /// Mainly used by [ShellFormInputEmail].
class ShellFormInputEmailController class ShellFormInputEmailController

View file

@ -26,9 +26,11 @@ class ShellFormInputNumberPicker extends ShellFormInputWidget {
super.registerController(context); super.registerController(context);
return NumberPickerFormField( return NumberPickerFormField(
minValue: minValue,
maxValue: maxValue,
onSaved: (value) => controller.onSaved(value), onSaved: (value) => controller.onSaved(value),
validator: (value) => controller.onValidate(value, _), validator: (value) => controller.onValidate(value, _),
initialValue: controller.value ?? 0, initialValue: controller.value ?? minValue,
); );
} }
} }

View file

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// Creates a slider with the given input parameters
class SliderFormField extends FormField<double> { class SliderFormField extends FormField<double> {
SliderFormField({ SliderFormField({
Key? key, Key? key,

View file

@ -0,0 +1 @@