You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter中实现类似Duolingo的选词组句功能?

实现Duolingo式单词拼接功能的优化方案

你当前用TextField实现的方案确实不够理想——输入框的编辑逻辑和Duolingo那种"点击单词填充到目标行、可随时移除调整"的交互不符,而且单词的复用、位置调整都会受限。这里给你一套更贴合需求的实现思路:

核心思路

  • 用两个列表分别维护待选单词和已选单词的状态
  • 目标句子区域用Wrap组件展示已选单词,每个单词支持点击移除
  • 待选单词区域用Wrap展示可点击的单词按钮,点击后将单词移至已选列表

完整实现代码

import 'package:flutter/material.dart';

class Screen6_1_3 extends StatefulWidget {
  const Screen6_1_3({super.key});

  @override
  State<Screen6_1_3> createState() => _Screen6_1_3State();
}

class _Screen6_1_3State extends State<Screen6_1_3> {
  // 待选单词列表
  final List<String> _availableWords = ["Bread", "I", "eat", "every", "morning"];
  // 已选单词列表(用来组成目标句子)
  final List<String> _selectedWords = [];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      appBar: AppBar(
        centerTitle: true,
        backgroundColor: Colors.blue,
        leading: GestureDetector(
          child: const Icon(Icons.close, color: Colors.white),
          onTap: () {
            Navigator.pushNamedAndRemoveUntil(context, "home", (route) => false);
          },
        ),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            // 目标句子展示区域
            Container(
              padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 16),
              decoration: BoxDecoration(
                color: const Color.fromARGB(255, 226, 226, 226),
                border: Border.all(color: const Color.fromARGB(255, 123, 123, 123), width: 2),
                borderRadius: BorderRadius.circular(10),
              ),
              child: _selectedWords.isEmpty
                  ? const Text("点击下方单词组成句子", style: TextStyle(color: Colors.grey))
                  : Wrap(
                      spacing: 8,
                      runSpacing: 8,
                      children: _selectedWords.map((word) {
                        return Chip(
                          label: Text(word),
                          onDeleted: () {
                            // 点击移除按钮,将单词放回待选列表
                            setState(() {
                              _selectedWords.remove(word);
                              _availableWords.add(word);
                            });
                          },
                        );
                      }).toList(),
                    ),
            ),
            const SizedBox(height: 32),
            // 待选单词按钮区域
            Wrap(
              spacing: 12,
              runSpacing: 12,
              children: _availableWords.map((word) {
                return ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.white,
                    foregroundColor: Colors.blue,
                    padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
                  ),
                  onPressed: () {
                    // 点击单词,移至已选列表
                    setState(() {
                      _availableWords.remove(word);
                      _selectedWords.add(word);
                    });
                  },
                  child: Text(word),
                );
              }).toList(),
            ),
          ],
        ),
      ),
    );
  }
}

方案优势

  1. 交互更贴合需求:完全模拟Duolingo的单词点击填充、移除调整逻辑,用户体验更直观
  2. 布局灵活:用Wrap组件自动适配不同屏幕宽度,单词过多时会自动换行
  3. 状态管理清晰:两个列表分别维护待选和已选状态,后续扩展排序、错误校验、单词拖拽等功能都很方便
  4. 可扩展性强:可以轻松添加比如"重置句子"、"检查答案"等功能,只需操作两个列表即可

内容的提问来源于stack exchange,提问作者Igor Boldyrev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 16:50:22