ぽぴなび

知って感動した技術情報・生活情報や買ってよかったものの雑記です。

[Flutter] ModalBottomSheetを使う

成果物

動作

ソースコード

github.com

メモ

Flutterで使えるModalBottomSheet(MBS)

showModalBottomSheet function - material library - Dart API

Flutter標準装備のMBS

isScrollControlledtrueにすると、フルスクリーンで表示されるようになる。

  void _showStandardModalBottomSheet(
    BuildContext context,
    bool isScrollControlled,
  ) {
    showModalBottomSheet(
      context: context,
      isScrollControlled: isScrollControlled,  // <-- trueにするとフルスクリーン
      builder: (_) => SamplePage('Standard Modal Bottom Sheet'),
    );
  }

FlutterパッケージのMBSiOSっぽい※MBSが使える。
そのほかにも何種類かのMBSがあり、カスタマイズもできるっぽい。

※ 下からシートが登場するとともに、元々の画面が奥に行った感じになる。視差効果を減らしていると奥には行かない。

  void _showCupertinoModalBottomSheet(BuildContext context) {
    showCupertinoModalBottomSheet(
      context: context,
      builder: (BuildContext context, ScrollController controller) =>
          SamplePage('Cupertino Modal Bottom Sheet'),
    );
  }

基本的にはFlutter標準のものと使い方は変わらないが、一点注意点がある。 showCupertinoModalBottomSheetを実行するWidgetのルートがMaterialPageRouteではなくMaterialWithModalsPageRouteでないとiOSっぽいアニメーション※が表現されない。 (元々の画面が奥に引っ込むアニメーションが表示されないだけなので、動作に影響はない。)

つまり、MaterialApp直下のWidgetshowCupertinoModalBottomSheetを実行したい場合は、以下のようにする必要がある。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // home: Home(),
      onGenerateRoute: (settings) {
        return MaterialWithModalsPageRoute(
          settings: settings,
          builder: (context) => Home(),
        );
      },
    );
  }
}

また、ページ遷移後、遷移後のページでshowCupertinoModalBottomSheetを実行したい場合は以下のようにページ遷移する必要がある。

  void _goToNextPage(BuildContext context) {
    Navigator.of(context).push(
      // MaterialPageRouteではなく、
      // MaterialWithModalsPageRouteをpushする
      MaterialWithModalsPageRoute(
        builder: (BuildContext context) {
          return Scaffold(
            appBar: AppBar(),
            body: Center(
              child: RaisedButton(
                child: Text('showCupertinoModalBottomSheet'),
                onPressed: () => _showCupertinoModalBottomSheet(context),
              ),
            ),
          );
        },
      ),
    );
  }

何度もここでつまづいたので記録しておきます(怒)