Closed10
DatePickerの週始まりを日曜から月曜にしたい
StackOverfrow で同じ質問を発見。
showDatePicker
でLocaleを指定できるので、 Locale('en', 'GB')
を指定すれば良いとあり、確かにこれだと動く。ただし、表記は英語になってしまう。
ちなみにGBはイギリスで、イギリスは月曜始まりらしい。
Localeで変わるということがわかったので、CalendarDatePickerの中を見ると、 MaterialLocalizations#firstDayOfWeekIndex
を参照して、週始まりを決めていた
(Flutter 3.3.5で確認)
firstDayOfWeekIndex
の定義はこちら
MaterialLocalizations
はbuildメソッドでMaterialLocalizations.ofで持ってきている
MaterialLocalizations
とは?
Materialウィジェットで利用されるリソースの定義群。
- DefaultMaterialLocalizations
- 実装クラス
- 英語
- GlobalMaterialLocalizations
- その他の言語をサポート
- 抽象クラス
GlobalMaterialLocalizationsの実装クラスはgenerated_material_localizations.dartに多くの言語でgenerateされている。日本語バージョンは下記 GlobalMaterialLocalizationsJa
。
カスタム GlobalMaterialLocalizationsJa
/// カレンダーの週始まりを月曜にするため、[MaterialLocalizationJa]をoverrideして
/// [firstDayOfWeekIndex]を変更します。
class CustomLocalization extends MaterialLocalizationJa {
/// コンストラクタの引数は、Flutter層の実装をほぼそのまま持ってきています。
CustomLocalization()
: super(
fullYearFormat: DateFormat('y年', 'ja'),
compactDateFormat: DateFormat('y/M/d', 'ja'),
shortDateFormat: DateFormat('y年M月d日', 'ja'),
mediumDateFormat: DateFormat('M月d日(E)', 'ja'),
longDateFormat: DateFormat('y年M月d日EEEE', 'ja'),
yearMonthFormat: DateFormat('y年M月', 'ja'),
shortMonthDayFormat: DateFormat('M月d日', 'ja'),
decimalFormat: NumberFormat('#,##0.###', 'ja'),
twoDigitZeroPaddedFormat: NumberFormat('00', 'ja'),
);
/// 週の始まりを月曜(1)に設定。
@override
int get firstDayOfWeekIndex => 1;
static const LocalizationsDelegate<MaterialLocalizations> delegate =
_CustomDelegate();
}
class _CustomDelegate extends LocalizationsDelegate<MaterialLocalizations> {
const _CustomDelegate();
@override
Future<MaterialLocalizations> load(Locale locale) async {
// 言語リソースをloadするため、先に[GlobalMaterialLocalizations]をコールする
final defaultLocalization =
await GlobalMaterialLocalizations.delegate.load(locale);
// 日本語の場合は[CustomLocalizations]で上書きする
if (locale.languageCode == 'ja') {
return CustomLocalization();
}
// それ以外の時は[GlobalMaterialLocalizations]から取得したものを利用する
return defaultLocalization;
}
@override
bool isSupported(Locale locale) {
return locale.languageCode == 'ja';
}
@override
bool shouldReload(_CustomDelegate old) => false;
}
CustomLocalizationのポイント
- 基本、日本語設定をそのまま使いたいので、
MaterialLocalizationJa
をimplementして作成 - superコンストラクタへの引数は、Flutterコードの中を見てほぼそのまま持ってきました。
- もちろん、カスタマイズしたければカスタマイズしても良さそう
- Localeにjaを指定しないと、DateFormatがデフォルトの英語表記になってしまうので、ちゃんと指定する
-
firstDayOfWeekIndex
をoverrideして1(月曜)に固定する。これが一番やりたかったこと - delegateの部分は、他のコードを参考に。
_CustomDelegateのポイント
- loadでは、先にLocale(翻訳リソース)を読み込ませる必要があるため、
GlobalMaterialLocalizations.delegate.load(locale)
をコールしておく必要がある- その上で、日本語であればCustomLocalizationを返却する
- それ以外の言語の場合は、そのままGlobalMaterialLocalizations.delegate.load(locale)の戻り値を返す
参考)
このスクラップは5ヶ月前にクローズされました