Flutter响应式文本输入插件reactive_text_field的使用

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

Flutter响应式文本输入插件reactive_text_field的使用

reactive_text_field 是一个围绕 TextField 构建的包装器,用于与 reactive_forms 一起使用。以下是详细的使用说明。

示例代码

import 'package:flutter/material.dart';
import 'package:reactive_forms/reactive_forms.dart' hide ReactiveTextField;
import 'package:reactive_text_field/reactive_text_field.dart';

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

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  TextEditingController? _controller;
  final FocusNode _focusNode = FocusNode();

  // 构建表单
  FormGroup buildForm() => fb.group({
        'input': FormControl<String>(value: 'some value'),
      });

  [@override](/user/override)
  void initState() {
    _focusNode.addListener(() {
      if (_focusNode.hasFocus) {
        _controller?.selection = TextSelection(
          baseOffset: 0,
          extentOffset: _controller?.text.length ?? 0,
        );
      }
    });
    super.initState();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Scaffold(
        body: SafeArea(
          child: SingleChildScrollView(
            physics: const BouncingScrollPhysics(),
            padding: const EdgeInsets.symmetric(
              horizontal: 20.0,
              vertical: 20.0,
            ),
            child: ReactiveFormBuilder(
              form: buildForm,
              builder: (context, form, child) {
                return Column(
                  children: [
                    // 使用ReactiveTextField
                    ReactiveTextField<String>(
                      formControlName: 'input',
                      onControllerInit: (controller) {
                        _controller = controller;
                      },
                      focusNode: _focusNode,
                    ),
                    const SizedBox(height: 16),
                    // 提交按钮
                    ElevatedButton(
                      child: const Text('Sign Up'),
                      onPressed: () {
                        if (form.valid) {
                          // 忽略:避免打印
                          print(form.value);
                        } else {
                          form.markAllAsTouched();
                        }
                      },
                    ),
                    // 全选文本按钮
                    ElevatedButton(
                      child: const Text('Select all text'),
                      onPressed: () {
                        if (_controller != null) {
                          form.control('input').focus();

                          _controller?.selection = TextSelection(
                            baseOffset: 0,
                            extentOffset: _controller?.text.length ?? 0,
                          );
                        }
                      },
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

代码解释

  1. 导入库

    import 'package:flutter/material.dart';
    import 'package:reactive_forms/reactive_forms.dart' hide ReactiveTextField;
    import 'package:reactive_text_field/reactive_text_field.dart';
    

    导入必要的库,包括 flutter 的核心库、reactive_formsreactive_text_field

  2. 创建应用主类

    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatefulWidget {
      const MyApp({Key? key}) : super(key: key);
    
      [@override](/user/override)
      State<MyApp> createState() => _MyAppState();
    }
    

    创建 MyApp 类,并在其中定义 _MyAppState 状态管理类。

  3. 构建表单

    FormGroup buildForm() => fb.group({
          'input': FormControl<String>(value: 'some value'),
        });
    

    定义一个表单,包含一个名为 input 的控件,并初始化其值为 some value

  4. 初始化状态

    [@override](/user/override)
    void initState() {
      _focusNode.addListener(() {
        if (_focusNode.hasFocus) {
          _controller?.selection = TextSelection(
            baseOffset: 0,
            extentOffset: _controller?.text.length ?? 0,
          );
        }
      });
      super.initState();
    }
    

    在组件初始化时添加焦点监听器,当文本框获得焦点时全选文本。

  5. 构建UI

    [@override](/user/override)
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
          visualDensity: VisualDensity.adaptivePlatformDensity,
        ),
        home: Scaffold(
          body: SafeArea(
            child: SingleChildScrollView(
              physics: const BouncingScrollPhysics(),
              padding: const EdgeInsets.symmetric(
                horizontal: 20.0,
                vertical: 20.0,
              ),
              child: ReactiveFormBuilder(
                form: buildForm,
                builder: (context, form, child) {
                  return Column(
                    children: [
                      // 使用ReactiveTextField
                      ReactiveTextField<String>(
                        formControlName: 'input',
                        onControllerInit: (controller) {
                          _controller = controller;
                        },
                        focusNode: _focusNode,
                      ),
                      const SizedBox(height: 16),
                      // 提交按钮
                      ElevatedButton(
                        child: const Text('Sign Up'),
                        onPressed: () {
                          if (form.valid) {
                            // 忽略:避免打印
                            print(form.value);
                          } else {
                            form.markAllAsTouched();
                          }
                        },
                      ),
                      // 全选文本按钮
                      ElevatedButton(
                        child: const Text('Select all text'),
                        onPressed: () {
                          if (_controller != null) {
                            form.control('input').focus();
    
                            _controller?.selection = TextSelection(
                              baseOffset: 0,
                              extentOffset: _controller?.text.length ?? 0,
                            );
                          }
                        },
                      ),
                    ],
                  );
                },
              ),
            ),
          ),
        ),
      );
    }
    

更多关于Flutter响应式文本输入插件reactive_text_field的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter响应式文本输入插件reactive_text_field的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用Flutter的reactive_text_field插件的示例代码。reactive_text_field是一个基于响应式编程理念的文本输入插件,通常与GetX或其他响应式状态管理库一起使用。这里我们假设你已经有一个基本的Flutter项目结构,并且已经添加了reactive_text_field依赖。

首先,确保在pubspec.yaml文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  reactive_text_field: ^x.y.z  # 请替换为最新版本号

然后,运行flutter pub get来获取依赖。

接下来,我们来看一个完整的示例,展示如何使用reactive_text_field

主文件 main.dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:reactive_text_field/reactive_text_field.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'Reactive TextField Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final ReactiveController _controller = ReactiveController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Reactive TextField Demo'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ReactiveTextField<String>(
              controller: _controller.textEditingController,
              onChanged: (value) {
                // 这里的value是文本字段的当前值
                print('Text changed to: $value');
              },
              decoration: InputDecoration(
                labelText: 'Enter text',
                border: OutlineInputBorder(),
              ),
            ),
            SizedBox(height: 20),
            Text(
              'Current Text: ${_controller.text}',
              style: TextStyle(fontSize: 20),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}

class ReactiveController extends GetxController {
  final ReactiveTextEditingController<String> textEditingController =
      ReactiveTextEditingController<String>();

  String get text => textEditingController.value;

  @override
  void onInit() {
    // 初始化时可以做一些设置
    super.onInit();
  }

  @override
  void onClose() {
    // 清理资源
    textEditingController.dispose();
    super.onClose();
  }
}

解释

  1. 依赖注入和初始化

    • 使用GetMaterialApp作为应用的根,这样我们可以利用GetX的状态管理功能。
    • 创建一个ReactiveController类来管理我们的响应式文本控制器。
  2. ReactiveTextField

    • ReactiveTextField是核心组件,它接收一个ReactiveTextEditingController作为控制器。
    • onChanged回调会在文本变化时被调用,这里我们简单地打印出当前值。
  3. 显示当前文本

    • 通过ReactiveControllertext属性获取当前文本值,并在界面上显示。
  4. 资源清理

    • ReactiveControlleronClose方法中调用textEditingController.dispose()来清理资源。
    • MyHomePagedispose方法中调用_controller.dispose()来确保控制器被正确释放。

这个示例展示了如何使用reactive_text_fieldGetX结合来实现响应式文本输入。你可以根据需求进一步扩展这个示例,比如添加验证逻辑、处理提交事件等。

回到顶部