Flutter表单动画包装插件form_animate_wrap的使用

Flutter表单动画包装插件form_animate_wrap的使用

Animated wrappers可以用来包裹TextFormField以获得一些不错的交互效果。

安装

在你的Flutter项目的pubspec.yaml文件中添加以下依赖:

form_animate_wrap: ^0.0.6

然后在你需要使用的文件中导入它:

import 'package:form_animate_wrap/form_animate_wrap.dart';

使用

动画验证器(Anime Validator)
动画验证器演示

此包装器可用于包裹TextFormField,如果需要在事件如验证错误时添加动画效果。

TextEditingController firstNameController = TextEditingController();

AnimeValidator(
   enableAnimation: true,
   child: CustomTextFormField( 
     controller: firstNameController,
     hintTextVal: "First Name",
  )),
荧光选择器(Glow Selector)
荧光选择器演示

此包装器可用于识别选中的TextFormField。如果有多个TextFormField,这将有助于快速识别选中的字段。

FocusNode firstNameNode = FocusNode();

GlowSelector(
   borderRadius: 15,
   enableFocusGlowing: true,
   focusGlowColor: Colors.blueAccent,
   focusNode: firstNameNode,
   child: CustomTextFormField(
     focusNode: firstNameNode,
     hintTextVal: "First Name",
   )),
荧光验证器(Glow Validator)
荧光验证器演示

此包装器可用于基于条件验证TextField。例如,你可以在提交表单时设置包装器以高亮显示空文本框。

TextEditingController firstNameController = TextEditingController();

GlowValidator(
   borderRadius: 15,
   enableAnimation: true,
   child: CustomTextFormField(
     controller: firstNameController,
   hintTextVal: "First Name",
  )),

示例代码

以下是完整的示例代码:

import 'package:animated_validator/widgets/custom_text_input.dart';
import 'package:flutter/material.dart';
import 'package:form_animate_wrap/form_animate_wrap.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // 此小部件是您的应用程序的根。
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Form Animate Wrap Demo'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool isSubmittedAnimeValidator = false;
  bool isSubmittedGlowValidator = false;
  TextEditingController avFirstNameController = TextEditingController();
  TextEditingController avLastNameController = TextEditingController();
  TextEditingController avEmailController = TextEditingController();

  TextEditingController gvFirstNameController = TextEditingController();
  TextEditingController gvLastNameController = TextEditingController();
  TextEditingController gvEmailController = TextEditingController();

  FocusNode firstNameNode = FocusNode();
  FocusNode lastNameNode = FocusNode();
  FocusNode emailNode = FocusNode();

  [@override](/user/override)
  Widget build(BuildContext context) {
    double height = MediaQuery.of(context).size.height;
    double width = MediaQuery.of(context).size.width;
    double appbarHeight = AppBar().preferredSize.height;

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: PageView(
        children: [
          Container(
            color: Colors.white,
            child: SingleChildScrollView(
              child: Center(
                child: SizedBox(
                  width: width * 0.8,
                  height: height - appbarHeight,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      SizedBox(
                        height: height * 0.5,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: [
                            const Text(
                              "Anime Validators",
                              style: TextStyle(
                                  fontSize: 24,
                                  fontWeight: FontWeight.bold,
                                  color: Colors.black),
                            ),
                            AnimeValidator(
                                enableAnimation:
                                    getAVValidity(avFirstNameController),
                                child: CustomTextFormField(
                                  controller: avFirstNameController,
                                  hintTextVal: "First Name",
                                )),
                            AnimeValidator(
                                enableAnimation:
                                    getAVValidity(avLastNameController),
                                child: CustomTextFormField(
                                  controller: avLastNameController,
                                  hintTextVal: "Last Name",
                                )),
                            AnimeValidator(
                                enableAnimation:
                                    getAVValidity(avEmailController),
                                child: CustomTextFormField(
                                  controller: avEmailController,
                                  hintTextVal: "Email",
                                )),
                          ],
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(bottom: 50),
                        child: GestureDetector(
                          onTap: () {
                            setState(() {
                              isSubmittedAnimeValidator = true;
                            });
                          },
                          child: Container(
                            decoration: BoxDecoration(
                                color: Colors.lightBlue,
                                borderRadius: BorderRadius.circular(15)),
                            width: width * 0.8,
                            child: const Padding(
                              padding: EdgeInsets.all(16.0),
                              child: Text(
                                "Submit",
                                style: TextStyle(
                                    fontSize: 20,
                                    color: Colors.white,
                                    fontWeight: FontWeight.bold),
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
          Container(
            color: Colors.white,
            child: SingleChildScrollView(
              child: Center(
                child: SizedBox(
                  width: width * 0.8,
                  height: height - appbarHeight,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      SizedBox(
                        height: height * 0.5,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: [
                            const Text(
                              "Glow Selector",
                              style: TextStyle(
                                  fontSize: 24,
                                  fontWeight: FontWeight.bold,
                                  color: Colors.black),
                            ),
                            GlowSelector(
                                borderRadius: 15,
                                enableFocusGlowing: true,
                                focusGlowColor: Colors.blueAccent,
                                focusNode: firstNameNode,
                                child: CustomTextFormField(
                                  focusNode: firstNameNode,
                                  hintTextVal: "First Name",
                                )),
                            GlowSelector(
                                borderRadius: 15,
                                enableFocusGlowing: true,
                                focusNode: lastNameNode,
                                focusGlowColor: Colors.green,
                                child: CustomTextFormField(
                                  focusNode: lastNameNode,
                                  hintTextVal: "Last Name",
                                )),
                            GlowSelector(
                                borderRadius: 15,
                                enableFocusGlowing: true,
                                focusNode: emailNode,
                                focusGlowColor: Colors.red,
                                child: CustomTextFormField(
                                  focusNode: emailNode,
                                  hintTextVal: "Email",
                                ))
                          ],
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(bottom: 50),
                        child: GestureDetector(
                          onTap: () {},
                          child: Container(
                            decoration: BoxDecoration(
                                color: Colors.lightBlue,
                                borderRadius: BorderRadius.circular(15)),
                            width: width * 0.8,
                            child: const Padding(
                              padding: EdgeInsets.all(16.0),
                              child: Text(
                                "Submit",
                                style: TextStyle(
                                    fontSize: 20,
                                    color: Colors.white,
                                    fontWeight: FontWeight.bold),
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
          Container(
            color: Colors.white,
            child: SingleChildScrollView(
              child: Center(
                child: SizedBox(
                  width: width * 0.8,
                  height: height - appbarHeight,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      SizedBox(
                        height: height * 0.5,
                        child: Column(
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: [
                            const Text(
                              "Glow Validators",
                              style: TextStyle(
                                  fontSize: 24,
                                  fontWeight: FontWeight.bold,
                                  color: Colors.black),
                            ),
                            GlowValidator(
                                borderRadius: 15,
                                enableAnimation:
                                    getGVValidity(gvFirstNameController),
                                child: CustomTextFormField(
                                  controller: gvFirstNameController,
                                  hintTextVal: "First Name",
                                )),
                            GlowValidator(
                                borderRadius: 15,
                                enableAnimation:
                                    getGVValidity(gvLastNameController),
                                child: CustomTextFormField(
                                  controller: gvLastNameController,
                                  hintTextVal: "Last Name",
                                )),
                            GlowValidator(
                                borderRadius: 15,
                                enableAnimation:
                                    getGVValidity(gvEmailController),
                                child: CustomTextFormField(
                                  controller: gvEmailController,
                                  hintTextVal: "Email",
                                )),
                          ],
                        ),
                      ),
                      Padding(
                        padding: const EdgeInsets.only(bottom: 50),
                        child: GestureDetector(
                          onTap: () {
                            setState(() {
                              isSubmittedGlowValidator = true;
                            });
                          },
                          child: Container(
                            decoration: BoxDecoration(
                                color: Colors.lightBlue,
                                borderRadius: BorderRadius.circular(15)),
                            width: width * 0.8,
                            child: const Padding(
                              padding: EdgeInsets.all(16.0),
                              child: Text(
                                "Submit",
                                style: TextStyle(
                                    fontSize: 20,
                                    color: Colors.white,
                                    fontWeight: FontWeight.bold),
                                textAlign: TextAlign.center,
                              ),
                            ),
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
    );
  }

  bool getAVValidity(TextEditingController controller) {
    if ((isSubmittedAnimeValidator && controller.text.isNotEmpty) ||
        (!isSubmittedAnimeValidator && controller.text.isNotEmpty)) {
      return false;
    } else {
      if (isSubmittedAnimeValidator) {
        return true;
      } else {
        return false;
      }
    }
  }

  bool getGVValidity(TextEditingController controller) {
    if ((isSubmittedGlowValidator && controller.text.isNotEmpty) ||
        (!isSubmittedGlowValidator && controller.text.isNotEmpty)) {
      return false;
    } else {
      if (isSubmittedGlowValidator) {
        return true;
      } else {
        return false;
      }
    }
  }
}

更多关于Flutter表单动画包装插件form_animate_wrap的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter表单动画包装插件form_animate_wrap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


form_animate_wrap 是一个Flutter插件,用于在表单提交时添加动画效果,例如加载动画、成功或失败的提示动画等。这个插件可以帮助你在表单提交过程中提供更好的用户体验。

安装

首先,你需要在 pubspec.yaml 文件中添加 form_animate_wrap 依赖:

dependencies:
  flutter:
    sdk: flutter
  form_animate_wrap: ^1.0.0  # 请检查最新版本

然后运行 flutter pub get 来安装依赖。

使用

form_animate_wrap 提供了一个 FormAnimateWrap 小部件,你可以将表单内容包裹在其中,并在表单提交时显示动画。

基本用法

import 'package:flutter/material.dart';
import 'package:form_animate_wrap/form_animate_wrap.dart';

class MyForm extends StatefulWidget {
  @override
  _MyFormState createState() => _MyFormState();
}

class _MyFormState extends State<MyForm> {
  final _formKey = GlobalKey<FormState>();
  String _name = '';

  Future<void> _submitForm() async {
    if (_formKey.currentState!.validate()) {
      _formKey.currentState!.save();
      // 模拟网络请求
      await Future.delayed(Duration(seconds: 2));
      // 这里可以处理提交逻辑
      print('Name: $_name');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Form Animate Wrap Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: FormAnimateWrap(
          onSubmit: _submitForm,
          child: Form(
            key: _formKey,
            child: Column(
              children: [
                TextFormField(
                  decoration: InputDecoration(labelText: 'Name'),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Please enter your name';
                    }
                    return null;
                  },
                  onSaved: (value) {
                    _name = value!;
                  },
                ),
                SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () {
                    if (_formKey.currentState!.validate()) {
                      _submitForm();
                    }
                  },
                  child: Text('Submit'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

参数说明

  • onSubmit: 表单提交时触发的异步函数。在这个函数中,你可以处理表单提交的逻辑。
  • child: 包裹的表单内容。
  • loadingWidget: 自定义加载动画,默认是一个 CircularProgressIndicator
  • successWidget: 自定义成功提示动画,默认是一个图标和文本。
  • errorWidget: 自定义错误提示动画,默认是一个图标和文本。

自定义动画

你可以通过 loadingWidgetsuccessWidgeterrorWidget 参数来自定义动画:

FormAnimateWrap(
  onSubmit: _submitForm,
  loadingWidget: Center(child: Text('Loading...')),
  successWidget: Center(child: Icon(Icons.check, color: Colors.green)),
  errorWidget: Center(child: Icon(Icons.error, color: Colors.red)),
  child: Form(
    key: _formKey,
    child: Column(
      children: [
        // 表单字段
      ],
    ),
  ),
)
回到顶部