2019年12月18日水曜日

1人 Flutter Advent Calendar 2019:#18 fps check


Flutterでは60fpsを目指しているとありますが、実際に60fpsがkeepされているかどうやったら分かるでしょうか?

Android StudioのでFlutter Performanceのwindowを開くのが最も良さそうです。
https://flutter.dev/docs/development/tools/android-studio#show-performance-data
ただ、release buildの時には当然使えません。

そんな時に大体のfpsを取ろうと思うとendOfFrameというのが使えると思います。
runAppの内部で行っていることをmainの中に書いて、WidgetsBindingにあるendOfFrameがfutureになっているので、thenで呼び出される関数を設定します。
これは、現在のframeの最後に呼び出されるだけで、毎frameごとに何回も呼び出されるものではないです。そのため、常に監視をしたい場合は、callbackの最後にもう一度設定をする必要があります。

https://github.com/matsuhiro/fps_check_test/blob/master/lib/main.dart#L3-L21

こんな感じ。

ただ、Flutterは、描画の必要がなければIdle状態になります。
ゲームのように常にEvent Loopが60pfsで動き続けているわけではないです。

実際に、Android studioで、Flutter Performanceのwindowを開くと描画がされていないときには、処理を行われていないことがはっきり分かると思います。

ここで示した例では、endOfFrameにcallbackを設定しています。そうするとidleになっていたものが起動されます。
そのため、Idleにならずに処理が続くことになります。
当然ですが、普通の状況では行うべきではないです。
release buildでfpsが知りたいときには使えるかもしれない程度で、実際にはこんな事しないでdebug buildでしっかりとperformanceのチューニングを行うのが良いでしょう。

サンプルです。

https://github.com/matsuhiro/fps_check_test

Flutter PerformanceはAndroid Studioの右下にあるのでclickすると見れます。
もしくは、⇧⌘A(Shift + command + a)で、「Flutter Performance」で検索してください。

2019年12月17日火曜日

1人 Flutter Advent Calendar 2019:#17 log


Flutterで適当にlogを出そうと思ったらとても楽で、printを使えばよいだけです。
それだけで、AndroidでもiOSでもログを見ることが出来ます。

ただ、これ、製品を作るときには困ります。
製品版では出したくないですよね。

Androidではproguradの設定で消したりtimber使ったりすると思います。
同じようにFlutterでも最初からLogについてはきちんと考えておいたほうが良いです。

print自体の制御をしたいと思っても簡単にprintの中身についてはわかりませんでした。
https://github.com/flutter/engine/blob/master/lib/ui/dart_runtime_hooks.cc#L200
このあたりで出力しているようなのですが、外部からの入力値によって出す出さないを切り替えるみたいな仕組みが無いような。。。うーん。

Flutterで利用するlogのツールとしては
https://pub.dev/packages/logger
が良さそうです。

特別なことはしておらずv,d,i,w,eと別れていて、使いやすいです。完全にログを出したくないと思えばLogFilterなどを作成して設定すれば良いです。
https://github.com/matsuhiro/font_log_test/blob/master/lib/main.dart#L11-L15
こんな感じで使えます。

といいえ、適当にprintだけ書いてそのままcommitしてしまうような事故もあるとは思うので、print自体をいじりたいもんです。


2019年12月16日月曜日

1人 Flutter Advent Calendar 2019:#16 cookbook


Flutterの記事はたくさんあるし、動画もあるしで、Flutterはドキュメントには事かきません。
日本語のドキュメントもあるし、日本語の本も何冊かあります。

なので、別に英語のドキュメントを頑張って読まなくても良いのかなとか思ったりもします。
ただでさえFlutterって公式のドキュメントが充実しているので、一つ一つ読んでいるとキリがないというのもありますが。

でも、Cookbookは一通り読んでおいたほうが良いのかなーとか思ったりもします。
こういう事言うと、「いや、これも。いや、あれも。」みたいな意見も出るでしょうけど、CookBookがいいなと思ったのは、テーマが具体的でこういうのってプロダクトで必要だよね。といったものがまとめられているという印象だからです。だからCookbookなのでしょうけど。

例えば
https://flutter.dev/docs/cookbook/images/cached-images
これとか、プロダクトで画像データのcacheとか絶対やると思いますし。

データの永続化だったり動画の再生だったりとかとか。いくつかの必要そうなテーマで短めに書かれているので読みやすいです。

FlutterのWidgetを一つ一つ見ていくのも面白いですが、実践的なものがよくまとまっているのはこれかなと。

githubにcodeもあればいいんですがね。自分で作れという話ではありますが、現在はないみたいです。

2019年12月15日日曜日

1人 Flutter Advent Calendar 2019:#15 click event


特定のWidgetをClickしたら処理をするのは当たり前ですが、その周りの余白だったりをclickした時になにか処理をしたい時にはどうすればよいか?

大抵は、Cancelのような挙動を設定したくなると思います。
Containerなどにもtapのイベントを設定することは可能です。GestureDetectorを利用して実装してみます。


https://github.com/matsuhiro/click_event_test/commit/39081b5a452cf23dd76f277c5b6919c1c4f8ca87#diff-fe53fad46868a294b309fc85ed138997R94-R132

これを適当なところにいれて表示させます。

Enable Debug paintをすると上のようになります。

Button以外の部分をtapすると「container tapped」と表示されるのが分かると思います。
Paddingの上をTapしても「container tapped」が表示されるので、だいたい想像通りに動作するようです。

ただ、Containerが何も描画していないとonTapが反応しません。
Event handingをしているのが、描画のObjectであるのが原因ぽかったです。
そのため、以下のようなコードだと
https://github.com/matsuhiro/click_event_test/blob/53596dfd7a6fd8e625ed8c27616be672f0a0b052/lib/main.dart#L94-L141
「inner container tapped」は出力されません。

「inner container tapped」のコードが記述されているのは、GestureDetectorとContainerを2重に入れ子にしたものの内側のGestureDetectorのonTapで表示させようとしています。
内側のContainerは何も描画していないので、onTapが反応しません。

そこで
https://github.com/matsuhiro/click_event_test/commit/8d44ed0b81a21374e5718249a3502ff4ccc0a3ac
このように透明な色を描画すれば「inner container tapped」が出力されて、ただの入れ物のContainerでもonTapを処理できるようになります。

サンプルは以下です。
https://github.com/matsuhiro/click_event_test

2019年12月14日土曜日

1人 Flutter Advent Calendar 2019:#14 qrcode


QR codeを読んだり表示したりってことがあると思います。

QRだけで検索するとreaderとgeneratorが両方引っかかります。
QR code readerもViewで大きさを変えられるものから、全画面のカメラになるものまでありました。

ただ、全体的に言えることは、ただただ簡単。ということです。
QR code readerって作るのこんなに簡単だったのかよ。。。
って思うくらい簡単です。

QR code 生成:https://pub.dev/packages/qr_flutter
QR code 読取:https://pub.dev/packages/flutter_qr_reader

が良いかなとか思いました。flutter_qr_readerの方は、サンプルアプリとか中国語でちょっと構えてしまいますが、別にコード読めばすぐ分かる感じでした。

当たり前ですが、Transformとかもきちんと動きますし、ほんとに簡単でした。


https://github.com/matsuhiro/qr_code_test
サンプルです。
カメラにアクセスするためのpermissionを取得する部分はQRコードとは関係ないけど必要なので入れました。

2019年12月13日金曜日

1人 Flutter Advent Calendar 2019:#13 storyboard

UI作っているとUIの部品を実機で見せたくもなります。
デザイナーなどに共有するために、いちいち専用アプリを作るのもだるいですし、実機で見せてコミュニケーション取りたいケースはたくさんあると思います。

そんな時にStoryboadというのが便利そうです。
https://proandroiddev.com/storyboarding-widgets-in-flutter-96d79d9a72f0

ただ部品を並べるための枠が用意されるだけなのですが便利です。

デザイナーなどとコミュニケーションするにも良いですし、エンジニアにとっても良いshowcaseになるります。


class TextStory extends Story {
  @override
  List get storyContent {
    return [
      Text('this is story sample'),
    ];
  }
}

のようにStoryを拡張したclassを作成して


class StoryBoardApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Storyboard([
      TextStory(),
    ]);
  }
}

といあった感じでWidget作れば良いので、組み込みも楽ちんです。

サンプルは以下です。
https://github.com/matsuhiro/story_board_test

2019年12月12日木曜日

1人 Flutter Advent Calendar 2019:#12 font

Flutterでfontをカスタマイズするのはほんとに簡単です。
ちょっとpubspec.yamlに


fonts:
        - family: NotoSerifJP-Regular
          fonts:
            - asset: assets/fonts/NotoSerifJP-Regular.otf
        - family: KouzanSoushoOTF
          fonts:
            - asset: assets/fonts/KouzanSoushoOTF.otf


とかいて

           Text(
              msg,
              style: TextStyle(
                fontFamily: 'NotoSerifJP-Regular',
              ),
            ),
            Text(
              msg,
              style: TextStyle(
                fontFamily: 'KouzanSoushoOTF',
              ),
            ),


こんな感じで指定するだけです。

すごい。
文字列の描画自体はどうしているのかと気になりましたが、WebのコンテンツなどのようにPlatformViewで表示するのも良いのでは?とか思ったりもしますが、独自に
https://github.com/flutter/engine/tree/master/third_party/txt
このあたりのライブラリを利用して独自に描画しているようです。

調べといてなんですが、本やニュースなど文字そのものが商品と直結しているようなものでない限りは、フォントに関してカスタマイズするということはそんなにないかなーとは思います。

サンプルは以下においてます
https://github.com/matsuhiro/font_log_test