ボクダイモリ

Life is like a Game

【Flutter入門】Flutterでメモ帳アプリ作ってみた

そろそろ何かアプリを作ってみたいと思ったので簡単にマルチプラットフォームなアプリを作れるFlutterというフレームワークを触ってみました。 今回は勉強の一環として作成した簡単なメモ帳アプリを公開、解説します。 作成したアプリはGithubにアップしています。

github.com

コードの解説の前にFlutterについてですが、Flutterとはハイブリットアプリを開発するためのフレームワークDartという言語で実装されています。 Flutterの公式にも書いてありますが簡単にMaterial UIを持ったネイティブアプリを開発することができます。 flutter.io

書いててとても便利だったのがホットリロード機能で、コード修正→UI確認が秒速で完了します。

実際にアプリ開発に入る前に公式のチュートリアルは一度やってみた方がいいでしょう。 flutter.io

なお、アプリ開発のための環境構築方法については割愛します。

アプリの機能

今回実装したアプリの機能は次の通りです。

  • メモの一覧表示

  • メモの新規作成

  • メモの編集

  • メモの削除

main.dart(Home画面)

アプリのホーム画面でメモの一覧を表示させています。

アプリの全体はmain.dartに記述されており、下記のように定義しています。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Note App',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Home(title: 'Note List'),
    );
  }
}

class Home extends StatefulWidget {
  Home({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _HomeState createState() => new _HomeState();
}

アプリののタイトルと_HomeStateというWidgetを定義しています。 このWidgetはStatefulでメモ帳のデータを持たせています。

class _HomeState extends State<Home> {
  List<Memo> memos = new List<Memo>();

...

Home画面のUIは次のコードで定義されています。

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: _list(),
      floatingActionButton: new FloatingActionButton(
        tooltip: 'add note',
        child: new Icon(Icons.add),
        onPressed: () {
          Memo newMemo = new Memo('','');
          memos.add(newMemo);
          Navigator.push(context, new MaterialPageRoute<Null>(
              settings: const RouteSettings(name: "/create"),
              builder: (BuildContext context) => new Create(newMemo)
          ));
        }
      ),
    );
  }

ScaffoldというクラスでUIを構成する各コンポーネントを定義します。 それぞれのコンポーネントについて説明します。

  • appBar

アプリのナビゲーションバーに表示するタイトルです。

  • body

Home画面に表示するコンポーネントの本体。_list()でメモ帳の一覧を表示するためのリストが返されます。

  • floatingActionButton

右下に丸いボタンを出すことができます。押すとメモ帳の新規作成画面に遷移します。

        onPressed: () {
          Memo newMemo = new Memo('','');
          memos.add(newMemo);
          Navigator.push(context, new MaterialPageRoute<Null>(
              settings: const RouteSettings(name: "/create"),
              builder: (BuildContext context) => new Create(newMemo)
          ));

Navigator.pushで遷移先を指定します。また、遷移する際に新しいメモデータを配列に追加しています。 また、メモ帳のデータはMemo型を自作して配列にして保存するようにしています。 Memo型はentity/memo.dartで定義しています。

そしてメモ帳のリストを作成している箇所が次の通り。

  Widget _list() {
    return new ListView.builder(
        padding: const EdgeInsets.all(16.0),
        itemCount: memos.length,
        itemBuilder: (context, i) {
          final item = memos[i];
          return new Dismissible(
            key: new Key(item.title),
            onDismissed: (direction) {
              memos.removeAt(i);

              Scaffold.of(context).showSnackBar(
                  new SnackBar(content: new Text("Memo dismissed")));
            },
            // Show a red background as the item is swiped away
            background: new Container(color: Colors.red),
            child: new ListTile(
              title: new Text(
                item.title,
                maxLines: 1,
                style: _biggerFont,
              ),
              onTap: () {
                Navigator.push(context, new MaterialPageRoute<Null>(
                    settings: const RouteSettings(name: "/detail"),
                    builder: (BuildContext context) => new Detail(item)
                ));
              },
            ),
          );
        },
    );
  }

ListView.builderを使ってメモ帳のデータをListViewに表示させています。

メモ帳の要素を元にListTileを一つずつ作っています。

ListView内のListTileをタップしたらメモ帳の編集が行えるようにしたいのでonTapというイベントハンドラーを定義して、 押された時に編集画面に遷移するようにしてます。

また、親要素にDismissibleクラスを定義していますがこれはListViewのTileにスワイプ→削除のようなモーションを実装するのに必要になります。onDismissedがメモ帳削除のイベントハンドラーです。

create.dart(メモ帳の新規作成)

前述したメモ帳の新規作成画面はHome画面の右下に出てくる丸いボタンを押すと遷移します。 新規作成画面にはテキストフィールドとボタンを置いています。

@override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Create new note'),
      ),
      body: new ListView(children: <Widget>[
        new TextField(
            decoration: new InputDecoration(
                hintText:"Write title."
            ),
            controller: new TextEditingController(text: _memo.title),
            onChanged: (String newTitle) {
              _memo.title = newTitle;
            }
        ),
        new TextField(
            maxLines: 10,
            decoration: new InputDecoration(
                hintText:"Write memo."
            ),
            controller: new TextEditingController(text: _memo.body),
            onChanged: (String newBody) {
              _memo.body = newBody;
            }
        ),
        Center(
          child: new Container(
            margin: const EdgeInsets.all(10.0),
            height: 75.0,
            width: 150.0,

            child: new FlatButton(
              child: new Text('save memo'),
              color: Colors.lightBlue,
              textColor: Colors.white,
              onPressed: () {
                Navigator.pop(context);
              }
            )
          )
        )
      ])
    );
  }

2つのテキストフィールドはonChangedを実装していて、変更を行ったタイミングでメモ帳の内容を上書きしています。 また、ボタンを押した時のイベントは単に元の画面(Home画面)に戻っているだけです。

detail.dart(メモ帳の編集)

メモ帳の詳細画面は新規作成とほとんど変わらないです。Home画面に戻るためのボタンがないだけ。

メモ帳の削除

メモ帳の削除については前述した通り、main.dartでonDismissedというイベントハンドラーで実装しています。

            onDismissed: (direction) {
              memos.removeAt(i);

              Scaffold.of(context).showSnackBar(
                  new SnackBar(content: new Text("Memo dismissed")));
            },

ListTileをスワイプすると対応するインデックスのメモデータを削除しています。 UIも削除後に自動的に再描画されます。

この勝手に再描画してくれる点がとても楽。これが正しいやり方なのかは分からないけども。

実装してみての感想

公式ドキュメントも分かりやすく情報は十分にあるので問題なく実戦で使えると思う。 文法的な部分ではアプリのUI構造を宣言的に書けるのでその分構造を組みやすいと感じるが、階層が深くなると一覧性を損なってしまう点を強く感じた。

Widgetの記述ををメソッドやクラスを使って階層を減らすように工夫が必要そうだが、別Widgetの変数をどう参照するかとかも考えないといけない。

UIの再描画を伴うデータの更新はStatefulなWidgetがSetState()の中で行うのが正しいと思われるので、今回のようなデータのポインタを渡した先で値変更、というようなやり方は良くないのかもしれない。

このWidget同士でのデータの扱い方とかStatefulとStatelessのWidgetの使い分けは良く分かっていないので後で調べてみる。

ともあれ、やはり開発時のホットリロードはサクサク開発を進められるのですごく気持ちいいので今後もFlutterは触ってると思う。

2018年の抱負

明けましておめでとうございます。今年もよろしくお願いします。
 
昨年は印象深いイベントがいくつかあったり、世の中の先端技術の知見を浅く広く学べた年で新鮮な体験が多かったです。
とりあえず今年の振り返りと反省をKPT使ってやっていきます。

Keep

分野を問わず情報をキャッチアップし続ける
最近思ったのがアイデアを考え出すセンスとか物事の違和感に気づける洞察力というのは、今まで蓄積した知識量に依るところが多いなということ。
現に一昨年までは新しい発想を生み出すのが苦手だったのですが、流行りのサービスをよく使うようにしたりニュースアプリやSNSなどから情報収集をよくするようになってから発想するアイデアの量が大きく増えました。
他にも常に広い範囲にアンテナを張っておくことは、今後自分のどの能力に投資すればよいかの判断材料を得るのに役立ちます。自分の市場価値を高めていくために如何にして学習する分野を選択し、その分野を極めていけるかがエンジニアとして大事なことだと考えています。
 
幅広く技術要素を習得していく
去年に学んだ技術はだいたいこんな感じ
 
フロントエンド系の学習はProgateがとても役に立ちました。初心者から中級者くらいまで参考にできるいいサービスだと思います。
その他にもGolangでチャットサービスを作ってみたり、作ったサービスをサーバにデプロイするためにnginxなどのミドルウェアについても学習できました。ただ、作成したサービスについては納得できるものができていないので、広く技術を学びながら今年またチャレンジしたい。
 
勉強会の開催
会社の同僚とか元同僚の人たちと集まって仕事とかそういうのなしで勉強会とかやれたのは良かった。お互い刺激になると思うしみんなで集まって話すのめっちゃ楽しいので今後も続けていきたい。
ただ、ずっと続けているとマンネリ化してくるのか人気が少しずつなくなっているような気がしている。開催するたびにいつもどうやったら面白くなるかを模索してる感がある。もう少し求心力というか参加して楽しくなるようなコンテンツを用意できたらなーとつくづく感じます。その点は勉強会メンバーと話し合いながら考えよう。
 
運動する
仕事の都合上デスクワークが多いので運動してないと30歳あたりから腰が悪くなりそう。僕の周りで30くらいで腰壊してる人が何人かいるので気をつける:(;゙゚'ω゚'):
ぎっくり腰予防も兼ねて毎週一回テニススクールに通ってるけど最近サボりが多いので反省。

Problem

本あまり読めてない
面白いと思った本は結構買ったけど半分以上積んでしまった。本はだいたい電車で読むこと多いけどここ最近は本よりもニュース見てることの方が多くなってきた。家にいる時も動画をだらだら見てること多くなったなー、特にNetflix超面白い。画質綺麗だしホント他に何も手がつかなくなるのでオススメ。
とはいえ積み本は消化したいので以前のようにしっかり読書の時間を確保したり、インプットすべき情報は厳選する。とりあえず読んで価値があると思ったもの以外は見ないようにする。

Try

Webサービスを公開する
(去年もこんなこと言ってたような…)
毎回何かしら作っては途中でやる気失って放置するの繰り返しになってる気がするのでそろそろ何か公開したい。

おわりに

いきなりですが新年早々モンハンの新作出ますね!めっちゃ楽しみです。
モンハンやる方は一緒にやりましょう。

SIerを辞めてWebサービス系に転職しました

最近色々あったので状況報告がてら更新。
去年の11月末に新卒で入社し2年半ほど勤めていた会社を退職しました。今年1月からはWeb系の会社でお世話になる予定です。

 

前職は良し悪し色々ありましたが、基本的にはゆったり仕事をやらせて貰えたので新卒で入社できて良かったなーと思っています。入社当時、自分のような人間でも就職出来る事実に驚いていたのが懐かしいです。​😅​

 

12月中は無職だったので1週間セブ島に旅行に行ってみたり、1週間で平均15時間くらいゲームに没頭してみたり、コミケに行って写真撮影してみたりと普段出来なそうな事を色々やってました。あと勉強もちょいちょいやってます。
1月からまたエンジニアとして働く予定です。無職生活儚い…

 

転職の理由


将来は事業化目線でサービスを作ったりマーケティングを考えたり出来る人になりたいと考えているので、それが実現出来そうなキャリアプランと仕事内容がマッチしてそうな企業さんで働きたかったというのが大きな理由です。
その為にもエンジニアとしてのスキルアップを目指したかったので、自分のキャリアプランに合った企業さんとご縁を持つ事が出来たのは幸運でした。


個人的にはずっと同じ職場で働く事については少しリスクがあると感じていて、前職に居続けることで図らずとも会社特有の文化に同調し過ぎてしまったり、社外への意識が薄くなってしまうことを危惧してました。それに僕は前職以外の企業で働いた事が無いのでこれからもっと色々な人や環境に出会うべきだと思っているし、今後色々な知見を得ていく上で如何様にも変わっていけると感じているので若い今のうちになるべくチャレンジしていければなと思っています。

転職活動の振り返り


転職活動は11月中旬くらいから始めて12月中旬あたりで内定を頂きました。次の職場決まる前に辞めるっていうと色んな人に驚かれる…計画性が無い​😅​

 

転職活動やってみて思ったのは会社行きながら並行して面接受けたりするのすごく大変だということ。当時は有給を全て使ってしまっていたので会社終わった後に面接行ってました。もう二度とやりません。

 

受けた企業は全部で7社くらい。どれも自社サービス開発をやっている企業です。
面接等を受けて印象に残っているのが質問であまり技術の深掘りをされる事があまりなく、その企業の理念に共感出来るかだとか説明が論理的であるかだとかがよく見られていた様に感じました。年齢が26という事もありもしかしたら第二新卒のように見られていたのかもしれないです。


また、志望させて頂いた企業の殆どが内定をもらうのが難しいとエージェントの方から言われており案の定お見送りが多かったのですが、お見送り理由が総じて「スキル不足」だったのも印象的でした。技術的な質問が殆ど無かったにも関わらずこの様な評価をされていたのも気になる点でした。


後ほど内定先の人事の方に話を聞いてみたところ、経歴的なWeb開発やベンチャー企業での経験がなかった点で技術的に経験不足であると判断されたとの事でした。前職ではWebアプリケーション開発の一次受けや保守運用の仕事が主で、ゼロイチでプロダクトを作った経験やWeb系・ベンチャーでの経験がなかった点で技術的な評価が低かったのだと思います。

まとめ


約1ヶ月と短い転職活動でしたが、自分の目標とスキル的にもいいタイミングで転職が出来たのでとても満足しています。
転職先での仕事内容も自分のやりたい事とマッチしており、契約の条件も良かったので本当に良いご縁を頂けたなと思っています。


ただ転職先からはスキル不足でありつつもポテンシャルに期待、といった評価で採用を頂いているはずなので、その点は自覚を持ちながら今後は上手くやっていきたいです。

メッセージキューについて調べてみた

メッセージキューについて

nsqをいじってみたがいまいちどう役に立つのかよく分からなかったので調べてみた。 一番下の参考文献を一通り読むことでメッセージキューを導入することによる利点は分かると思う。

メッセージキューとは

システム間のメッセージの送信と受信の間を仲介して、送受信されるメッセージを制御するためのシステム。 やっていることはシンプルだが、システムをコンポーネントとして分割し、独立性を高める役割を果たしている。 まず送信側は受信側の状態に関わらずメッセージをキューに送信してしまうことでメッセージをすぐ手放すことができる。 例えば受信側が処理待ちや障害が発生していても、送信側がそれに合わせる必要がない。 受信側も同様、メッセージを処理している最中にメッセージが送られることがない。 メッセージキューがシステム間の仲介をすることで、受信側と送信側の独立性を高められる。

可用性

受信側がメッセージを受け取った時点で、キューにメッセージのコピーが作られる。 コピーはキューが受信側からメッセージを受け取ったという通知をもらうまでは、コピーを削除しない。 そのため、複数台あるうちの受信側のマシンで障害が発生しても、一定時間後に別のマシンがメッセージを受信する ことで処理をやり直すことができる。

拡張性

受信側の処理スピードが間に合わなくなり、キューにメッセージが貯まるようになったとき、キューがそれを検知して 受信側のマシンを増やすという運用にすることができる。 例えばAWSには仮想マシンの台数を増減させるオートスケーリングというサービスがある。

メッセージキューの種類

以下のリンク先でメッセージキューライブラリの紹介がされている。 http://postd.cc/dissecting-message-queues/

各ライブラリのパフォーマンスや導入のしやすさ等を比較したサイト。 1回読んでみたがまだ所々分からないところがある。

まとめ

  • メッセージキューとは送信側と受信側でのメッセージの仲介を行う
  • 送信側と受信側はお互いの状態を気にすることなく、メッセージの送受信ができるためパフォーマンスの劣化を防げる(可用性を上げられる)
  • メッセージキューに一定以上のメッセージが貯まったことをトリガーにして、受信側のマシンを増減させるなどの運用が可能
  • メッセージキューのライブラリは色々ある

参考文献

若手が知らない昔の技術MQ、クラウドではホットだ http://itpro.nikkeibp.co.jp/atcl/watcher/16/110700001/011600017/

分散型メッセージングミドルウェアの詳細比較 http://postd.cc/dissecting-message-queues/

【一人旅】等々力渓谷行ってきた

久々に投稿。

 

最近会社での疲れが溜まってきていたので、リラックスしたくて落ち着けるところとか行きたいなーと思い、色々調べていたら等々力渓谷という所がいいらしい。

最寄駅から1時間ほど。自然が多くて良さそう。

ちょうど会社で休暇をもらっていたので、行ってみました。

 

感想

写真をいくつか撮ったので挙げます。

 

f:id:anrakusan:20170914101639j:image

 

f:id:anrakusan:20170914101648j:image

 

 f:id:anrakusan:20170914101737j:image

 

素晴らしきかな自然!!

片っ端から行けそうな所は全部行った。全部回るのに1時間くらい。

疲れたら途中に喫茶店とかあるのそこで休憩も出来る。

写真で分かる通り川が近くで流れてるせいか気に囲まれてるせいか湿度が高めでちょっと蒸し暑かった。

周りには僕のように1人で来てる人もいれば、カップルもちらほら。

 

たまにこういう自然と触れ合う機会があると、リフレッシュ出来ますね。

いい運動になったし行ってよかった。

疲れたので近くのカフェに寄ってから帰りました。

 

一人旅いい!

一人旅ってした事なかったんですが、今回行ってみていい体験だったので今月またどこかのタイミングでどっか行ってみようと思います。

やっぱり行くなら自然があるとこがいいですね。あと、今回は日帰りで若干物足りない感じがしたので次は1泊2日くらいで観光出来るところを探してみます。

近況

ライブ行ってきました

昨日の土曜日に豚乙女さんのライブに行ってきました。 場所は渋谷TAKE OFF7 の200人くらい入れそうなライブハウス。 特に豚乙女のファンとかではなかったですが、友人に誘われたのでせっかくなので参加。 こういう盛り上がり激しいライブとかはあまり行ったことが無かったので結構新鮮でした。 曲名は少しだけ知ってたので歌えるところは全力で歌った。 おかげで今も喉がちょっと痛い。 めっちゃ面白かったのでまた行きたいです。

スマートウォッチ使ってみた

最近はこれ付けて生活してる

辞めていく会社の先輩から頂いたので使わせてもらっています。 軽いし身に着けやすいので結構気にってます。

主に腕時計と歩数計の機能を使ってます。 スマートフォンと連携すれば、プッシュ通知をスマートウォッチで見れます。 画面小さくて見にくいですが。 歩数などの統計情報はスマホに専用のアプリを入れることでチェックできるようになるようです。

アニメ

今日の午後はずっとエロ漫画先生っていうアニメ見てました。 友人から勧められたのでamazonビデオで一気見。 エロ漫画先生の所々のシーンがエロい。 それと登場人物たちの夢に対する思いを語られたときとかはじーんと来た。 ただ主人公の男の子がいつの間にかモテているがちょっと謎でした。 きっとそういうことは気にしない方が楽しめるアニメ。

趣味コーディング

最近GolangでWebアプリを作ってます。
今週半ばまでにはサーバ側だけでもちゃんと動くのを作りたい。

他のことで時間取られてあまり進んでいないので、 平日に早起きしてコーディングの時間を作るようにしたいです。

WordPress飽きたのではてなブログに戻ってきました

2ヶ月前くらいにからブログをWordPressに移行して「デザインがリッチなブログを作ろう!」とか「アフィリエイトやってマネタイズしよう!」とか考えていたわけですが、時間が経つにつれブログのデザインだとかアフィリエイトだとかどうでもよくなり当時の決心もあっけなく薄らいでしまったのでとりあえずはてなに戻ってきました。 読んでくれる方々を振り回しているみたいで申し訳ないですが😅

そもそもWordPressを始めようとしたのは知り合いから「ブログやるならWordPressがいい!」というようなアドバイスをもらったのがきっかけなのだけれども、それってきっと配信するコンテンツを限定したりしてマネタイズすることが前提なんじゃないのかなーといまでは思っている。 自分もマネタイズは視野に入れてWordPressを始めたけれども、雑記とかどんどん書きたいし色々な分野で得た知見もアウトプットしていきたいのでがっつりマネタイズ重視ってわけでもないんだよなー。

WordPressでブログを運用したいと考えていた理由は他にもあって自前で用意したサーバ上で動かしてみたいだとか、WordPressを動かすための仕組みも勉強したいというそれなりの理由があったのだけれでも、それも今や達成してしまった。 なので現在ブログをWordPressで運用する理由がない。 まぁ最初から飽きたらやめればいいかーという感じでやってたし、経験にもなったのでよかったのかなと。

はてなぶろぐよりWordPressがいいところといったら、たくさんあるプラグインを入れるだけで簡単にブログをカスタマイズできることと、 ブログのフォントサイズとかもソースコードを書き換えることで細かく変えられるところかなー。 逆に不便だったところとかは記事を書くときのエディタがイケてない。 はてなブログみたいに簡単にMarkdown挿入できたり、codeの挿入もタブが入らなかったりで融通があまり効かない感じ。 なので、特にブログにこだわりがない人ははてなブログでいいと思う。 独自ドメイン持ちたいとかならはてなProに加入すればできるし。

そんなこんなでこれからははてなブログでブログをまったり書いていこうと思います。