こちらの記事で、 Material Design Color System や TextTheme に対応したバージョンを公開しました。
この記事のアプローチも有効な場合はあると思いますが、私の環境では新しい方を活用しています。
目的
- アプリ内で使う TextStyle を一覧化
- かつ、標準的なスタイル変更を単純に・便利に呼び出せるようにする
- color
- fontWeight
定義したいスタイル
- Material Design Typography にのっとったスタイルのみをアプリ内で使用する
- 用途ごとの定義 (title, body, label...)
- スケールの定義 (large, medium, small)
改善前
- 用途 x スケール で定数をふつうに定義すると・・・
- 定数名が冗長
- 定義が縦に長くて一覧性が微妙
- 活用の拡張がめんどい
- color を変えたい場合など、いちいち
copyWith()
で変更しないといけない
- color を変えたい場合など、いちいち
活用部分
Text(
"Normal Text!",
style: MyTextStyles.bodyMedium,
);
// MyColors の定義は別に用意があるものとする
Text(
"Error!",
style: MyTextStyles.bodyMedium.copyWith(
color: MyColors.caution,
),
);
Text(
"Large Bold Error!",
style: MyTextStyles.bodyLarge.copyWith(
color: MyColors.caution,
fontWeight: FontWeight.bold,
),
);
定義部分
class MyTextStyles {
static const titleLarge = TextStyle(
fontFamily: "Noto Sans",
color: MyColors.black,
fontSize: 57,
height: 64 / 57,
fontWeight: FontWeight.w400,
letterSpacing: -0.25,
);
static const titleMedium = TextStyle(
fontFamily: "Noto Sans",
color: MyColors.black,
fontSize: 45,
height: 52 / 45,
fontWeight: FontWeight.w400,
letterSpacing: 0,
);
static const titleSmall = TextStyle(
fontFamily: "Noto Sans",
color: MyColors.black,
fontSize: 36,
height: 44 / 36,
fontWeight: FontWeight.w400,
letterSpacing: 0,
);
...
}
改善後
活用部分
Text(
"Normal Text!",
style: MyTextStyles.body,
);
Text(
"Error!",
style: MyTextStyles.body.caution,
);
Text(
"Large Bold Error!",
style: MyTextStyles.body.large.caution.bold,
);
定義部分
import 'package:flutter/material.dart';
/// Use as:
/// Text("Hello!", styles: MyTextStyles.title.large.white);
class MyTextStyles {
MyTextStyles._();
static const fontFamily = "Hiragino Sans";
static _toStyle(double fontSize, double height, FontWeight fontWeight,
double letterSpacing,
{Color color = MyColors.black}) {
return TextStyle(
fontFamily: MyTextStyles.fontFamily,
color: color,
fontSize: fontSize,
// baseline 設定がうまくいかず height 指定すると下寄りの文字になってしまうので、適用を保留
// height: height / fontSize,
fontWeight: fontWeight,
letterSpacing: letterSpacing,
);
}
static final title = _MyTextStyleSet(
large: _toStyle(22, 28, FontWeight.w400, 0),
medium: _toStyle(16, 24, FontWeight.w500, 0.15),
small: _toStyle(14, 20, FontWeight.w500, 0.1),
);
static final label = _MyTextStyleSet(
large: _toStyle(14, 20, FontWeight.w500, 0.1),
medium: _toStyle(12, 16, FontWeight.w500, 0.5),
small: _toStyle(11, 16, FontWeight.w500, 0.5),
);
static final body = _MyTextStyleSet(
large: _toStyle(16, 24, FontWeight.w400, 0.15),
medium: _toStyle(14, 20, FontWeight.w400, 0.25),
small: _toStyle(12, 16, FontWeight.w400, 0.4),
);
static final link = _MyTextStyleSet(
large: _toStyle(16, 24, FontWeight.w400, 0.15, color: MyColors.textlink),
medium: _toStyle(14, 20, FontWeight.w400, 0.25, color: MyColors.textlink),
small: _toStyle(12, 16, FontWeight.w400, 0.4, color: MyColors.textlink),
);
}
/// Wrapper for TextStyle
class _MyTextStyle extends TextStyle {
_MyTextStyle(TextStyle style)
: super(
color: style.color,
backgroundColor: style.backgroundColor,
fontSize: style.fontSize,
fontWeight: style.fontWeight,
fontStyle: style.fontStyle,
letterSpacing: style.letterSpacing,
wordSpacing: style.wordSpacing,
textBaseline: style.textBaseline,
height: style.height,
leadingDistribution: style.leadingDistribution,
locale: style.locale,
foreground: style.foreground,
background: style.background,
shadows: style.shadows,
fontFeatures: style.fontFeatures,
decoration: style.decoration,
decorationColor: style.decorationColor,
decorationStyle: style.decorationStyle,
decorationThickness: style.decorationThickness,
debugLabel: style.debugLabel,
overflow: style.overflow,
);
_MyTextStyle get black => _MyTextStyle(copyWith(color: MyColors.black));
_MyTextStyle get white => _MyTextStyle(copyWith(color: MyColors.white));
_MyTextStyle get caution => _MyTextStyle(copyWith(color: MyColors.caution));
_MyTextStyle get bold => _MyTextStyle(copyWith(fontWeight: FontWeight.w700));
}
class _MyTextStyleSet extends _MyTextStyle {
final _MyTextStyle large;
// medium is this
final _MyTextStyle small;
_MyTextStyleSet(
{required TextStyle large,
required TextStyle medium,
required TextStyle small})
: large = _MyTextStyle(large),
small = _MyTextStyle(small),
super(medium);
}