person t-kobayashi

RaisedButtonをElevatedButtonへ移行(2)

calendar_today 2021年05月13日 update 2021年05月19日
Facebook Twitter LINE はてなブックマーク Pocket

今回はStateによってスタイルが変化する場合の移行について記述したいと思います。

前回の記事では、styleプロパティにほぼコピペするだけで移行できましたが、今回はMaterialStatePropertyというクラスを利用します。

自社アプリでは、ラジオボタンのように難易度を選択するボタンが用意されていますが、インストール時、中級と上級のボタンは無効になっていて、下の級をクリアしないと有効化されません。コードは以下のようになっています。

RaisedButton(
    onPressed: unlocked ? callback : null,
    disabledColor: Colors.grey,
    disabledTextColor: Colors.white,
    disabledElevation: 2,
    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
    textColor: Colors.white,
    color: buttonColor,
    padding: EdgeInsets.symmetric(vertical: fontSize / 3),
    child: buttonStack,
),

前回同様、RaisedButtonをElevatedButtonに変更して、廃止されたプロパティをコメントアウトします。

ElevatedButton(
    onPressed: unlocked ? callback : null,
    // disabledColor: Colors.grey,
    // disabledTextColor: Colors.white,
    // disabledElevation: 2,
    // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
    // textColor: Colors.white,
    // color: buttonColor,
    // padding: EdgeInsets.symmetric(vertical: fontSize / 3),
    child: buttonStack,
),

ホットリロードすると、新しいデフォルトのボタンのスタイルで表示されます。無効化されているボタンについては半透明になっています。

参考用のドキュメントを確認すると、無効化(disabled)の状態のスタイルをカスタマイズする場合は、MaterialStatePropertyを使う必要があると記載があります。これにより、他のプロパティもMaterialStatePropertyで書くことになります。

無効化されているときの背景色(disabledColor)をColors.greyにするためには以下のようにコードを追加します。

ElevatedButton(
    onPressed: unlocked ? callback : null,
    style: ButtonStyle(
        backgroundColor: MaterialStateProperty.resolveWith<Color>(
            (Set<MaterialState> states) {
                if (states.contains(MaterialState.disabled)) return Colors.grey;
                return buttonColor; // buttonColorはデフォルトカラーです。
            },
        ),
    ),
    // disabledColor: Colors.grey,
    // disabledTextColor: Colors.white,
    // disabledElevation: 2,
    // shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
    // textColor: Colors.white,
    // color: buttonColor,
    // padding: EdgeInsets.symmetric(vertical: fontSize / 3),
    child: buttonStack,
),

ホットリロードすると、無効化されたボタンがデフォルトの半透明がなくなり、Colors.greyが適用されていることがわかります。

この形式を踏襲して、他のプロパティもMaterialStatePropertyを使って適用していくとこうなります。

ElevatedButton(
    onPressed: unlocked ? callback : null,
    style: ButtonStyle(
        backgroundColor: MaterialStateProperty.resolveWith<Color>(
            (Set<MaterialState> states) {
                if (states.contains(MaterialState.disabled)) return Colors.grey;
                return buttonColor; // buttonColorはデフォルトカラーです。
            },
        ),
        foregroundColor: MaterialStateProperty.resolveWith<Color>(
            (states) => Colors.white,
        ),
        elevation: MaterialStateProperty.resolveWith(
            (states) => 2,
        ),
        shape: MaterialStateProperty.resolveWith(
            (states) => RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10.0),
            ),
        ),
        textStyle: MaterialStateProperty.resolveWith(
            (states) => TextStyle(color: Colors.white),
        ),
        padding: MaterialStateProperty.resolveWith(
            (states) => EdgeInsets.symmetric(vertical: fontSize / 3),
        ),
    ),
    child: buttonStack,
),

MaterialStatePropertyを挟むことで、冗長になりますが、Stateによって変化しないプロパティに関しては、アロー関数で固定値を返せばよいだけです。

今回のようにアップデートすると、リファクタリングする機会にもなるので、勉強にもなりますね。

関連記事

Flutterの記事一覧を見る

Flutterの質問

soichiro1210 が1年前に投稿

質問日時 2023年07月31日

a-sato が3年前に投稿

質問日時 2021年07月01日

a-sato が3年前に投稿

質問日時 2021年06月30日

takumi が3年前に投稿

質問日時 2021年05月20日

a-sato が3年前に投稿

質問日時 2021年05月14日

Flutterの質問一覧を見る
search