Flutter幸运转盘插件fortune_wheel_enhanced的使用

Flutter幸运转盘插件fortune_wheel_enhanced的使用

Flutter Fortune Wheel

这个Flutter插件包含了轮盘小部件,可以用来可视化随机选择过程。这些小部件高度可定制,并且可以在移动设备、桌面端和Web上运行。

幸运转盘

你可以在这篇文章中了解更多关于轮盘实现的细节,并尝试这里的交互式演示。

快速开始

首先通过pub.dev安装该插件。 然后导入并使用FortuneWheelEnhanced

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

StreamController<int> controller = StreamController<int>();

[@override](/user/override)
Widget build(BuildContext context) {
  return FortuneWheelEnhanced(
    selected: controller.stream,
    items: [
      FortuneItem(child: Text('Han Solo')),
      FortuneItem(child: Text('Yoda')),
      FortuneItem(child: Text('Obi-Wan Kenobi')),
    ],
  );
}

示例

轮盘

轮盘是最具代表性的可视化形式。

轮盘旋转

幸运条形图

不幸的是,当垂直屏幕空间稀缺时,圆形形状并不是最佳解决方案。因此,提供了较小的垂直方向的幸运条形图作为替代。以下是一个示例:

幸运条形图动画

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

StreamController<int> controller = StreamController<int>();

[@override](/user/override)
Widget build(BuildContext context) {
  return FortuneBar(
    selected: controller.stream,
    items: [
      FortuneItem(child: Text('Han Solo')),
      FortuneItem(child: Text('Yoda')),
      FortuneItem(child: Text('Obi-Wan Kenobi')),
    ],
  );
}

定制化

拖拽行为

默认情况下,幸运转盘和条形图对触摸和拖拽输入有反应。这种行为可以通过physics属性进行自定义,该属性期望一个实现了PanPhysics类的实例。如果你想禁用拖拽,只需传递一个NoPanPhysics实例。

对于FortuneWheelEnhanced,建议使用CircularPanPhysics。而对于FortuneBar,默认使用DirectionalPanPhysics.horizontal。如果你的需求不符合现有的任何实现,你可以总是创建一个PanPhysics的子类。

PanPhysics检测到滑动手势时,传递给onFling的回调会被调用。这给了你选择新随机项目的机会。

StreamController<int> controller = StreamController<int>();

[@override](/user/override)
Widget build(BuildContext context) {
  return FortuneWheelEnhanced(
    // 更改用户停止拖动时的返回动画
    physics: CircularPanPhysics(
      duration: Duration(seconds: 1),
      curve: Curves.decelerate,
    ),
    onFling: () {
      controller.add(1);
    },
    selected: controller.stream,
    items: [
      FortuneItem(child: Text('Han Solo')),
      FortuneItem(child: Text('Yoda')),
      FortuneItem(child: Text('Obi-Wan Kenobi')),
    ],
  );
}

项目样式

FortuneItems可以通过其style属性进行单独样式设置。根据共同逻辑为FortuneWidget的项目设置样式,可以通过传递StyleStrategy来实现。默认情况下,FortuneWheelEnhanced使用AlternatingStyleStrategy,而FortuneBar使用UniformStyleStrategy。与拖拽行为一样,你可以将自定义实现传递给styleStrategy属性。

// 单独样式化FortuneItems
FortuneWheelEnhanced(
  selected: Stream.value(0),
  items: [
    FortuneItem(
      child: Text('A'),
      style: FortuneItemStyle(
        color: Colors.red, // 自定义圆环切片填充颜色
        borderColor: Colors.green, // 自定义圆环切片描边颜色
        borderWidth: 3, // 自定义圆环切片描边宽度
      ),
    ),
    FortuneItem(child: Text('B')),
  ],
)

// 为FortuneWidget的所有项目应用通用样式
FortuneBar(
  // 在幸运条形图上使用交替项目样式
  styleStrategy: AlternatingStyleStrategy(),
  selected: Stream.value(0),
  items: [
    FortuneItem(child: Text('Han Solo')),
    FortuneItem(child: Text('Yoda')),
    FortuneItem(child: Text('Obi-Wan Kenobi')),
  ],
)

指示器样式

可以通过传递一组FortuneIndicatorFortuneWidget.indicators来自定义指示器。默认情况下,FortuneWheelEnhanced使用TriangleIndicator,而FortuneBar使用RectangleIndicator。你可以传递这些现有小部件的样式版本,或者创建自己的实现,因为指示器可以是任何类型的widget。以下是一个自定义指示器的例子:

FortuneWheelEnhanced(
  selected: Stream.value(0),
  indicators: [
    FortuneIndicator(
      alignment: Alignment.bottomCenter, // 改变指示器的位置
      child: TriangleIndicator(
        color: Colors.green, // 改变指示器的颜色
      ),
    ),
  ],
  items: [
    FortuneItem(child: Text('A')),
    FortuneItem(child: Text('B')),
  ],
)

示例代码

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

import 'dart:async';

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

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

  [@override](/user/override)
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Fortune Wheel Example',
      home: ExamplePage(),
    );
  }
}

class ExamplePage extends StatefulWidget {
  const ExamplePage({super.key});

  [@override](/user/override)
  _ExamplePageState createState() => _ExamplePageState();
}

class _ExamplePageState extends State<ExamplePage> {
  StreamController<int> selected = StreamController<int>();

  [@override](/user/override)
  void dispose() {
    selected.close();
    super.dispose();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    final items = [
      'Grogu',
      'Mace Windu',
      'Obi-Wan Kenobi',
      'Han Solo',
      'Luke Skywalker',
      'Darth Vader',
      'Yoda',
      'Ahsoka Tano',
    ];

    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter Fortune Wheel'),
      ),
      body: GestureDetector(
        onTap: () {
          setState(() {
            selected.add(
              Fortune.randomInt(0, items.length),
            );
          });
        },
        child: Column(
          children: [
            Expanded(
              child: FortuneWheelEnhanced(
                selected: selected.stream,
                items: [
                  for (var it in items) FortuneItem(child: Text(it)),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

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

更多关于Flutter幸运转盘插件fortune_wheel_enhanced的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter幸运转盘插件fortune_wheel_enhanced的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


fortune_wheel_enhanced 是一个 Flutter 插件,可以帮助你轻松创建一个可自定义的幸运转盘。这个插件提供了丰富的配置选项,可以让你自定义转盘的外观、动画效果以及交互行为。

1. 添加依赖

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

dependencies:
  flutter:
    sdk: flutter
  fortune_wheel_enhanced: ^最新版本

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

2. 基本使用

下面是一个简单的基本使用示例:

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

class WheelPage extends StatefulWidget {
  @override
  _WheelPageState createState() => _WheelPageState();
}

class _WheelPageState extends State<WheelPage> {
  final List<String> items = ['一等奖', '二等奖', '三等奖', '谢谢参与'];
  String? selectedItem;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('幸运转盘'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            FortuneWheelEnhanced(
              items: items.map((item) => FortuneItem(child: Text(item))).toList(),
              onAnimationEnd: (selectedIndex) {
                setState(() {
                  selectedItem = items[selectedIndex];
                });
              },
            ),
            SizedBox(height: 20),
            Text(
              selectedItem == null ? '点击转盘开始' : '你获得了: $selectedItem',
              style: TextStyle(fontSize: 20),
            ),
          ],
        ),
      ),
    );
  }
}

3. 自定义配置

fortune_wheel_enhanced 提供了许多自定义选项,以下是一些常见的配置示例:

FortuneWheelEnhanced(
  items: items.map((item) => FortuneItem(child: Text(item))).toList(),
  onAnimationEnd: (selectedIndex) {
    setState(() {
      selectedItem = items[selectedIndex];
    });
  },
  textStyle: TextStyle(
    fontSize: 20,
    color: Colors.white,
    fontWeight: FontWeight.bold,
  ),
  colorSequences: [
    Colors.red,
    Colors.blue,
    Colors.green,
    Colors.yellow,
  ],
  indicators: [
    FortuneIndicator(
      alignment: Alignment.topCenter,
      child: TriangleIndicator(color: Colors.black),
    ),
  ],
  rotateDuration: Duration(seconds: 3),
  curve: Curves.easeInOut,
  physics: CircularPanPhysics(
    duration: Duration(seconds: 3),
    curve: Curves.easeInOut,
  ),
)

4. 主要参数说明

  • items: 转盘的选项列表,通常使用 FortuneItem 来包装每个选项的内容。
  • onAnimationEnd: 当转盘动画结束时触发的回调函数,参数是选中的索引。
  • textStyle: 文本样式,用于设置选项中的文字样式。
  • colorSequences: 转盘每个部分的颜色序列。
  • indicators: 指示器,通常是指向选中的箭头或其他标记。
  • rotateDuration: 转盘旋转的持续时间。
  • curve: 动画的曲线效果。
  • physics: 转盘的物理效果,例如 CircularPanPhysics 用于模拟转盘的旋转。

5. 高级功能

你可以通过 FortuneWheelEnhancedController 来控制转盘的行为,例如手动启动转盘、停止转盘等。

final _controller = FortuneWheelEnhancedController();

FortuneWheelEnhanced(
  controller: _controller,
  items: items.map((item) => FortuneItem(child: Text(item))).toList(),
  onAnimationEnd: (selectedIndex) {
    setState(() {
      selectedItem = items[selectedIndex];
    });
  },
);

// 手动启动转盘
_controller.rotate();
回到顶部