mirror of
https://github.com/Iconica-Development/flutter_form_wizard.git
synced 2025-05-20 03:13:47 +02:00
Merge pull request #3 from Iconica-Development/feature/scroll_direction
Feature/scroll direction
This commit is contained in:
commit
9c76d2766a
5 changed files with 92 additions and 38 deletions
|
@ -1,3 +1,9 @@
|
||||||
## 0.0.1 - September 29th 2022
|
## 0.0.1 - September 29th 2022
|
||||||
|
|
||||||
- Initial release
|
- Initial release
|
||||||
|
|
||||||
|
## 0.0.2 - October 12th 2022
|
||||||
|
|
||||||
|
- Added a multi line plain text input widget
|
||||||
|
- Ability to set the scrolldirection of the pageview
|
||||||
|
- Ability to set the scrollphysics of the pages' scrollview.
|
||||||
|
|
16
README.md
16
README.md
|
@ -24,13 +24,15 @@ Flutter Form has two paramaters: options and formController. Each of these param
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
|
|
||||||
| Parameter | Explaination |
|
| Parameter | Explaination |
|
||||||
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| checkPage | If this is set the form will feature a checkpage at the end so the end user can verify and alter his answers. |
|
| checkPage | If this is set the form will feature a checkpage at the end so the end user can verify and alter his answers. |
|
||||||
| nextButton | The button which is put in the stack of the Form. An onTap has to be implemented and should call to the FormController. Standard call is autoNextStep(). |
|
| nextButton | The button which is put in the stack of the Form. An onTap has to be implemented and should call to the FormController. Standard call is autoNextStep(). |
|
||||||
| backButton | Same as the nextButton. A widget that is put in the stack of the Form. An onTap has to be implemented and should call to the FormController. Standard call is previousStep(). |
|
| backButton | Same as the nextButton. A widget that is put in the stack of the Form. An onTap has to be implemented and should call to the FormController. Standard call is previousStep(). |
|
||||||
| onFinised | The callback that will be called when the last page is finished. If checkPage is enabled this will call after the checkPage is passed. |
|
| onFinised | The callback that will be called when the last page is finished. If checkPage is enabled this will call after the checkPage is passed. |
|
||||||
| onNext | The callback that is called when the user finishes a page. PageNumber is also provided. |
|
| onNext | The callback that is called when the user finishes a page. PageNumber is also provided. |
|
||||||
|
| scrollDirection | The abilty to set the scroll direction of the forms .pageview |
|
||||||
|
| scrollPhysics | The ability to set the scroll physics of scroll views in each form page. |
|
||||||
|
|
||||||
FormController:
|
FormController:
|
||||||
|
|
||||||
|
|
|
@ -229,6 +229,7 @@ class _FlutterFormState extends ConsumerState<FlutterForm> {
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
PageView(
|
PageView(
|
||||||
|
scrollDirection: _formController._options.scrollDirection,
|
||||||
controller: _formController.getPageController(),
|
controller: _formController.getPageController(),
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
children: [
|
children: [
|
||||||
|
@ -238,6 +239,8 @@ class _FlutterFormState extends ConsumerState<FlutterForm> {
|
||||||
child: fs.FormState(
|
child: fs.FormState(
|
||||||
formController: _formController.getFormPageControllers()[i],
|
formController: _formController.getFormPageControllers()[i],
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
|
physics: _formController._options.scrollPhysics ??
|
||||||
|
const ClampingScrollPhysics(),
|
||||||
slivers: [
|
slivers: [
|
||||||
SliverFillRemaining(
|
SliverFillRemaining(
|
||||||
hasScrollBody: false,
|
hasScrollBody: false,
|
||||||
|
@ -255,6 +258,8 @@ class _FlutterFormState extends ConsumerState<FlutterForm> {
|
||||||
widget.options.checkPage!.title!,
|
widget.options.checkPage!.title!,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: CustomScrollView(
|
child: CustomScrollView(
|
||||||
|
physics: _formController._options.scrollPhysics ??
|
||||||
|
const ClampingScrollPhysics(),
|
||||||
slivers: [
|
slivers: [
|
||||||
SliverFillRemaining(
|
SliverFillRemaining(
|
||||||
hasScrollBody: false,
|
hasScrollBody: false,
|
||||||
|
@ -504,6 +509,9 @@ class FlutterFormController extends ChangeNotifier {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> nextStep() async {
|
Future<void> nextStep() async {
|
||||||
|
_options.onNext(
|
||||||
|
_currentStep, _formPageControllers[_currentStep].getAllValues());
|
||||||
|
|
||||||
_currentStep += 1;
|
_currentStep += 1;
|
||||||
|
|
||||||
if (_currentStep >= _options.pages.length && _options.checkPage != null) {
|
if (_currentStep >= _options.pages.length && _options.checkPage != null) {
|
||||||
|
|
|
@ -12,8 +12,19 @@ class FlutterFormInputPlainText extends FlutterFormInputWidget {
|
||||||
Key? key,
|
Key? key,
|
||||||
required FlutterFormInputController controller,
|
required FlutterFormInputController controller,
|
||||||
Widget? label,
|
Widget? label,
|
||||||
|
this.decoration,
|
||||||
|
this.textAlignVertical,
|
||||||
|
this.expands = false,
|
||||||
|
this.maxLines,
|
||||||
|
this.maxLength,
|
||||||
}) : super(key: key, controller: controller, label: label);
|
}) : super(key: key, controller: controller, label: label);
|
||||||
|
|
||||||
|
final InputDecoration? decoration;
|
||||||
|
final TextAlignVertical? textAlignVertical;
|
||||||
|
final bool expands;
|
||||||
|
final int? maxLines;
|
||||||
|
final int? maxLength;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
String Function(String, {List<String>? params}) _ =
|
String Function(String, {List<String>? params}) _ =
|
||||||
|
@ -21,54 +32,73 @@ class FlutterFormInputPlainText extends FlutterFormInputWidget {
|
||||||
|
|
||||||
super.registerController(context);
|
super.registerController(context);
|
||||||
|
|
||||||
|
InputDecoration inputDecoration = decoration ??
|
||||||
|
InputDecoration(
|
||||||
|
label: label ?? const Text("Plain text"),
|
||||||
|
);
|
||||||
|
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
initialValue: controller.value,
|
initialValue: controller.value,
|
||||||
onSaved: (value) => controller.onSaved(value),
|
onSaved: (value) => controller.onSaved(value),
|
||||||
validator: (value) => controller.onValidate(value, _),
|
validator: (value) => controller.onValidate(value, _),
|
||||||
decoration: InputDecoration(
|
decoration: inputDecoration,
|
||||||
label: label ?? const Text("Plain text"),
|
textAlignVertical: textAlignVertical,
|
||||||
),
|
expands: expands,
|
||||||
|
maxLines: maxLines,
|
||||||
|
maxLength: maxLength,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Input for an plain text with extra styling used in a [FlutterForm].
|
/// Input for a multi line plain text field [FlutterForm].
|
||||||
///
|
///
|
||||||
/// Standard controller is [FlutterFormInputPlainTextController].
|
/// Standard controller is [FlutterFormInputPlainTextController].
|
||||||
class FlutterFormInputPlainTextWhiteWithBorder extends FlutterFormInputWidget {
|
///
|
||||||
const FlutterFormInputPlainTextWhiteWithBorder({
|
/// Hint can be set to set a hint inside the field.
|
||||||
|
///
|
||||||
|
/// MaxCharacters can be set to set a maximum amount of characters.
|
||||||
|
class FlutterFormInputMultiLine extends StatelessWidget {
|
||||||
|
const FlutterFormInputMultiLine({
|
||||||
Key? key,
|
Key? key,
|
||||||
required FlutterFormInputController controller,
|
required this.controller,
|
||||||
Widget? label,
|
this.label,
|
||||||
this.hint,
|
this.hint,
|
||||||
}) : super(key: key, controller: controller, label: label);
|
this.maxCharacters,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
|
final FlutterFormInputController controller;
|
||||||
|
final Widget? label;
|
||||||
|
|
||||||
final String? hint;
|
final String? hint;
|
||||||
|
final int? maxCharacters;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context) {
|
||||||
String Function(String, {List<String>? params}) _ =
|
return Column(
|
||||||
getTranslator(context, ref);
|
children: [
|
||||||
|
Expanded(
|
||||||
super.registerController(context);
|
child: FlutterFormInputPlainText(
|
||||||
|
label: label,
|
||||||
return TextFormField(
|
controller: controller,
|
||||||
initialValue: controller.value,
|
textAlignVertical: TextAlignVertical.top,
|
||||||
onSaved: (value) => controller.onSaved(value),
|
expands: true,
|
||||||
validator: (value) => controller.onValidate(value, _),
|
maxLines: null,
|
||||||
decoration: InputDecoration(
|
maxLength: maxCharacters,
|
||||||
hintText: hint,
|
decoration: InputDecoration(
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
hintText: hint,
|
||||||
isDense: true,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
border: const OutlineInputBorder(
|
isDense: true,
|
||||||
borderSide: BorderSide(color: Color(0xFF979797)),
|
border: const OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Color(0xFF979797)),
|
||||||
|
),
|
||||||
|
focusedBorder: const OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(color: Color(0xFF979797)),
|
||||||
|
),
|
||||||
|
filled: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
focusedBorder: const OutlineInputBorder(
|
],
|
||||||
borderSide: BorderSide(color: Color(0xFF979797)),
|
|
||||||
),
|
|
||||||
fillColor: Colors.white,
|
|
||||||
filled: true,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,10 @@ import 'package:flutter/material.dart';
|
||||||
/// [onFinished] and [onNext] are both callbacks which give the users results.
|
/// [onFinished] and [onNext] are both callbacks which give the users results.
|
||||||
/// [onNext] is called when the user goes to the next page.
|
/// [onNext] is called when the user goes to the next page.
|
||||||
/// [onFinished] is called when the form is finished. When checkpage is set [onFinished] is called when the checkpage is finished.
|
/// [onFinished] is called when the form is finished. When checkpage is set [onFinished] is called when the checkpage is finished.
|
||||||
|
///
|
||||||
|
/// [scrollDirection] can be set to change the Axis on which the pageview slides. Defaults to horizontal.
|
||||||
|
///
|
||||||
|
/// [scrollPhysics] can be set to set the scroll phyisics of the scroll views in each page. Default to [ClampingScrollPhysics].
|
||||||
class FlutterFormOptions {
|
class FlutterFormOptions {
|
||||||
final List<FlutterFormPage> pages;
|
final List<FlutterFormPage> pages;
|
||||||
|
|
||||||
|
@ -23,6 +27,8 @@ class FlutterFormOptions {
|
||||||
backButton;
|
backButton;
|
||||||
final void Function(Map<int, Map<String, dynamic>>) onFinished;
|
final void Function(Map<int, Map<String, dynamic>>) onFinished;
|
||||||
final void Function(int pageNumber, Map<String, dynamic>) onNext;
|
final void Function(int pageNumber, Map<String, dynamic>) onNext;
|
||||||
|
final Axis scrollDirection;
|
||||||
|
final ScrollPhysics? scrollPhysics;
|
||||||
|
|
||||||
const FlutterFormOptions({
|
const FlutterFormOptions({
|
||||||
required this.pages,
|
required this.pages,
|
||||||
|
@ -31,6 +37,8 @@ class FlutterFormOptions {
|
||||||
this.backButton,
|
this.backButton,
|
||||||
required this.onFinished,
|
required this.onFinished,
|
||||||
required this.onNext,
|
required this.onNext,
|
||||||
|
this.scrollDirection = Axis.horizontal,
|
||||||
|
this.scrollPhysics,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue