2017/2/27
2018/7/7 一部更新資料を見てる人向け: スライドを↓に進めるのを多用してます
あくまで「現時点の情報では」です!
$ brew tap dart-lang/dart
$ brew install dart
C:\> choco install dart-sdk
Linuxは省略
Dartで何かを作り始めたいとき便利!
$ cd ~/development
$ unzip ~/Downloads/flutter_macos_v0.5.1-beta.zip
$ export PATH=`pwd`/flutter/bin:$PATH
# 必要なものが入っているかチェックしてくれる
$ flutter doctor
# XCodeでiOSシミュレーターとかAndroid Studioなどをインストール
$ flutter create my_app
Creating project my_app...
...
All done! In order to run your application, type:
$ cd my_app
$ flutter run
Your main program file is lib/main.dart in the my_app directory.
$ cd my_app
$ open -a Simulator # iOSシミュレータを起動
$ flutter run
$ flutter build apk # flutter build ios でiOSビルド(MacOSのみ)
$ flutter install
小さなアプリでビルド20秒、インストール10秒 🚀
iOSアプリをビルド・インストールするにはApple Developerアカウントの登録などが必要
webpackに慣れすぎて↑が無設定で動くことに感動 😭
$ flutter create my_app
my_app
├── android
├── ios
├── lib # libの中にコードを書いていく
│ └── main.dart # アプリケーションのエントリーポイント
└── pubspec.yaml # package.jsonとかpom.xmlみたいなの
// lib/main.dart
import 'package:flutter/material.dart';
void main() {
runApp(
new Center(
child: new Text('Hello, Flutter!')
)
);
}
class HelloWorld extends StatelessWidget {
// コンストラクタ
// {}の中は名前付き引数 new HelloWorld(name: 'foo');
HelloWorld({Key key, this.name}): super(key: key);
final String name;
// buildメソッドをoverrideする
@override
Widget build(BuildContext context) {
return new Text('Hello, $name!');
}
}
間違っとったらスマン!! 😳
マサカリポイント!!! 🔨
class Counter extends StatefulWidget {
...
@override
_CounterState createState() => new _CounterState();
}
class _CounterState extends State<Counter> {
...
@override
Widget build(BuildContext context) {
return new ...;
}
}
StatefulWidgetとState<T>の生存期間が違うとかなんとか
Counter Widget
class Counter extends StatefulWidget {
Counter({Key key, this.title}) : super(key: key);
final String title;
@override
_CounterState createState() => new _CounterState();
}
class Counter extends StatefulWidget {
Counter({Key key, this.title}) : super(key: key);
final String title;
@override
_CounterState createState() => new _CounterState();
}
class Counter extends StatefulWidget {
...
@override
_CounterState createState() => new _CounterState();
}
class _CounterState extends State<Counter> {
...
@override
Widget build(BuildContext context) {
return new ...;
}
}
class Counter extends StatefulWidget {
...
final String title;
...
}
class _CounterState extends State<Counter> {
...
@override
Widget build(BuildContext context) {
return new Text(this.config.title); // I am Counter
}
}
class _CounterState extends State<Counter> {
int _counter = 0;
void _incrementCounter() {
setState(() => _counter++);
}
@override
Widget build(BuildContext context) {
return new ...
new FloatingActionButton(onPressed: _incrementCounter, ...)
);
}
}
import 'package:flutter/material.dart';
void main() {
runApp(new MaterialApp(
home: new Counter(title: 'I am Counter'),
));
}
class Counter extends StatefulWidget {
Counter({Key key, this.title}) : super(key: key);
final String title;
@override
_CounterState createState() => new _CounterState();
}
class _CounterState extends State<Counter> {
int _counter = 0;
void _incrementCounter() {
setState(() => _counter++);
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new Center(
child: new Column(
children: [
new Text(this.config.title),
new Text('Button tapped $_counter time(s).')
],
mainAxisAlignment: MainAxisAlignment.center
)
),
floatingActionButton: new FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: new Icon(Icons.add),
)
);
}
}
React | Flutter |
---|---|
Component#props | StatefulWidgetのメンバ変数、State<T>のthis.config |
Component#state | State<T>のメンバ変数 |
Component#setState | State<T>#setState |
React Component | Flutter State<T> |
---|---|
componentDidMount
componentWillReceiveProps componentWillUnmount など |
initState
didUpdateConfig dispose など |
出勤・退勤画面を御覧ください
※ 個人的な感想・意見です
※ 実際は謎でも何でもない適切な判断が行われています
import 'package:flutter/http.dart' as http;
Future<bool> signin() async {
var client = new http.Client();
var headers = new Map()
..['Content-Type'] = 'application/json';
var body = new Map()
..['secret1'] = 'secretなデータが'
..['secret2'] = 'いろいろありますね';
var response = await client.post(
'https://example.com/',
headers: headers,
body: JSON.encode(body)
);
// responseをよしなに処理
}
Futureが返ってくる普通の使いやすいhttpクライアントがあった
Universalなhttpクライアントがない
どこでも動くDartだから、httpクライアントも当然どこでも動くと思いハマった 😂
dart-lang/httpにIssueがあり、コメントによると4月には解決する?
出勤・退勤時にアニメーションしてユーザーの気持ちを受け止めたい
Animation<T>とAnimationControllerを使う
new Positioned(
top: animation.value * 200.0, // 0から200の間の値を変化
child: new Text('上から下に動くぞ!')
);
new FloatingActionButton(
child: new Text('押すと止まる'),
onPressed: () => _animationController.stop(),
);
// 2秒間にAnimationの値を初期値から終了値まで変化させる
// AnimationControllerをつくり、forwardメソッドで開始する
_controller = new AnimationController(
duration: const Duration(seconds: 2),
vsync: this,
)..forward();
// fastOutSlowInな値の変化を0.0から1.0まで持つAnimation
_animation = new CurvedAnimation(
parent: _controller,
curve: new Interval(0.0, 1.0, curve: Curves.fastOutSlowIn)
);
// 子コンポーネントの不透明度を設定できるOpacity Widgetに
// Textを入れて、不透明度の値opacityをAnimationクラスから取得する
new Opacity(
child: new Text('透明から徐々に見えるようになるぞ!'),
opacity: _animation.value
)
exampleにアニメーションのサンプルがあった 😂
公式ドキュメントだけじゃ実装できなかった