📜  带有块库的颤振计数器应用程序 - Dart (1)

📅  最后修改于: 2023-12-03 15:25:27.288000             🧑  作者: Mango

带有块库的颤振计数器应用程序 - Dart

本文介绍的是一个用Dart编写的颤振计数器应用程序,该应用程序使用了Flutter框架的块库(Block library)。

块库(Block library)

块库是一种可重用代码块的封装方式,它使得代码重用更加简单和高效。块库可以有多个输入和多个输出,这些输入和输出可以是不同类型的数据,包括数字、文本、图像等等。使用块库可以使得代码更加易于维护和重构,同时也可以提高代码的可读性和可维护性。

Flutter提供了自带的块库(Block library),其中包含了很多常用的块,例如计算器块、字符串操作块、网络请求块等等。如果你需要更多其他的块,也可以使用Flutter社区提供的第三方块库,例如dart_blocks等等。

应用程序介绍

这个颤振计数器应用程序使用了Flutter自带的块库(Block library)实现。用户可以选择两种不同的计数器,一个是基于手势的计数器,用户通过点击和滑动屏幕上的数字来实现计数;另一个是基于计时器的计数器,用户可以选择不同的计时器周期来实现计数。用户可以通过按钮来切换计数器类型。

以下是应用程序实现的核心代码,其中体现了块库的使用方式:

class CounterBloc {
  final _counter = BehaviorSubject<int>.seeded(0);

  // 输入块:更新计数器数值
  Function(int) get updateCounter => _counter.sink.add;

  // 输出块:获取当前的计数器数值
  Stream<int> get counter => _counter.stream;

  // 通过StreamController来实现输入和输出块的连接
  CounterBloc() {
    _counter.addTransformer(StreamTransformer.fromHandlers(handleData: (int data, sink) {
      if (data < 0) {
        sink.addError("Counter can't be negative");
      } else {
        sink.add(data);
      }
    }));
  }

  // 释放资源
  dispose() {
    _counter.close();
  }
}

class CounterScreen extends StatefulWidget {
  @override
  _CounterScreenState createState() => _CounterScreenState();
}

class _CounterScreenState extends State<CounterScreen> {
  final _counterBloc = CounterBloc();
  bool _isGestureCounter = true;
  Timer _timer;

  // 计时器回调函数
  void _timerCallback(Timer timer) {
    _counterBloc.updateCounter(_counterBloc.counter.value + 1);
  }

  // 切换计数器类型
  void _toggleCounter() {
    setState(() {
      _isGestureCounter = !_isGestureCounter;
      if (!_isGestureCounter) {
        _timer = Timer.periodic(Duration(seconds: 1), _timerCallback);
      } else {
        _timer?.cancel();
      }
    });
  }

  // 构建基于手势的计数器UI部分
  Widget _buildGestureCounter() {
    return GestureDetector(
      onTap: () => _counterBloc.updateCounter(_counterBloc.counter.value + 1),
      onVerticalDragUpdate: (details) {
        if (details.delta.dy < -5) {
          _counterBloc.updateCounter(_counterBloc.counter.value + 1);
        } else if (details.delta.dy > 5) {
          _counterBloc.updateCounter(_counterBloc.counter.value - 1);
        }
      },
      child: Center(
        child: StreamBuilder<int>(
            stream: _counterBloc.counter,
            builder: (context, snapshot) {
              return Text(
                '${snapshot.data}',
                style: TextStyle(fontSize: 80),
              );
            }),
      ),
    );
  }

  // 构建基于计时器的计数器UI部分
  Widget _buildTimerCounter() {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Text(
            'Counter value:',
            style: TextStyle(fontSize: 24),
          ),
          SizedBox(height: 16),
          StreamBuilder<int>(
              stream: _counterBloc.counter,
              builder: (context, snapshot) {
                return Text(
                  '${snapshot.data}',
                  style: TextStyle(fontSize: 80),
                );
              }),
          SizedBox(height: 16),
          Text(
            'Timer period:',
            style: TextStyle(fontSize: 24),
          ),
          SizedBox(height: 16),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              RaisedButton(
                onPressed: () => _timer?.cancel(),
                child: Text(
                  'STOP',
                  style: TextStyle(fontSize: 20),
                ),
              ),
              SizedBox(width: 16),
              RaisedButton(
                onPressed: () => _timer = Timer.periodic(Duration(seconds: 1), _timerCallback),
                child: Text(
                  'START',
                  style: TextStyle(fontSize: 20),
                ),
              ),
              SizedBox(width: 16),
              DropdownButton<int>(
                value: _timer?.tickDuration?.inSeconds ?? 1,
                items: [1, 2, 3, 4, 5].map((e) {
                  return DropdownMenuItem<int>(
                    value: e,
                    child: Text('$e second${e == 1 ? '' : 's'}'),
                  );
                }).toList(),
                onChanged: (value) {
                  _timer?.cancel();
                  setState(() {
                    _timer = Timer.periodic(Duration(seconds: value), _timerCallback);
                  });
                },
              ),
            ],
          ),
        ],
      ),
    );
  }

  // 应用程序主UI
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Counter'),
      ),
      body: _isGestureCounter ? _buildGestureCounter() : _buildTimerCounter(),
      floatingActionButton: FloatingActionButton(
        onPressed: _toggleCounter,
        child: Icon(Icons.swap_horiz),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _counterBloc.dispose();
  }
}
总结

本文介绍了一个用Dart编写的颤振计数器应用程序,该应用程序使用了Flutter自带的块库(Block library)实现。通过该应用程序的介绍,我们了解了如何使用Flutter的块库(Block library)来实现代码的重用以及提高代码的可读性和可维护性。