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

Flutter ListView Builder实现单SwitchListTile选中限制咨询

实现同一时间仅一行Switch为选中状态的方案

核心思路

无需维护布尔值列表,改用单个变量记录当前选中的行索引,既简化状态管理,又天然保证同一时间只有一行处于选中状态。

具体修改步骤

  1. 替换状态变量:移除原flags列表,新增int _selectedIndex变量,初始值设为-1(代表无任何行被选中)。
  2. 简化添加逻辑:添加新行时仅维护names列表,无需再同步更新布尔值列表。
  3. 修复删除时的索引异常:删除行时,若被删除的是当前选中行,或删除行的索引在选中行之前,同步调整_selectedIndex,避免索引越界。
  4. 更新Switch状态绑定:每个Switch的value改为判断当前行索引是否等于_selectedIndex;点击开关时,将_selectedIndex设为当前行索引(开启时)或重置为-1(关闭时)。

修改后的完整代码

import 'package:flutter/material.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final List<String> names = <String>[];
  TextEditingController mc = TextEditingController();
  // 记录当前选中的行索引,-1表示无选中
  int _selectedIndex = -1;

  addItemToList() {
    setState(() {
      if (mc.text.isNotEmpty) {
        names.add(mc.text);
      }
    });
  }

  deleteItemFromList() {
    setState(() {
      if (names.isNotEmpty) {
        // 处理删除后的选中索引逻辑
        if (_selectedIndex == names.length - 1) {
          _selectedIndex = -1;
        } else if (_selectedIndex != -1) {
          _selectedIndex -= 1;
        }
        names.removeLast();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    Widget space = const SizedBox(height: 5);
    Widget myinput = TextField(
        controller: mc,
        decoration:
            InputDecoration(border: OutlineInputBorder(), labelText: 'Name'));
    Widget btnAdd =
        ElevatedButton(onPressed: addItemToList, child: const Text('Add'));
    Widget btnRemove =
        ElevatedButton(onPressed: deleteItemFromList, child: const Text('Remove'));
    Widget mylist = SizedBox(
      width: 800,
      height: 500,
      child: ListView.builder(
        shrinkWrap: true,
        itemCount: names.length,
        itemBuilder: (BuildContext context, int index) {
          return SwitchListTile(
            title: Text(names[index], style: const TextStyle(fontSize: 11)),
            value: index == _selectedIndex,
            onChanged: (bool value) {
              setState(() {
                _selectedIndex = value ? index : -1;
              });
            },
          );
        },
      ),
    );

    return MaterialApp(
      home: Scaffold(
        resizeToAvoidBottomInset: false,
        body: SingleChildScrollView(
          scrollDirection: Axis.vertical,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Container(
                padding: const EdgeInsets.all(5),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                  children: <Widget>[
                    space,
                    myinput,
                    space,
                    btnAdd,
                    space,
                    btnRemove,
                    space,
                    mylist,
                    space
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

额外优化说明

  • 移除冗余的SingleChildScrollView嵌套,避免多重滚动冲突
  • 用const修饰常量Widget,提升渲染性能
  • 增加删除操作时的空列表判断,防止报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:07:45