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

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)),
        ),
      ),
    );
  }
}

关键细节说明

  1. 等宽布局:每个子组件用Expanded包裹,自动平分Row宽度,确保5个组件占满屏幕一行。
  2. 状态切换逻辑:
    • 初始状态(0):显示加号按钮,点击后立即切换为下划线状态(1)并弹出输入Dialog。
    • 待输入状态(1):显示下划线容器,等待用户在Dialog中输入内容。
    • 完成状态(2):将输入文本转为字符间带下划线的格式展示。
  3. 输入交互:Dialog中校验输入不为空后,更新对应项的状态和文本,触发UI重建。
  4. 分隔文本生成:通过split('').join('_')快速将输入文本转为字符间带分隔线的格式,如需前后也加下划线,可修改为'_${text.split('').join('_')}_'。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 22:33:27