以下の方法はFlutter 1.17
以上では動かなくなりました。
1. Flutterプロジェクトを新規作成
2. ビルドして確認
AndroidStudioでビルドして確認
Xcodeでビルドして確認
ios/Runner.xcworkspace
を開いて
3. Today Extenstionを作成
- テンプレートからToday Extenstion選択して作成
- today Targetに
App.framework
,Flutter.framework
を追加
4. Today Extenstionの修正
- MainInterface.storyboardから不要なラベルを削除
- Flutter frameworkをimport
- FlutterEngineをつくる
- FlutterViewControllerをTodayViewControllerに追加
import Flutter
class TodayViewController: UIViewController, NCWidgetProviding {
lazy var flutterEngine = FlutterEngine(name: "TodayViewController")
override func viewDidLoad() {
super.viewDidLoad()
flutterEngine.run()
addFlutterVC()
}
func addFlutterVC() {
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)
flutterViewController.view.translatesAutoresizingMaskIntoConstraints = false
addChild(flutterViewController)
view.addSubview(flutterViewController.view)
flutterViewController.view.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
flutterViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
flutterViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
flutterViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
flutterViewController.didMove(toParent: self)
}
}
5. ナビゲーションバーを削除
- DartクラスでToday Extenstion用のTodayAppを作成
(基本MYAppのままでappBarのみ削除)
import 'package:flutter/material.dart';
class TodayApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyTodayPage(title: 'Flutter Demo Home Page'),
);
}
}
class MyTodayPage extends StatefulWidget {
MyTodayPage({Key key, this.title}) : super(key: key);
final String title;
_MyTodayPageState createState() => _MyTodayPageState();
}
class _MyTodayPageState extends State<MyTodayPage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display1,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
- Today Extenstion用のエントリーポイントを作成
('vm:entry-point')
void mainForTodayExtension() => runApp(TodayApp());
- Today Extenstion用のエントリーポイントを利用
override func viewDidLoad() {
super.viewDidLoad()
flutterEngine.run(withEntrypoint: "mainForTodayExtension", libraryURI: nil)
addFlutterVC()
}
6. Today Extenstionの高さ変更可能に
override func viewDidLoad() {
super.viewDidLoad()
extensionContext?.widgetLargestAvailableDisplayMode = NCWidgetDisplayMode.expanded
flutterEngine.run(withEntrypoint: "mainForTodayExtension", libraryURI: nil)
addFlutterVC()
}
func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) {
if (activeDisplayMode == NCWidgetDisplayMode.compact) {
self.preferredContentSize = maxSize;
} else {
self.preferredContentSize = CGSize(width: 0, height: 200);
}
}
7. Today Extenstionのタイトル修正
全ソースコードはこちらに
https://github.com/hmhv/flutter_today_extension_example
8. 参考
Today Extenstionはアプリアイコンの長押しでも表示される