Flutter实现5个可转换为文本输入的加号按钮需求
Flutter实现动态加号转分隔文本组件方案
核心实现思路
通过状态管理控制每个组件的三种状态:初始加号按钮、待输入下划线、已输入分隔文本,结合Row+Expanded实现等宽布局,配合Dialog完成输入交互。
完整代码实现
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Dynamic Input Demo', theme: ThemeData(primarySwatch: Colors.blue), home: const DynamicInputScreen(), ); } } class DynamicInputScreen extends StatefulWidget { const DynamicInputScreen({super.key}); @override State<DynamicInputScreen> createState() => _DynamicInputScreenState(); } class _DynamicInputScreenState extends State<DynamicInputScreen> { // 维护5个项的状态:0=初始加号,1=待输入(下划线),2=已输入完成 final List<Map<String, dynamic>> _items = List.generate(5, (index) => { 'state': 0, 'text': '', }); void _showInputDialog(int index) { final controller = TextEditingController(); showDialog( context: context, builder: (_) => AlertDialog( title: const Text('输入内容'), content: TextField( controller: controller, decoration: const InputDecoration(hintText: '请输入文本'), ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('取消'), ), TextButton( onPressed: () { if (controller.text.trim().isNotEmpty) { setState(() { _items[index]['state'] = 2; _items[index]['text'] = controller.text.trim(); }); Navigator.pop(context); } }, child: const Text('添加'), ), ], ), ); } // 生成带分隔的文本(如e_x_a_m_p_l_e) Widget _buildSeparatedText(String text) { return Text( text.split('').join('_'), style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ); } Widget _buildItem(int index) { final item = _items[index]; switch (item['state']) { case 0: return Expanded( child: IconButton( icon: const Icon(Icons.add, size: 24), onPressed: () { setState(() => item['state'] = 1); _showInputDialog(index); }, ), ); case 1: return Expanded( child: Container( height: 24, alignment: Alignment.center, decoration: const BoxDecoration( border: Border(bottom: BorderSide(color: Colors.black, width: 2)), ), ), ); case 2: return Expanded( child: Center(child: _buildSeparatedText(item['text'])), ); default: return const SizedBox(); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('动态输入组件')), body: Padding( padding: const EdgeInsets.all(16), child: Row( children: List.generate(5, (index) => _buildItem(index)), ), ), ); } }
关键细节说明
- 等宽布局:每个子组件用
Expanded包裹,自动平分Row宽度,确保5个组件占满屏幕一行。 - 状态切换逻辑:
- 初始状态(0):显示加号按钮,点击后立即切换为下划线状态(1)并弹出输入Dialog。
- 待输入状态(1):显示下划线容器,等待用户在Dialog中输入内容。
- 完成状态(2):将输入文本转为字符间带下划线的格式展示。
- 输入交互:Dialog中校验输入不为空后,更新对应项的状态和文本,触发UI重建。
- 分隔文本生成:通过
split('').join('_')快速将输入文本转为字符间带分隔线的格式,如需前后也加下划线,可修改为'_${text.split('').join('_')}_'。
内容的提问来源于stack exchange,提问作者Promaster
相关产品推荐
相关产品推荐

