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

相关推荐
chushiyunen1 天前
npy文件笔记
笔记·python
念恒123061 天前
Python(列表入门)
python·学习
Yang-Never1 天前
Git -> Git Worktree 工作树
android·开发语言·git·android studio
zjy277771 天前
Go语言怎么用GitHub Actions_Go语言GitHub Actions教程【基础】
jvm·数据库·python
2301_782040451 天前
如何实现SQL用户行为追踪_通过触发器记录操作明细
jvm·数据库·python
xingpanvip1 天前
星盘接口开发文档:日运语料接口指南
android·开发语言·前端·css·php·lua
hrhcode1 天前
【LangGraph】五.人机协作:审批和中断
python·ai·langchain·agent·langgraph
王杨游戏养站系统1 天前
王杨游戏蜘蛛养站系统:提交百度站长工具平台教程!
游戏·百度·游戏下载站养站系统·游戏养站系统
dFObBIMmai1 天前
golang如何实现数据导入进度跟踪_golang数据导入进度跟踪实现教程
jvm·数据库·python
步辞1 天前
golang如何实现即时通讯IM系统_golang即时通讯IM系统实现方案
jvm·数据库·python