Flutter触控旋转交互插件reactive_touch_spin的使用

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

Flutter触控旋转交互插件reactive_touch_spin的使用

reactive_touch_spin 是一个基于 flutter_touch_spin 的包装器,用于与 reactive_forms 一起使用。目前文档还在编写中。您可以查看 example 文件夹以获取示例。

示例代码

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:reactive_forms/reactive_forms.dart';
import 'package:reactive_touch_spin/reactive_touch_spin.dart';

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

// 自定义值访问器,用于处理数值转换
class NumValueAccessor extends ControlValueAccessor<int, num> {
  final int fractionDigits;

  NumValueAccessor({
    this.fractionDigits = 2,
  });

  @override
  num? modelToViewValue(int? modelValue) {
    return modelValue;
  }

  @override
  int? viewToModelValue(num? viewValue) {
    return viewValue?.toInt();
  }
}

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

  // 构建表单
  FormGroup buildForm() => fb.group({
        'touchSpin': FormControl<int>(value: 10),
      });

  @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: [
                    // 使用ReactiveTouchSpin组件
                    ReactiveTouchSpin<int>(
                      formControlName: 'touchSpin',
                      valueAccessor: NumValueAccessor(),
                      displayFormat: NumberFormat()..minimumFractionDigits = 0,
                      min: 5,
                      max: 100,
                      step: 5,
                      textStyle: const TextStyle(fontSize: 18),
                      decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        contentPadding: EdgeInsets.fromLTRB(12, 12, 0, 0),
                        labelText: "Search amount",
                        helperText: '',
                      ),
                    ),
                    const SizedBox(height: 16),
                    // 提交按钮
                    ElevatedButton(
                      child: const Text('Sign Up'),
                      onPressed: () {
                        if (form.valid) {
                          // 打印表单值
                          print(form.value);
                        } else {
                          form.markAllAsTouched();
                        }
                      },
                    ),
                  ],
                );
              },
            ),
          ),
        ),
      ),
    );
  }
}

说明

  1. 导入库

    import 'package:flutter/material.dart';
    import 'package:intl/intl.dart';
    import 'package:reactive_forms/reactive_forms.dart';
    import 'package:reactive_touch_spin/reactive_touch_spin.dart';
    
  2. 自定义值访问器

    class NumValueAccessor extends ControlValueAccessor<int, num> {
      final int fractionDigits;
    
      NumValueAccessor({
        this.fractionDigits = 2,
      });
    
      @override
      num? modelToViewValue(int? modelValue) {
        return modelValue;
      }
    
      @override
      int? viewToModelValue(num? viewValue) {
        return viewValue?.toInt();
      }
    }
    
  3. 构建表单

    FormGroup buildForm() => fb.group({
          'touchSpin': FormControl<int>(value: 10),
        });
    
  4. 创建应用

    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @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: [
                        // 使用ReactiveTouchSpin组件
                        ReactiveTouchSpin<int>(
                          formControlName: 'touchSpin',
                          valueAccessor: NumValueAccessor(),
                          displayFormat: NumberFormat()..minimumFractionDigits = 0,
                          min: 5,
                          max: 100,
                          step: 5,
                          textStyle: const TextStyle(fontSize: 18),
                          decoration: const InputDecoration(
                            border: OutlineInputBorder(),
                            contentPadding: EdgeInsets.fromLTRB(12, 12, 0, 0),
                            labelText: "Search amount",
                            helperText: '',
                          ),
                        ),
                        const SizedBox(height: 16),
                        // 提交按钮
                        ElevatedButton(
                          child: const Text('Sign Up'),
                          onPressed: () {
                            if (form.valid) {
                              // 打印表单值
                              print(form.value);
                            } else {
                              form.markAllAsTouched();
                            }
                          },
                        ),
                      ],
                    );
                  },
                ),
              ),
            ),
          ),
        );
      }
    }
    

更多关于Flutter触控旋转交互插件reactive_touch_spin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter触控旋转交互插件reactive_touch_spin的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何使用Flutter中的reactive_touch_spin插件来实现触控旋转交互的示例代码。这个插件允许用户通过触摸和旋转手势来操控UI元素,非常适合需要旋转交互的应用场景。

首先,确保你已经在pubspec.yaml文件中添加了reactive_touch_spin依赖:

dependencies:
  flutter:
    sdk: flutter
  reactive_touch_spin: ^最新版本号  # 请替换为最新的版本号

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

以下是一个完整的示例代码,展示了如何使用reactive_touch_spin插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Reactive Touch Spin Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('Reactive Touch Spin Demo'),
        ),
        body: Center(
          child: ReactiveTouchSpinDemo(),
        ),
      ),
    );
  }
}

class ReactiveTouchSpinDemo extends StatefulWidget {
  @override
  _ReactiveTouchSpinDemoState createState() => _ReactiveTouchSpinDemoState();
}

class _ReactiveTouchSpinDemoState extends State<ReactiveTouchSpinDemo> {
  double _angle = 0.0;

  @override
  Widget build(BuildContext context) {
    return ReactiveTouchSpin(
      onAngleChanged: (angle) {
        setState(() {
          _angle = angle;
        });
      },
      initialAngle: _angle,
      child: Container(
        width: 200,
        height: 200,
        decoration: BoxDecoration(
          color: Colors.blue.withOpacity(0.5),
          shape: BoxShape.circle,
        ),
        child: Center(
          child: Transform.rotate(
            angle: _angle,
            child: Icon(
              Icons.arrow_circle_down,
              color: Colors.white,
              size: 50,
            ),
          ),
        ),
      ),
    );
  }
}

在这个示例中:

  1. 我们创建了一个MyApp应用,它包含一个Scaffold,并在其主体中放置了一个ReactiveTouchSpinDemo组件。
  2. ReactiveTouchSpinDemo是一个有状态的组件,它维护了一个_angle状态变量来存储当前的旋转角度。
  3. ReactiveTouchSpin组件被用来包裹一个可旋转的容器。当用户旋转这个容器时,onAngleChanged回调会被触发,并更新_angle状态。
  4. 在容器内部,我们使用Transform.rotate来根据_angle值旋转一个图标。

这个示例展示了如何使用reactive_touch_spin插件来检测用户的旋转手势,并相应地更新UI。你可以根据需要进一步自定义和扩展这个示例。

回到顶部