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

Flutter横向时间选择器如何禁止多选容器,仅支持单选功能?

要实现单选效果,只需要在每次点击时间项时,先把对应时间列表的所有选中状态重置为false,再更新当前点击项的选中状态即可,调整后的完整代码如下:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "custom time picker horizontal",
      home: TimePickerScreen(),
    );
  }
}

class TimePickerScreen extends StatefulWidget {
  @override
  _TimePickerScreenState createState() => _TimePickerScreenState();
}

class _TimePickerScreenState extends State<TimePickerScreen> {
  String selectedFromTime = " ";
  List<String> fromTimeList = ["0:00", "0:30", "1:00", "1:30", "2:00", "2:30", "3:00", "3:30", "4:00", "4:30", "5:00", "5:30", "6:00", "6:30"];
  List<bool> fromTimeListSelect = List.filled(14, false);

  String selectedToTime =" ";
  List<String> toTimeList = ["0:00", "0:30", "1:00", "1:30", "2:00", "2:30", "3:00", "3:30", "4:00", "4:30", "5:00", "5:30", "6:00", "6:30"];
  List<bool> toTimeListSelect = List.filled(14, false);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('custom time picker horizontal'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Divider(),
          fromTime(),
          Divider(),
          toTime(),
          Text('From : $selectedFromTime To : $selectedToTime'),
        ],
      ),
    );
  }

  Widget fromTime(){
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: fromTimeList.length,
        itemBuilder: (BuildContext context,int index){
          return GestureDetector(
            child: Container(
              padding: EdgeInsets.all(6),
              child: Center(
                child: Text(fromTimeList[index],
                  style: TextStyle(color: fromTimeListSelect[index] ? Colors.white : Colors.black ,fontSize: 16),)),
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: fromTimeListSelect[index] ? Colors.black : Colors.white,
              ),
            ),
            onTap: (){
              // 如需支持点击已选中项取消,可放开下方注释的判断逻辑
              // if(fromTimeListSelect[index]){
              //   fromTimeListSelect[index] = false;
              //   selectedFromTime = ' ';
              // }else{
                // 重置所有选中状态
                for (var i = 0; i < fromTimeListSelect.length; i++) {
                  fromTimeListSelect[i] = false;
                }
                fromTimeListSelect[index] = true;
                selectedFromTime = fromTimeList[index];
              // }
              setState(() {});
            },
          );
        },
      ),
    );
  }

  Widget toTime(){
    return Expanded(
      child: ListView.builder(
        shrinkWrap: true,
        scrollDirection: Axis.horizontal,
        itemCount: toTimeList.length,
        itemBuilder: (BuildContext context,int index){
          return GestureDetector(
            child: Container(
              padding: EdgeInsets.all(6),
              child: Center(
                child: Text(toTimeList[index],
                  style: TextStyle(color: toTimeListSelect[index] ? Colors.white : Colors.black ,fontSize: 16),)),
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: toTimeListSelect[index] ? Colors.black : Colors.white,
              ),
            ),
            onTap: (){
              // 如需支持点击已选中项取消,可放开下方注释的判断逻辑
              // if(toTimeListSelect[index]){
              //   toTimeListSelect[index] = false;
              //   selectedToTime = ' ';
              // }else{
                // 重置所有选中状态
                for (var i = 0; i < toTimeListSelect.length; i++) {
                  toTimeListSelect[i] = false;
                }
                toTimeListSelect[index] = true;
                selectedToTime = toTimeList[index];
              // }
              setState(() {});
            },
          );
        },
      ),
    );
  }
}

核心修改点说明:

  • 点击开始时间列表项时,先遍历fromTimeListSelect将所有值重置为false,再将当前点击项的状态设为true,保证同一时间仅能选中一个开始时间
  • 结束时间列表逻辑同理,保证仅能选中一个结束时间
  • 代码中预留了点击已选中项取消选择的逻辑,按需放开注释即可使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 20:18:03