Flutter表单管理插件formstack的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter表单管理插件formstack的使用

简介

logo

FormStack

Comprehensive Library for Creating Dynamic Form

Platform License: MIT FormStack Library version License: MIT

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

1 回复

更多关于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);
                  // 在这里处理表单提交逻辑,比如发送到服务器
                }
              },
            ),
          ],
        ),
      ),
    );
  }
}

解释

  1. 依赖添加:在pubspec.yaml中添加flutter_form_builder依赖。
  2. 表单构建:使用FormBuilder小部件来创建表单。FormBuilder接受一个initialValue参数来设置表单的初始值,以及一个child参数来定义表单字段。
  3. 表单字段:使用FormBuilderTextFieldFormBuilderCheckbox等小部件来定义表单字段。每个字段可以包含验证器(validators),这些验证器会在用户交互时触发。
  4. 表单提交:使用FormBuilderSubmitButton小部件来创建一个提交按钮。当用户点击提交按钮时,会调用onPressed回调,在该回调中,你可以验证表单并处理提交逻辑。

这个示例展示了如何使用flutter_form_builder来创建、验证和处理表单数据。如果你使用的是其他表单管理插件,如一个假设的formstack插件,请参考其官方文档,但大多数表单管理插件的API结构应该是类似的。

回到顶部