Flutter for OpenHarmony 万能游戏库App实战 - 笑话生成器实现

笑话生成器是一个有趣的娱乐功能。这篇文章我们来实现一个笑话生成器,包括分类选择、笑话加载、答案揭晓、以及复制功能。通过这个功能,我们能展示如何构建一个简单的内容展示应用

页面的基本结构

JokesScreen是笑话生成器的主页面:

dart 复制代码
class JokesScreen extends StatefulWidget {
  const JokesScreen({super.key});

  @override
  State<JokesScreen> createState() => _JokesScreenState();
}

class _JokesScreenState extends State<JokesScreen> {
  final JokeApi _api = JokeApi();
  Map<String, dynamic>? _joke;
  bool _isLoading = false;
  String _category = 'Any';
  bool _showPunchline = false;

  final List<Map<String, dynamic>> _categories = [
    {'name': 'Any', 'label': '全部', 'icon': Icons.shuffle},
    {'name': 'Programming', 'label': '编程', 'icon': Icons.code},
    {'name': 'Misc', 'label': '杂项', 'icon': Icons.category},
    {'name': 'Pun', 'label': '双关语', 'icon': Icons.text_fields},
    {'name': 'Spooky', 'label': '恐怖', 'icon': Icons.nightlight},
    {'name': 'Christmas', 'label': '圣诞', 'icon': Icons.ac_unit},
  ];

_joke存储当前笑话。
_category存储选择的分类。
_showPunchline表示是否显示答案。
_categories定义了所有可用的分类。

笑话加载

_loadJoke方法加载笑话:

dart 复制代码
  Future<void> _loadJoke() async {
    setState(() {
      _isLoading = true;
      _showPunchline = false;
    });
    try {
      final data = await _api.getJoke(category: _category);
      setState(() {
        _joke = data;
        _isLoading = false;
      });
    } catch (e) {
      setState(() => _isLoading = false);
    }
  }

调用API获取笑话。
重置_showPunchline,这样新笑话的答案不会立即显示。

复制功能

_copyJoke方法复制笑话到剪贴板:

dart 复制代码
  void _copyJoke() {
    if (_joke == null) return;
    String text;
    if (_joke!['type'] == 'single') {
      text = _joke!['joke'] ?? '';
    } else {
      text = '${_joke!['setup']}\n\n${_joke!['delivery']}';
    }
    Clipboard.setData(ClipboardData(text: text));
    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('已复制到剪贴板')));
  }

根据笑话类型(单行或两行)组织文本。
使用Clipboard.setData复制到剪贴板。

分类选择

分类用水平的ListView展示:

dart 复制代码
          SizedBox(
            height: 100,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              padding: const EdgeInsets.all(12),
              itemCount: _categories.length,
              itemBuilder: (context, index) {
                final cat = _categories[index];
                final isSelected = _category == cat['name'];
                return Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 4),
                  child: InkWell(
                    onTap: () {
                      setState(() => _category = cat['name']);
                      _loadJoke();
                    },
                    borderRadius: BorderRadius.circular(12),
                    child: Container(
                      width: 80,
                      padding: const EdgeInsets.all(8),
                      decoration: BoxDecoration(
                        color: isSelected ? Theme.of(context).colorScheme.primaryContainer : null,
                        borderRadius: BorderRadius.circular(12),
                        border: Border.all(color: isSelected ? Theme.of(context).colorScheme.primary : Colors.grey.withOpacity(0.3)),
                      ),
                      child: Column(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: [
                          Icon(cat['icon'], color: isSelected ? Theme.of(context).colorScheme.primary : Colors.grey),
                          const SizedBox(height: 4),
                          Text(cat['label'], style: TextStyle(fontSize: 12, color: isSelected ? Theme.of(context).colorScheme.primary : Colors.grey)),
                        ],
                      ),
                    ),
                  ),
                );
              },
            ),
          ),

每个分类用一个容器展示,包含图标和标签。
选中的分类用primaryContainer颜色高亮。

笑话展示

笑话用Card展示:

dart 复制代码
                    Card(
                      child: Padding(
                        padding: const EdgeInsets.all(24),
                        child: Column(
                          children: [
                            Icon(
                              _joke!['type'] == 'single' ? Icons.format_quote : Icons.question_answer,
                              size: 48,
                              color: Theme.of(context).colorScheme.primary,
                            ),
                            const SizedBox(height: 20),
                            if (_joke!['type'] == 'single')
                              Text(_joke!['joke'] ?? '', style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center)
                            else ...[
                              Text(_joke!['setup'] ?? '', style: Theme.of(context).textTheme.titleLarge, textAlign: TextAlign.center),
                              const SizedBox(height: 20),
                              if (_showPunchline)
                                Text(_joke!['delivery'] ?? '', style: Theme.of(context).textTheme.titleMedium?.copyWith(color: Theme.of(context).colorScheme.primary, fontWeight: FontWeight.bold), textAlign: TextAlign.center)
                              else
                                OutlinedButton(
                                  onPressed: () => setState(() => _showPunchline = true),
                                  child: const Text('揭晓答案'),
                                ),
                            ],
                          ],
                        ),
                      ),
                    ),

单行笑话直接显示。
两行笑话先显示问题,然后显示"揭晓答案"按钮。
点击按钮后显示答案。

总结

这篇文章我们实现了一个笑话生成器。涉及到的知识点包括:

  • API集成 - 使用笑话API获取笑话
  • 分类管理 - 支持多个笑话分类
  • 交互设计 - 实现答案揭晓的交互
  • 剪贴板操作 - 复制笑话到剪贴板
  • UI设计 - 清晰地展示笑话内容

笑话生成器展示了如何构建一个简单的内容展示应用 。通过合理的UI设计和流畅的交互,我们能为用户提供一个有趣的娱乐体验


欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

相关推荐
程序媛徐师姐2 小时前
Python基于人脸识别的社区签到系统【附源码、文档说明】
python·人脸识别·python人脸识别·python社区签到系统·python人脸识别社区签到·人脸识别社区签到系统·社区签到系统
请叫我聪明鸭2 小时前
基于 marked.js 的扩展机制,创建一个自定义的块级容器扩展,让内容渲染为<div>标签而非默认的<p>标签
开发语言·前端·javascript·vue.js·ecmascript·marked·marked.js插件
deephub2 小时前
使用 tsfresh 和 AutoML 进行时间序列特征工程
人工智能·python·机器学习·特征工程·时间序列
2501_944526422 小时前
Flutter for OpenHarmony 万能游戏库App实战 - 21点游戏实现
android·javascript·flutter·游戏·harmonyos
0思必得02 小时前
[Web自动化] Selenium中Select元素操作方法
前端·python·selenium·自动化·html
Duang007_2 小时前
【万字学习总结】API设计与接口开发实战指南
开发语言·javascript·人工智能·python·学习
小北方城市网2 小时前
JVM 调优实战指南:从问题排查到参数优化
java·spring boot·python·rabbitmq·java-rabbitmq·数据库架构
Alex老夫子2 小时前
android room数据库增加字段注意事项
android·数据库
Java程序员威哥2 小时前
用Java玩转机器学习:协同过滤算法实战(比Python快3倍的工程实现)
java·开发语言·后端·python·算法·spring·机器学习