【问题标题】:DatePicker flutter change display date formatDatePicker颤动改变显示日期格式
【发布时间】:2020-11-20 07:46:18
【问题描述】:

如何更改显示日期的格式?

我在这里找不到日期格式字段。这是我的示例代码:

_onDateChanging(BuildContext context, DateKind dateKind,
      FlightSearchQueryProvider searchProvider) {
    ...
    showDatePicker(
      context: context,
      initialDate: DateTime.tryParse(date),
      firstDate: DateTime.now(),
      lastDate: DateTime(2050),
      helpText: helperText,
      cancelText: cancelText,
      confirmText: confirmText,
      fieldHintText: hintText,
      errorFormatText: getTranslation(context, 'invalid_date_value'),
      errorInvalidText: getTranslation(context, 'invalid_date_value'),
    ).then((value) {
      if (value != null) {
        if (dateKind == DateKind.Departure) {
          searchProvider.updateDepartureDate(value.toString());
        } else {
          searchProvider.updateArrivalDate(value.toString());
        }
      }
    });
  }

谢谢!

【问题讨论】:

  • 您可能需要先发布一些代码

标签: flutter dart flutter-layout


【解决方案1】:

.
我发现最简单的方法是重写LocalizationsDelegate

showDatePicker 方法使用MaterialLocalizations.of(context); 来格式化您需要的DatePickerHeader dateText。

要更改格式,您需要重写showDatePicker 方法或添加您自己的LocalizationsDelegate。第二种方式要快得多。

添加自定义LocalizationsDelegate:

MaterialApp(
 localizationsDelegates: [
   CustomMaterialLocalizationsDelegate(),
  ],
..
)

要创建CustomMaterialLocalizationsDelegate,您可以复制_MaterialLocalizationsDelegate(链接到您可以在GlobalMaterialLocalizations.delegate 中找到的委托)

接下来您需要更改mediumDateFormat 变量。

这可能不是一个完美的解决方案,因为您更改了整个 MaterialApp 的格式,但如果您不想创建自己的 DatePicker,这可能是唯一的解决方案。

工作示例:

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart' as intl;
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/date_symbols.dart' as intl;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        CustomMaterialLocalizationsDelegate(), // GlobalMaterialLocalizations.delegate,
      ],
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: SafeArea(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Test(),
    );
  }
}

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

  _showDialog(BuildContext context) {
    return () => showDatePicker(
          context: context,
          initialDate: DateTime.now(),
          firstDate: DateTime.now(),
          lastDate: DateTime(2050),
        ).then(print);
  }

  @override
  Widget build(BuildContext context) {
    final localizations = MaterialLocalizations.of(context);
    return Center(
      child: RaisedButton(
        child: Text(
            'showDialog: ${localizations.formatMediumDate(DateTime.now())}'),
        onPressed: _showDialog(context),
      ),
    );
  }
}


class CustomMaterialLocalizationsDelegate
    extends LocalizationsDelegate<MaterialLocalizations> {
  const CustomMaterialLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) =>
      kMaterialSupportedLanguages.contains(locale.languageCode);

  static final Map<Locale, Future<MaterialLocalizations>> _loadedTranslations =
      <Locale, Future<MaterialLocalizations>>{};

  @override
  Future<MaterialLocalizations> load(Locale locale) {
    assert(isSupported(locale));
    return _loadedTranslations.putIfAbsent(locale, () {
      // util.loadDateIntlDataIfNotLoaded();

      final String localeName =
          intl.Intl.canonicalizedLocale(locale.toString());
      assert(
        locale.toString() == localeName,
        'Flutter does not support the non-standard locale form $locale (which '
        'might be $localeName',
      );

      intl.DateFormat fullYearFormat;
      intl.DateFormat compactDateFormat;
      intl.DateFormat shortDateFormat;
      intl.DateFormat mediumDateFormat;
      intl.DateFormat longDateFormat;
      intl.DateFormat yearMonthFormat;
      intl.DateFormat shortMonthDayFormat;
      if (intl.DateFormat.localeExists(localeName)) {
        fullYearFormat = intl.DateFormat.y(localeName);
        compactDateFormat = intl.DateFormat.yMd(localeName);
        shortDateFormat = intl.DateFormat.yMMMd(localeName);
        // mediumDateFormat = intl.DateFormat.MMMEd(localeName);
        longDateFormat = intl.DateFormat.yMMMMEEEEd(localeName);
        yearMonthFormat = intl.DateFormat.yMMMM(localeName);
        shortMonthDayFormat = intl.DateFormat.MMMd(localeName);
      } else if (intl.DateFormat.localeExists(locale.languageCode)) {
        fullYearFormat = intl.DateFormat.y(locale.languageCode);
        compactDateFormat = intl.DateFormat.yMd(locale.languageCode);
        shortDateFormat = intl.DateFormat.yMMMd(locale.languageCode);
        // mediumDateFormat = intl.DateFormat.MMMEd(locale.languageCode);
        longDateFormat = intl.DateFormat.yMMMMEEEEd(locale.languageCode);
        yearMonthFormat = intl.DateFormat.yMMMM(locale.languageCode);
        shortMonthDayFormat = intl.DateFormat.MMMd(locale.languageCode);
      } else {
        fullYearFormat = intl.DateFormat.y();
        compactDateFormat = intl.DateFormat.yMd();
        shortDateFormat = intl.DateFormat.yMMMd();
        // mediumDateFormat = intl.DateFormat.MMMEd();
        longDateFormat = intl.DateFormat.yMMMMEEEEd();
        yearMonthFormat = intl.DateFormat.yMMMM();
        shortMonthDayFormat = intl.DateFormat.MMMd();
      }

      mediumDateFormat = intl.DateFormat.y(); // <- added

      intl.NumberFormat decimalFormat;
      intl.NumberFormat twoDigitZeroPaddedFormat;
      if (intl.NumberFormat.localeExists(localeName)) {
        decimalFormat = intl.NumberFormat.decimalPattern(localeName);
        twoDigitZeroPaddedFormat = intl.NumberFormat('00', localeName);
      } else if (intl.NumberFormat.localeExists(locale.languageCode)) {
        decimalFormat = intl.NumberFormat.decimalPattern(locale.languageCode);
        twoDigitZeroPaddedFormat = intl.NumberFormat('00', locale.languageCode);
      } else {
        decimalFormat = intl.NumberFormat.decimalPattern();
        twoDigitZeroPaddedFormat = intl.NumberFormat('00');
      }

      return SynchronousFuture<MaterialLocalizations>(getMaterialTranslation(
        locale,
        fullYearFormat,
        compactDateFormat,
        shortDateFormat,
        mediumDateFormat,
        longDateFormat,
        yearMonthFormat,
        shortMonthDayFormat,
        decimalFormat,
        twoDigitZeroPaddedFormat,
      ));
    });
  }

  @override
  bool shouldReload(CustomMaterialLocalizationsDelegate old) => false;

  @override
  String toString() =>
      'GlobalMaterialLocalizations.delegate(${kMaterialSupportedLanguages.length} locales)';
}



更新。
我注意到你来自土库曼斯坦。 也许您要更改Local,对话框中有此选项。

但不幸的是,我没有资助土库曼人,这是俄罗斯人。

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: SafeArea(
          child: MyHomePage(),
        ),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Test(),
    );
  }
}

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

  _showDialog(BuildContext context) {
    return () => showDatePicker(
          locale: Locale('ru', 'ru_Ru'),
          context: context,
          initialDate: DateTime.now(),
          firstDate: DateTime.now(),
          lastDate: DateTime(2050),
        ).then(print);
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: Text('showDialog'),
        onPressed: _showDialog(context),
      ),
    );
  }
}

【讨论】:

  • 感谢您的回复!)) 解决方案很好,但在实践中很难使用,我已经有自定义土库曼语(MaterialLocalizationTkDelegate),这不是更改日期的最佳方法DatePicker,因为我使用了 DefaultMaterialLocalizations(原因是我不想重写所有 MaterialLocalizations 字段,它们太多了!)。很遗憾,flutter 不提供开箱即用的日期自定义功能,我会寻找其他解决方案。
  • 这个答案的问题是,如果本地化列表中存在该语言,它会更改语言环境:api.flutter.dev/flutter/flutter_localizations/… 不幸的是,这里没有添加土库曼语。那么我如何以编程方式为该语言定制它呢?
  • 嗨@Ruslanbek0809,我已经创建了对土库曼语的支持。地方,我找到解决方案的地方是:docs.flutter.dev/development/accessibility-and-localization/…,您会在该主题“add_language”中找到指向 github 的链接。
  • @AtamyratBabayev 感谢人。
  • @Ruslanbek0809 你好,我创建了支持土库曼语的文件,你可以在这里找到它:github.com/Mickey-A-Mouse/turkmen_localization_flutter
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 2021-08-15
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多