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

相关推荐
鸽芷咕7 分钟前
为什么越来越多开发者转向 CANN 仓库中的 Python 自动化方案?
python·microsoft·自动化·cann
秋邱8 分钟前
用 Python 写出 C++ 的性能?用CANN中PyPTO 算子开发硬核上手指南
开发语言·c++·python
我的offer在哪里20 分钟前
用 Unity 从 0 做一个「可以玩的」游戏,需要哪些步骤和流程
游戏·unity·游戏引擎
lpruoyu25 分钟前
【Android第一行代码学习笔记】Android架构_四大组件_权限_持久化_通知_异步_服务
android·笔记·学习
晚烛42 分钟前
CANN + 物理信息神经网络(PINNs):求解偏微分方程的新范式
javascript·人工智能·flutter·html·零售
串流游戏联盟42 分钟前
启程!手机也能邂逅暖暖万相奇观
游戏·远程工作
wazmlp0018873691 小时前
python第三次作业
开发语言·python
一起养小猫1 小时前
Flutter for OpenHarmony 实战:扫雷游戏完整开发指南
flutter·harmonyos
深蓝电商API1 小时前
住宅代理与数据中心代理在爬虫中的选择
爬虫·python
独自破碎E1 小时前
【BISHI15】小红的夹吃棋
android·java·开发语言