Flutter表单管理插件formstack的使用
Flutter表单管理插件formstack的使用
简介
FormStack
Comprehensive Library for Creating Dynamic Form
FormStack
是一个用于帮助开发者在 Flutter 中创建动态用户界面的库。特别是它专注于使用 JSON 或 Dart 模型来创建表单和调查。该库的主要目标是让开发者能够轻松地创建动态 UI,而无需编写大量代码。
支持的组件
- ✅ TextFiled - Text
- ✅ TextFiled - Number
- ✅ TextFiled - Password
- ✅ TextFiled - Name
- ✅ TextFiled - Email
- ✅ TextFiled - File Picker
- ✅ TextFiled - OTP View
- ✅ Cupertino Picker View - Date Only
- ✅ Cupertino Picker View - Date Time
- ✅ Cupertino Picker View - Time Only
- ✅ Single Selection List
- ✅ Multiple Selection List
- ✅ Dropdown List
- ✅ Smile Rating
- ✅ Dynamic Key Value Widget
- ✅ HTML Editor
- ✅ Location Picker (Using Google Map and Google Place Auto completer API)
示例代码
以下是一个完整的示例代码,展示了如何使用 FormStack
创建一个简单的表单应用。
main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:formstack/formstack.dart';
void main() {
runApp(const MainApp());
}
class MainApp extends StatelessWidget {
const MainApp({super.key});
@override
Widget build(BuildContext context) {
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white,
systemNavigationBarDividerColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.dark,
),
);
return MaterialApp(
theme: ThemeData(
useMaterial3: true,
colorScheme: ColorScheme.fromSwatch(
primarySwatch: Colors.blue,
backgroundColor: Colors.white,
),
),
home: const HomeScreen(),
debugShowCheckedModeBanner: false,
);
}
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: SizedBox(
width: 400,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
ListTile(
trailing: const Icon(Icons.arrow_forward_ios_outlined),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoadFromObjectScreen(),
),
);
},
title: const Text("Load Form using Object"),
subtitle: const Text("Render UI by constructing dart objects"),
),
ListTile(
trailing: const Icon(Icons.arrow_forward_ios_outlined),
onTap: () async {
FormStack.clearForms();
await FormStack.api().loadFromAssets(
['assets/app.json', 'assets/full.json'],
mapKey: MapKey("GOOGLE_MAP_ANDROID_KEY _KEY", "GOOGLE_MAP_IOS_KEY", "GOOGLE_MAP_WEB_KEY"),
initialLocation: LocationWrapper(0, 0),
).then(
(value) {
FormStack.api().addCompletionCallback(
GenericIdentifier(id: "IS_COMPLETED"),
formName: "login_form",
onFinish: (p0) {
debugPrint("$p0");
},
onBeforeFinishCallback: (result) async {
FormStack.api().setError(
GenericIdentifier(id: "email"),
"Invalid email,",
formName: "login_form",
);
FormStack.api()
.setResult(result, formName: "login_form");
return Future.value(false);
},
);
FormStack.api().setResult(
{"email": "sudhi.s@live.com"},
formName: "login_form",
);
// ignore: use_build_context_synchronously
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const LoadFromJSONScreen(),
),
);
},
);
},
title: const Text("Load Form Json File"),
subtitle: const Text("Render UI by loading from json file"),
)
],
),
),
),
);
}
}
class LoadFromObjectScreen extends StatelessWidget {
const LoadFromObjectScreen({super.key});
@override
Widget build(BuildContext context) {
FormStack.api().form(
initialLocation: LocationWrapper(0, 0),
mapKey: MapKey("GOOGLE_MAP_ANDROID_KEY _KEY", "GOOGLE_MAP_IOS_KEY", "GOOGLE_MAP_WEB_KEY"),
steps: [
InstructionStep(
id: GenericIdentifier(id: "IS_STARTED"),
title: "Example Survey",
text: "Simple survey example using dart model",
cancellable: false,
),
QuestionStep(
title: "Name",
text: "Your name",
inputType: InputType.name,
id: GenericIdentifier(id: "NAME"),
),
QuestionStep(
title: "Your Email ?",
text: "Tell Email address",
inputType: InputType.email,
id: GenericIdentifier(id: "EMAIL"),
),
QuestionStep(
title: "Phone Number",
text: "Share your phone number.",
inputType: InputType.number,
id: GenericIdentifier(id: "NUM"),
),
QuestionStep(
title: "Comment",
text: "Tell us about yourself and why you want our help to improve your health.",
inputType: InputType.text,
numberOfLines: 5,
id: GenericIdentifier(id: "COMMENT"),
),
QuestionStep(
title: "Multiple Choice",
text: "Select multiple countries",
inputType: InputType.multipleChoice,
options: [
Options("IN", "India"),
Options("CH", "China"),
Options("AM", "America"),
Options("SR", "Sri Lanka")
],
id: GenericIdentifier(id: "MULTIPLE_CHOICE"),
),
QuestionStep(
title: "Single Choice",
text: "Select one country",
inputType: InputType.singleChoice,
options: [
Options("IN", "India"),
Options("CH", "China"),
Options("AM", "America"),
Options("SR", "Sri Lanka")
],
id: GenericIdentifier(id: "SINGLE_CHOICE"),
),
QuestionStep(
title: "Time Only",
text: "Select time",
inputType: InputType.time,
id: GenericIdentifier(id: "TIME_ONLY"),
),
QuestionStep(
title: "Date Of Birth",
text: "Enter your date of birth",
inputType: InputType.dateTime,
id: GenericIdentifier(id: "DATE_TIME"),
),
QuestionStep(
title: "Are you happy",
text: "Rate your happiness",
inputType: InputType.smile,
id: GenericIdentifier(id: "IS_HAPPY"),
),
QuestionStep(
title: "Date Of Birth",
text: "Enter your date of birth",
inputType: InputType.date,
id: GenericIdentifier(id: "DOB"),
),
CompletionStep(
id: GenericIdentifier(id: "IS_COMPLETED"),
title: "Survey Completed",
text: "End of survey",
onFinish: (result) {
debugPrint("Completed With Result : $result");
},
),
],
);
return Scaffold(
body: FormStack.api().render(),
);
}
}
class LoadFromJSONScreen extends StatelessWidget {
const LoadFromJSONScreen({super.key});
@override
Widget build(BuildContext context) {
FormStack.api().setResult({
"dateOfBirth": "08-07-2023",
"firstName": "Sudhi",
"country": [
{"title": "Aruba", "subTitle": null, "key": "AW"}
]
}, formName: "contact_information");
FormStack.api().setResult({"approvedPosition": "BRANCH MANAGERS"}, formName: "login_form");
FormStack.api().addCompletionCallback(
GenericIdentifier(id: "IS_COMPLETED"),
formName: "contact_information",
onFinish: (p0) {
debugPrint("$p0");
},
onBeforeFinishCallback: (result) async {
return Future.value(true);
},
);
return Scaffold(
body: FormStack.api().render(),
);
}
}
JSON 示例
{
"default": {
"backgroundAnimationFile": "assets/bg.json",
"backgroundAlignment": "bottomCenter",
"steps": [
{
"type": "QuestionStep",
"title": "My Car",
"cancellable": false,
"titleIconAnimationFile": "assets/car.json",
"nextButtonText": "",
"autoTrigger": true,
"inputType": "singleChoice",
"options": [
{"key": "CAR_SELECTED", "title": "Select A Car"},
{"key": "CALL_DRIVER", "title": "Call Driver Now"}
],
"id": "CHOICE",
"relevantConditions": [{"id": "CALL_DRIVER", "expression": "IN CALL_DRIVER"}]
},
{
"type": "QuestionStep",
"title": "Select Car",
"titleIconAnimationFile": "assets/car.json",
"nextButtonText": "",
"autoTrigger": true,
"inputType": "singleChoice",
"options": [
{"key": "AUDI", "title": "Audi"},
{"key": "BENZ", "title": "Benz"},
{"key": "SUZUKI", "title": "Suzuki"}
],
"id": "CAR_SELECTED",
"relevantConditions": [{"id": "SMILE", "expression": "FOR_ALL"}]
},
{
"type": "QuestionStep",
"title": "Call / Ping Driver",
"titleIconAnimationFile": "assets/car.json",
"nextButtonText": "",
"autoTrigger": true,
"inputType": "singleChoice",
"options": [
{"key": "CALL", "title": "Call"},
{"key": "PING", "title": "PING"}
],
"id": "CALL_DRIVER"
},
{
"type": "QuestionStep",
"title": "Are you Happy",
"text": "",
"inputType": "smile",
"id": "SMILE"
},
{
"type": "CompletionStep",
"autoTrigger": true,
"nextButtonText": "",
"title": "Please wait..",
"id": "IS_COMPLETED"
}
]
}
}
在线演示
修改 web/index.html
以加载 Google Maps JavaScript API
<head>
<!-- // Other stuff -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY"></script>
</head>
Bugs 或请求
如果您遇到任何困难,请不要犹豫,在 GitHub 上打开一个 issue。如果您认为库缺少某个特定功能,请创建一个 ticket,我会进行调查。此外,我也欢迎 pull requests。
维护者
通过以上内容,您可以了解并使用 FormStack
插件来创建动态表单和调查。希望这些信息对您有所帮助!
更多关于Flutter表单管理插件formstack的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter表单管理插件formstack的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter中使用formstack
(这里假设你指的是一个用于管理表单状态的插件,尽管Flutter社区中可能没有直接名为formstack
的流行插件,但我们可以类比使用其他流行的表单管理插件如flutter_form_builder
或者手动管理表单状态)的示例代码。
由于Flutter本身没有直接的formstack
插件,我将使用flutter_form_builder
作为替代示例,因为它是一个流行的用于创建和管理表单的Flutter插件。如果你确实有一个特定的formstack
插件,请参考其官方文档,但以下代码结构可以作为大多数表单管理插件的参考。
使用flutter_form_builder
管理表单
首先,确保在你的pubspec.yaml
文件中添加flutter_form_builder
依赖:
dependencies:
flutter:
sdk: flutter
flutter_form_builder: ^6.0.0 # 确保使用最新版本
然后,运行flutter pub get
来安装依赖。
创建表单UI
下面是一个简单的Flutter应用示例,展示如何使用flutter_form_builder
来创建和管理表单:
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('FormStack Example'),
),
body: FormBuilderExample(),
),
);
}
}
class FormBuilderExample extends StatefulWidget {
@override
_FormBuilderExampleState createState() => _FormBuilderExampleState();
}
class _FormBuilderExampleState extends State<FormBuilderExample> {
final _formKey = GlobalKey<FormBuilderState>();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16.0),
child: FormBuilder(
key: _formKey,
initialValue: {
'name': '',
'email': '',
},
autoValidateMode: AutovalidateMode.onUserInteraction,
child: Column(
children: <Widget>[
FormBuilderTextField(
name: 'name',
decoration: InputDecoration(labelText: 'Name'),
validators: [
FormBuilderValidators.required(errorText: 'Name is required'),
],
),
FormBuilderTextField(
name: 'email',
decoration: InputDecoration(labelText: 'Email'),
keyboardType: TextInputType.emailAddress,
validators: [
FormBuilderValidators.required(errorText: 'Email is required'),
FormBuilderValidators.email(errorText: 'Email is not valid'),
],
),
FormBuilderCheckbox(
name: 'subscribe',
label: Text('Subscribe to newsletter'),
),
SizedBox(height: 20),
FormBuilderSubmitButton(
child: Text('Submit'),
onPressed: () {
if (_formKey.currentState!.validate()) {
_formKey.currentState!.save();
print(_formKey.currentState!.value);
// 在这里处理表单提交逻辑,比如发送到服务器
}
},
),
],
),
),
);
}
}
解释
- 依赖添加:在
pubspec.yaml
中添加flutter_form_builder
依赖。 - 表单构建:使用
FormBuilder
小部件来创建表单。FormBuilder
接受一个initialValue
参数来设置表单的初始值,以及一个child
参数来定义表单字段。 - 表单字段:使用
FormBuilderTextField
和FormBuilderCheckbox
等小部件来定义表单字段。每个字段可以包含验证器(validators
),这些验证器会在用户交互时触发。 - 表单提交:使用
FormBuilderSubmitButton
小部件来创建一个提交按钮。当用户点击提交按钮时,会调用onPressed
回调,在该回调中,你可以验证表单并处理提交逻辑。
这个示例展示了如何使用flutter_form_builder
来创建、验证和处理表单数据。如果你使用的是其他表单管理插件,如一个假设的formstack
插件,请参考其官方文档,但大多数表单管理插件的API结构应该是类似的。