Flutter教程StreamBuilder与AnimatedBuilder结合打字游戏

我在用Flutter开发一个打字游戏,想结合StreamBuilder和AnimatedBuilder来实现实时更新分数和动画效果。目前遇到几个问题:

  1. 如何正确设置StreamBuilder的stream参数,让它能实时接收游戏分数变化?每次分数更新时,UI似乎没有立即响应。
  2. AnimatedBuilder在使用时,如何与StreamBuilder配合?动画效果总是卡顿,不知道是不是重建Widget太频繁导致的。
  3. 有没有更高效的写法?现在感觉代码结构有点乱,两个Builder嵌套在一起显得很臃肿。

希望有经验的朋友能分享一下最佳实践,或者提供一个简洁的实现示例!


更多关于Flutter教程StreamBuilder与AnimatedBuilder结合打字游戏的实战教程也可以访问 https://www.itying.com/category-92-b0.html

3 回复
  1. StreamBuilder:监听数据流,实时更新UI。创建一个Stream<int>用于生成随机字符流。
final _charStream = Stream.periodic(Duration(seconds: 1), (i) => i);
  1. AnimatedBuilder:实现动画效果。比如让字符从大变小。
int _currentCharIndex = 0;
@override
Widget build(BuildContext context) {
  return StreamBuilder<int>(
    stream: _charStream,
    builder: (context, snapshot) {
      if (!snapshot.hasData) return CircularProgressIndicator();
      final char = 'A' + snapshot.data! % 26; // 生成'A'-'Z'
      return AnimatedBuilder(
        animation: AlwaysStoppedAnimation(snapshot.data),
        builder: (_, __) => Text(
          String.fromCharCode(char),
          style: TextStyle(fontSize: 100 - snapshot.data! * 5),
        ),
      );
    },
  );
}
  1. 打字游戏逻辑:监听键盘输入并与当前字符对比。
TextEditingController _controller = TextEditingController();

void _onKeyPress(String key) {
  if (key == String.fromCharCode(char)) {
    setState(() {
      _currentCharIndex++;
    });
  } else {
    print("错误");
  }
}

FocusNode _focusNode = FocusNode();
@override
void initState() {
  super.initState();
  _focusNode.requestFocus();
}

这样就实现了结合StreamBuilderAnimatedBuilder的打字游戏。

更多关于Flutter教程StreamBuilder与AnimatedBuilder结合打字游戏的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


好的!先用Stream生成字符流,用StreamBuilder监听,显示字符;再用AnimatedBuilder实现动画效果。以下是简单示例:

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

void main() => runApp(TypingGame());

class TypingGame extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('打字游戏')),
        body: TypingGameStateful(),
      ),
    );
  }
}

class TypingGameStateful extends StatefulWidget {
  @override
  _TypingGameStateful createState() => _TypingGameStateful();
}

class _TypingGameStateful extends State<TypingGameStateful> {
  final StreamController<String> _streamController = StreamController<String>();
  String text = '';

  @override
  void dispose() {
    _streamController.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        StreamBuilder<String>(
          stream: _streamController.stream,
          builder: (context, snapshot) {
            return AnimatedBuilder(
              animation: AlwaysStoppedAnimation(snapshot.data ?? ''),
              builder: (_, __) => Text(text, style: TextStyle(fontSize: 40)),
            );
          },
        ),
        TextField(onChanged: (val) {
          setState(() => text = val);
        }),
        ElevatedButton(onPressed: () {
          _streamController.add('${DateTime.now().millisecondsSinceEpoch}');
        }, child: Text('刷新'))
      ],
    );
  }
}

运行时点击“刷新”按钮,StreamBuilder监听到新数据后,AnimatedBuilder会触发动画更新文字。

在Flutter中,结合StreamBuilder和AnimatedBuilder可以创建动态的打字游戏效果。StreamBuilder用于处理文本流数据,AnimatedBuilder用于实现动画效果。以下是实现打字游戏的核心代码示例:

import 'package:flutter/material.dart';

class TypingGame extends StatefulWidget {
  @override
  _TypingGameState createState() => _TypingGameState();
}

class _TypingGameState extends State<TypingGame> with SingleTickerProviderStateMixin {
  final Stream<String> _textStream = Stream<String>.periodic(
    Duration(milliseconds: 100),
    (x) => "Flutter打字游戏".substring(0, x + 1),
  ).take("Flutter打字游戏".length);

  AnimationController _controller;
  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: Duration(seconds: 1),
      vsync: this,
    )..repeat(reverse: true);
    _animation = Tween(begin: 0.0, end: 1.0).animate(_controller);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            StreamBuilder<String>(
              stream: _textStream,
              builder: (context, snapshot) {
                if (!snapshot.hasData) {
                  return Text("准备开始...");
                }
                return AnimatedBuilder(
                  animation: _animation,
                  builder: (context, child) {
                    return Opacity(
                      opacity: _animation.value,
                      child: Text(
                        snapshot.data,
                        style: TextStyle(fontSize: 24),
                      ),
                    );
                  },
                );
              },
            ),
          ],
        ),
      ),
    );
  }

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

这个示例展示了:

  1. 使用StreamBuilder逐步显示文本
  2. 通过AnimatedBuilder添加淡入淡出动画效果
  3. 结合动画控制器控制动画行为

你可以扩展这个基础功能,添加用户输入验证、得分系统等来完善游戏体验。

回到顶部