この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
大阪オフィスの山田です。家の中でよくねこを紛失しますが、大体布団の中にいます。今回は、プラットフォーム毎に、異なるUIのダイアログを表示してみます。
今回やること
前回作ったチャットアプリにサインイン機能を追加しましたので、今回はサインアウト機能をつけます。その際に表示する確認ダイアログをiOS、Androidで表示を変えてみたいと思います。
完成イメージ
iOS
Android
※画像はタブレット端末のスクリーンショットです
開発環境
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, v0.5.1, on Mac OS X 10.13.5 17F77, locale ja-JP)
[✓] Android toolchain - develop for Android devices (Android SDK 28.0.1)
[✓] iOS toolchain - develop for iOS devices (Xcode 9.4)
[✓] Android Studio (version 3.1)
✗ Flutter plugin not installed; this adds Flutter specific functionality.
✗ Dart plugin not installed; this adds Dart specific functionality.
[!] VS Code (version 1.26.1)
[✓] Connected devices (1 available)
flutter --version
Flutter 0.5.1 • channel beta • https://github.com/flutter/flutter.git
Framework • revision c7ea3ca377 (3 months ago) • 2018-05-29 21:07:33 +0200
Engine • revision 1ed25ca7b7
Tools • Dart 2.0.0-dev.58.0.flutter-f981f09760
実装
前準備
前回作ったチャットアプリの続きから始めます。プラットフォーム毎に処理を切り替える実装自体は、前回からの続きからでなくても参考にできるかと思います。
実装
まずは、ナビゲーションバーの右上にSignOut
ボタンを表示する部分です。ログインしている時にのみボタンを表示するようにしています。実装は以下の通りです。
import 'dart:io';
import 'package:flutter/cupertino.dart';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: new Text("Firebase Chat"),
actions: _buildAppBarActionButton()
),
body: Container(
child: _user == null ? _buildGoogleSignInButton() : _buildChatArea()),
);
}
List<Widget> _buildAppBarActionButton() {
return _user == null ? null :
<Widget>[
MaterialButton(
onPressed: () {
StatelessWidget dialog;
dialog = Platform.isIOS ?
_buildSignOutDialogiOS()
: _buildSignOutDialogAndroid();
showDialog(
context: context,
builder: (context) {
return dialog;
}
);
},
child: Text(
"SignOut",
style: TextStyle(
fontSize: 14.0,
color: Colors.white
),
),
)
];
}
dart:io
をimportして、Platform.isXXX
メソッドでプラットフォームを判定します。_buildSignOutDialogXXX
メソッドで各プラットフォームに対応したダイアログを生成します。ダイアログを生成するメソッドは以下の通りです。
Widget _buildSignOutDialogAndroid() {
return AlertDialog(
title: Text("Confirm"),
content: Text("Are you sure you want to Sign out?"),
actions: <Widget>[
FlatButton(
child: const Text("Cancel"),
onPressed: () {
Navigator.pop(context);
},
),
FlatButton(
child: const Text("SignOut"),
onPressed: () {
Navigator.pop(context);
_signOut();
},
)
]
);
}
Widget _buildSignOutDialogiOS() {
return CupertinoAlertDialog(
title: Text("Confirm"),
content: Text("Are you sure you want to Sign out?"),
actions: <Widget>[
CupertinoDialogAction(
child: const Text("Cancel"),
isDefaultAction: true,
onPressed: () {
Navigator.pop(context);
},
),
CupertinoDialogAction(
child: const Text("SignOut"),
isDestructiveAction: true,
onPressed: () {
Navigator.pop(context);
_signOut();
},
)
]
);
}
void _signOut() {
_auth.signOut()
.then((_) {
setState(() {
_user = null;
});
})
.catchError((error) {
print(error);
});
}
AndroidはAlertDialog
, FlatButton
、iOSはCupertinoAlertDialog
, CuprtinoDialogAction
クラスを使用しています。どちらも処理はほぼ同じでSignOut
ボタンがタップされたらサインアウトする処理を実行します。うーん、ここはほとんど処理が同じだし、なんとか共通化したいなぁ。。。今回、実装したソースはこちらに載せておきます。
最後に
いかがだったでしょうか。Flutterで完結する内容であれば、Flutterでプラットフォーム毎に処理を分けることができました。あんまり分けすぎるとFlutterを使うメリットも小さくなってしまうので、可能な限り統一して進めたい、というのが所感です。