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

Flutter按钮输入值存储、展示与修改功能实现咨询

Flutter数字输入组件实现方案

以下是满足你所有需求的完整实现代码,附带关键逻辑的详细说明:

完整代码

import 'package:flutter/material.dart';
import 'package:flutter_grid_button/flutter_grid_button.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '数字输入Demo',
      theme: ThemeData(primarySwatch: Colors.purple),
      home: const NumberInputPage(),
    );
  }
}

class NumberInputPage extends StatefulWidget {
  const NumberInputPage({Key? key}) : super(key: key);

  @override
  State<NumberInputPage> createState() => _NumberInputPageState();
}

class _NumberInputPageState extends State<NumberInputPage> {
  // 控制最大输入数量(可在1-12之间调整)
  final int maxInputLength = 6;
  // 存储输入的数字列表,按输入顺序保存
  List<String> inputNumbers = [];
  // 当前修改的索引(-1表示无修改状态)
  int editingIndex = -1;

  // 统一处理按钮点击事件
  void handleButtonPress(dynamic val) {
    setState(() {
      switch (val) {
        case 'Back':
          // 退格逻辑:修改状态下删除当前项,非修改状态删除最后一项
          if (editingIndex != -1) {
            inputNumbers.removeAt(editingIndex);
            editingIndex = -1;
          } else if (inputNumbers.isNotEmpty) {
            inputNumbers.removeLast();
          }
          break;
        case 'Next':
          // 触发数据库存储操作
          _saveToDatabase();
          break;
        case 'X':
          // 取消修改状态
          editingIndex = -1;
          break;
        default:
          // 数字输入逻辑:修改状态替换对应位置值,非修改状态新增(不超过最大数量)
          if (editingIndex != -1) {
            inputNumbers[editingIndex] = val.toString();
            editingIndex = -1;
          } else {
            if (inputNumbers.length < maxInputLength) {
              inputNumbers.add(val.toString());
            }
          }
          break;
      }
    });
  }

  // 数据库存储逻辑(替换为你的实际数据库实现)
  void _saveToDatabase() {
    if (inputNumbers.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('请输入数字后再提交')),
      );
      return;
    }
    // 示例:打印存储内容,实际项目中替换为sqflite/Firebase等数据库操作
    print('存入数据库的数字:${inputNumbers.join(', ')}');
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(content: Text('已成功存储 ${inputNumbers.length} 个数字')),
    );
  }

  // 构建输入展示区域,支持点击修改
  Widget buildInputDisplay() {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: List.generate(maxInputLength, (index) {
        final hasValue = index < inputNumbers.length;
        return GestureDetector(
          onTap: hasValue ? () => setState(() => editingIndex = index) : null,
          child: Container(
            width: 50,
            height: 50,
            margin: const EdgeInsets.symmetric(horizontal: 8),
            decoration: BoxDecoration(
              border: Border.all(
                color: editingIndex == index ? Colors.orange : Colors.grey,
                width: editingIndex == index ? 2 : 1,
              ),
              borderRadius: BorderRadius.circular(8),
            ),
            child: Center(
              child: Text(
                hasValue ? inputNumbers[index] : '',
                style: const TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
              ),
            ),
          ),
        );
      }),
    );
  }

  @override
  Widget build(BuildContext context) {
    const textStyle = TextStyle(fontSize: 26);
    return Scaffold(
      appBar: AppBar(title: const Text('数字输入')),
      body: Padding(
        padding: const EdgeInsets.only(top: 30, left: 16, right: 16),
        child: Column(
          children: [
            // 输入数字展示区域
            buildInputDisplay(),
            const SizedBox(height: 30),
            // 输入状态提示
            Text(
              editingIndex != -1
                  ? '正在修改第 ${editingIndex + 1} 位数字'
                  : '已输入 ${inputNumbers.length}/$maxInputLength 个数字',
              style: const TextStyle(fontSize: 16),
            ),
            const SizedBox(height: 30),
            // 数字键盘
            Expanded(
              child: GridButton(
                textStyle: textStyle,
                borderColor: Colors.grey[300],
                borderWidth: 2,
                onPressed: handleButtonPress,
                items: [
                  [
                    const GridButtonItem(title: "9"),
                    const GridButtonItem(title: "10"),
                    const GridButtonItem(title: "X"),
                  ],
                  [
                    const GridButtonItem(title: "6"),
                    const GridButtonItem(title: "7"),
                    const GridButtonItem(title: "8"),
                  ],
                  [
                    const GridButtonItem(title: "3"),
                    const GridButtonItem(title: "4"),
                    const GridButtonItem(title: "5"),
                  ],
                  [
                    const GridButtonItem(title: "0"),
                    const GridButtonItem(
                      title: "1",
                      color: Colors.white,
                      textStyle: TextStyle(
                          fontSize: 26,
                          color: Colors.black,
                          fontWeight: FontWeight.bold),
                    ),
                    const GridButtonItem(
                      title: "2",
                      color: Colors.white,
                      textStyle: TextStyle(
                          fontSize: 26,
                          color: Colors.black,
                          fontWeight: FontWeight.bold),
                    ),
                  ],
                  [],
                  [
                    const GridButtonItem(
                      title: "Back",
                      color: Colors.blue[900],
                      textStyle: TextStyle(
                          fontSize: 26,
                          color: Colors.black,
                          fontWeight: FontWeight.bold),
                    ),
                    const GridButtonItem(
                      title: "Next",
                      color: Colors.deepOrangeAccent,
                      textStyle: TextStyle(
                          fontSize: 26,
                          color: Colors.black,
                          fontWeight: FontWeight.bold),
                    ),
                  ]
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }
}

关键功能实现说明

1. 数字输入与顺序展示

  • 用inputNumbers列表按点击顺序存储输入的数字
  • buildInputDisplay生成固定数量的输入框(数量由maxInputLength控制),已输入数字实时展示,未输入位置为空

2. 输入数量控制

  • 通过maxInputLength变量设置允许输入的最大数字数(范围1-12),新增数字时判断列表长度,超过限制则不允许添加

3. 已输入数字修改

  • 点击已输入的数字框进入修改状态(通过editingIndex标记当前修改位置)
  • 修改状态下点击数字按钮会替换对应位置的数值,点击X可取消修改
  • Back按钮在修改状态下删除当前选中项,非修改状态下删除最后一项

4. Next按钮存储数据库

  • _saveToDatabase方法封装存储逻辑,你可以替换为实际的数据库操作(如sqflite插入数据、Firebase云存储等)
  • 存储前会校验输入是否为空,避免无效提交

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 14:15:44