ElevatedButtonの背景色とスタイル設定
FlutterのElevatedButton
の背景色を変更する際に発生する一般的なエラーとその解決方法について解説します。
問題の概要
ElevatedButton
の背景色を関数経由で変更しようとした際に、以下のようなエラーが発生することがあります:
type '_MaterialStatePropertyAll' is not a subtype of type 'MaterialStateProperty<Color?>?'
このエラーは、MaterialStateProperty
の型が正しく設定されていない場合に発生します。
ソリューション
方法1: styleFromを使用する(推奨)
Flutter 3.1.0以降では、ElevatedButton.styleFrom
を使用するのが最も簡単で安全な方法です:
ElevatedButton(
onPressed: () {},
child: Text('ボタン'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red, // 背景色
foregroundColor: Colors.white, // 文字色
elevation: 5, // 影の高さ
padding: EdgeInsets.all(16), // パディング
),
)
TIP
styleFrom
メソッドは、ボタンの基本的なスタイル設定に最適で、コードが簡潔で読みやすくなります。
方法2: ButtonStyleとMaterialStatePropertyを使用する
より詳細なカスタマイズが必要な場合は、ButtonStyle
とMaterialStateProperty
を直接使用します:
ElevatedButton(
onPressed: () {},
child: Text('ボタン'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all<Color>(Colors.red),
foregroundColor: MaterialStateProperty.all<Color>(Colors.white),
padding: MaterialStateProperty.all<EdgeInsets>(EdgeInsets.all(16)),
),
)
方法3: 状態に応じた色変更
ボタンの状態(押されたとき、ホバー時など)に応じて色を変更する場合は、MaterialStateProperty.resolveWith
を使用します:
ElevatedButton(
onPressed: () {},
child: Text('状態に応じて色が変わるボタン'),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.resolveWith<Color>(
(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
return Colors.green; // 押されたときの色
} else if (states.contains(MaterialState.hovered)) {
return Colors.blue; // ホバー時の色
}
return Colors.red; // デフォルトの色
},
),
),
)
元のコードの修正例
質問の元のコードを修正すると以下のようになります:
void playSound(int soundNumber) {
final player = AudioCache();
player.play('note$soundNumber.wav');
}
Expanded buildPlayButton({Color color, int soundNumber}) {
return Expanded(
child: ElevatedButton(
onPressed: () {
playSound(soundNumber);
},
style: ElevatedButton.styleFrom(
backgroundColor: color,
),
child: Text('ノート $soundNumber'),
),
);
}
呼び出し側:
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
buildPlayButton(color: Colors.red, soundNumber: 1),
buildPlayButton(color: Colors.orange, soundNumber: 2),
buildPlayButton(color: Colors.yellow, soundNumber: 3),
buildPlayButton(color: Colors.green, soundNumber: 4),
buildPlayButton(color: Colors.blue, soundNumber: 5),
buildPlayButton(color: Colors.indigo, soundNumber: 6),
buildPlayButton(color: Colors.purple, soundNumber: 7),
],
);
}
バージョン対応について
WARNING
Flutter 3.1.0以前と以降でプロパティ名が変更されている点に注意してください:
- 3.1.0以前:
primary
(背景色),onPrimary
(文字色) - 3.1.0以降:
backgroundColor
,foregroundColor
古いコードを扱う場合は、この違いに注意が必要です。
追加のスタイル設定
ボタンの形や枠線もカスタマイズできます:
ElevatedButton(
onPressed: () {},
child: Text('カスタムボタン'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20), // 角丸
),
side: BorderSide(
color: Colors.black, // 枠線の色
width: 1, // 枠線の太さ
),
),
)
まとめ
ElevatedButton
の背景色を変更するには:
- 簡易な方法:
ElevatedButton.styleFrom()
を使用 - 詳細なカスタマイズ:
ButtonStyle
とMaterialStateProperty
を使用 - 状態に応じた変更:
MaterialStateProperty.resolveWith()
を使用
Flutterのバージョンに応じて適切なプロパティ名を使用し、型の不一致エラーを避けるようにしましょう。