繁体   English   中英

在 Flutter 中调用 showTimePicker() 时如何使用 24 小时制?

[英]How to use 24 hour clock when invoking showTimePicker() in Flutter?

当我在 Fluter 中调用 showTimePicker() 方法时,它会显示一个 12 小时制的选择器(使用 AM 和 PM 时段)。 此外,当我在 TimeOfDay 对象上调用 format() 方法时,它会在 12 小时系统中返回值。

如何将其更改为 24 小时制? 我发现我需要更改 Window 类中的 alwaysUse24HourFormat 属性,但我不知道该怎么做。

有人可以帮我吗? 预先感谢您的回答。

编辑:代码如下所示:

    Future<Null> _selectTime(BuildContext context) async {
    final TimeOfDay response = await showTimePicker(
      context: context,
      initialTime: pickedTime,
    );
    if (response != null && response != pickedTime) {
      setState(() {
        pickedTime = response;
      });
    }
  } 

edit2:我只在 Android 上试过这个。

在阅读此答案之前,您需要了解 MediaQuery.of() 的工作原理。 本质上,任何给定页面中都有一个小部件树。 每个小部件都有一个Context ,您可以将其视为树中的一个节点。 当您调用 MediaQuery.of(context) 时,它基本上会向上跟踪树,直到找到(或未找到)一个 MediaQuery 小部件,然后返回与该小部件关联的数据。

你想做的事情是可能的,但你必须稍微小心你如何做。 请参阅下面的最小代码示例:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      builder: (context, child) =>
          MediaQuery(data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true), child: child),
      home: new Container(
        color: Colors.white,
        child: Center(
          child: Builder(
            builder: (context) => FlatButton(
                  onPressed: () => showTimePicker(context: context, initialTime: TimeOfDay.now()),
                  child: Text("Show Time Picker"),
                ),
          ),
        ),
      ),
    );
  }
}

这里有几点需要注意。 首先是我在 MaterialApp 的构建器中从旧的 MediaQueryData 创建一个新的 MediaQueryData。 这是因为您无法修改 MaterialQueryData 的属性。

第二个是我用新的 MediaQuery 将孩子包装在 MaterialApp 的构建器中。 这是必要的,以便导航器中的所有“页面”(在此实例中是材料应用程序的一部分)使用 MediaQuery.of() 读取这个新的 MediaQueryData。

第三个是我在 FlatButton 周围使用了一个 Builder。 如果我不这样做,它将使用的上下文将是 MyApp 的上下文,而不是 MaterialApp 下的上下文。 如果您创建了自己的课程来附上“页面”,那就没有必要了。

MediaQuery 必须放在现在的位置,因为如果您将它放在“页面”中(容器下的任何位置),TimePicker 小部件实际上不会读取它。 这是因为 TimePicker 实际上将自己作为导航堆栈的顶部元素插入,该元素位于 Navigator(和 MaterialApp)下,而不是嵌入在您的页面下。 如果不是这种情况,那么使用时间选择器会更加困难。

我不知道我解释得很好,所以这里有一个图表:

MyApp  <------ Context (the one that would have been used without the builder)
  MaterialApp
    MediaQuery (from flutter)
      MediaQuery copy (that was made in the builder)
        Navigator (implicit - built as part of MaterialApp)
         |- Container
         |    Center
         |      Builder     <----\ Context (used to showTimePicker)
         |        FlatButton ----/ 
         \- TimePicker

考虑到@rmtmckenzie 的回答,您实际上可以简化他告诉您的内容。 您不需要在MyApp上下文中设置alwaysUse24HourFormat: true

这会成功的

void inputTimeSelect() async {
    final TimeOfDay picked = await showTimePicker(
      context: context,
      initialTime: TimeOfDay.now(),
      builder: (BuildContext context, Widget child) {
        return MediaQuery(
          data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
          child: child,
        );
      },
    );
}

小部件树可以是您想要的任何东西。

上面的答案对我不起作用。 也许对于新的颤振或飞镖版本。 我通过 -

 final newTime = await showTimePicker(
        context: context,
        initialTime: TimeOfDay.now(),
        builder: (context, child) {
          return MediaQuery(
            data: MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
          child: child ?? Container(),
          );
        },
      );

如果有人使用flutter_form_builder,这里有一个例子:

FormBuilderDateTimePicker(
          name: field.attribute,
          inputType: InputType.both,
          decoration: InputDecoration(labelText: field.labelText),
          alwaysUse24HourFormat: true,
          transitionBuilder: (BuildContext context, Widget? child) {
            return MediaQuery(
              data:
                  MediaQuery.of(context).copyWith(alwaysUse24HourFormat: true),
              child: child ?? Container(),
            );
          },
        );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM