FlutterでCupertino UIのアプリを作ってみた

最近、少しずつですがFlutterの勉強をしています。

FlutterでiPhoneっぽいUIのアプリを作れないのか調べたところ、
さすがはFlutterさん！ちゃんと「flutter/cupertino.dart」っていうパッケージが用意されてました。

勉強がてら、「Cupertino」パッケージを使って、簡単なアプリを作ってみました。

##成果物

<img width="435" alt="スクリーンショット 2018-12-14 7.57.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/140849/e768c761-7613-b386-8b6d-84e6a75431cd.png">
<img width="435" alt="スクリーンショット 2018-12-14 7.58.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/140849/79f99322-6168-f9c4-c957-a292691c1f45.png">
<img width="435" alt="スクリーンショット 2018-12-14 8.00.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/140849/6630dbe5-aacb-8275-c016-9a353f3244cb.png">
<img width="435" alt="スクリーンショット 2018-12-14 8.00.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/140849/7d346700-a1a3-cdae-859e-4645181d276b.png">
<img width="435" alt="スクリーンショット 2018-12-14 8.01.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/140849/3448a673-8b28-39cd-ebab-ba408db26006.png">


##コード

```flutter:main.dart
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        theme: ThemeData.light(),
        home: CupertinoPageScaffold(
          navigationBar: new CupertinoNavigationBar(
            leading: Icon(CupertinoIcons.back),
            middle: Icon(CupertinoIcons.info),
            trailing: Icon(CupertinoIcons.forward),
          ),
          child: new MyHomePage(),
        ));
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: [
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.clock),
            title: Text('テストページ1'),
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.book),
            title: Text('テストページ2'),
          ),
        ],
      ),
      tabBuilder: (context, index) {
        return CupertinoTabView(
          builder: (context) {
            switch (index) {
              case 0:
                return CupertinoDialogTest();
                break;
              case 1:
                return CupertinoActionSheetTest();
                break;
            }
          },
        );
      },
    );
  }
}

class CupertinoDialogTest extends StatefulWidget {
  @override
  CupertinoDialogTestState createState() => CupertinoDialogTestState();
}

class CupertinoDialogTestState extends State<CupertinoDialogTest> {
  Widget build(BuildContext context) {
    return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          CupertinoButton(
            color: Colors.blue,
            borderRadius: new BorderRadius.circular(30.0),
            onPressed: () {
              showDialog(
                  context: context,
                  child: new CupertinoAlertDialog(
                    title: new Column(
                      children: <Widget>[
                        new Text("テストダイアログ"),
                      ],
                    ),
                    actions: <Widget>[new FlatButton(child: new Text("OK"))],
                  ));
            },
            child: Text('ダイアログを表示します'),
          ),
        ]);
  }
}

class CupertinoActionSheetTest extends StatefulWidget {
  @override
  CupertinoActionSheetTestState createState() =>
      CupertinoActionSheetTestState();
}

class CupertinoActionSheetTestState extends State<CupertinoActionSheetTest> {
  String _message;

  @override
  void initState() {
    super.initState();
    _message = '';
  }

  void _setMessage(message) {
    setState(() {
      _message = message;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          new Container(
            padding: new EdgeInsets.all(15.0),
            child: new Text(
              _message,
              style:
                  DefaultTextStyle.of(context).style.apply(fontSizeFactor: 0.5),
            ),
          ),
          CupertinoButton(
            color: Colors.blue,
            borderRadius: new BorderRadius.circular(30.0),
            onPressed: () {
              showCupertinoModalPopup(
                  context: context,
                  builder: (BuildContext context) {
                    return CupertinoActionSheet(
                        title: const Text('選択した項目が画面に表示されます'),
                        actions: <Widget>[
                          CupertinoActionSheetAction(
                            child: const Text('テスト1'),
                            onPressed: () {
                              _setMessage('テスト1');
                              Navigator.pop(context, 'テスト1');
                            },
                          ),
                          CupertinoActionSheetAction(
                            child: const Text('テスト2'),
                            onPressed: () {
                              _setMessage('テスト2');
                              Navigator.pop(context, 'テスト2');
                            },
                          ),
                          CupertinoActionSheetAction(
                            child: const Text('テスト3'),
                            onPressed: () {
                              _setMessage('テスト3');
                              Navigator.pop(context, 'テスト3');
                            },
                          ),
                        ],
                        cancelButton: CupertinoActionSheetAction(
                          child: const Text('キャンセル'),
                          isDefaultAction: true,
                          onPressed: () {
                            Navigator.pop(context, 'キャンセル');
                          },
                        ));
                  });
            },
            child: Text('選択してください'),
          ),
        ]);
  }
}

```

##まとめ
ナビゲーションやフッターのタブをiphoneっぽくして、
アラートダイアログやアクティブシートを使ってみています。

そのほかにも、ボタンやスライドバーなどのWidgetが用意されているみたいです。

https://flutter.io/docs/development/ui/widgets/cupertino

基本的には「Material UI」用に用意されたWidgetのクラス名を、
「Cupertino UI」で用意されているWidgetに置き換えれば使えるようになっているようです。

不備や至らない点がありましたら、ご指摘いただけましたら嬉しいです。