LoginSignup
13
10

More than 3 years have passed since last update.

Flutterを使ってクソアプリを作ってみた

Posted at

これは何?

最近、若者の間で「クソアプリ」なるものを作って公開するのが話題になっているようで。いや確かに「ちゃんとしたもの」を作ろうとすると、それはそれで多大なる労力が必要になってハードルも上がるのだけれども、クソアプリでいいやってハードルを下げると「ちょっとかじってみる」程度の経験を積むにはいいし、やったことを公開することで情報の整理にもつながっていい気がするな、ということで最近気になるFlutterで負けじとクソアプリを作ってみた。

ソースコードはコチラ

Flutterとは?

Android/iOSのマルチデバイス対応のアプリが1つのソースコードで開発できるというGoogleが作った技術。Dart言語で実装する。

やったこと

開発環境の構築

大いにこの記事を参考にしており「開発環境の構築」は全く同じなので端折ります(手抜き)

Flutterに入門してクソアプリを作るまで
https://qiita.com/matsushou/items/f62ca1fb249670d7dbbc

ちなバージョンは

  • Flutter v1.2.1 (for Mac)
  • Android Studio 3.4
    • FlutterとDartのプラグインを入れる

Dartに再入門する

筆者Google好きで、Dartが公開された直後(1.0以前)にかじったことがあったので、おさらい的に言語仕様(結構変わっている...)を見直してみる。

Language Tourをナナメ読む
https://www.dartlang.org/guides/language/language-tour

前述の参考記事のとおり Important concepts まで読んだが、Javaエンジニアとしては以下を踏まえればどうにかなりそう。

  • 型はある、クラス定義も継承もある、ちゃんとオブジェクト指向
  • new は2.x系から省略可能になった(当時のリリースノート
  • アンダースコア _ 始まりの変数/関数/クラスがprivateになる
    • 可視性を示す修飾子 public/private はない

Flutterアプリを作ってみる

  • Android Studioから「Start a new Flutter project」を選択
    Kobito.OHndNY.png

    • Flutter Applicationを選択してNext
    • Project nameを適当に指定(デフォルトの flutter_app のままでもいい)してNext
    • Company domainを適当に指定、Sample Applicationの "generate sample content" にチェックしてFinish
    • サンプルコード付きのプロジェクトが作成される Kobito.W0QeXI.png
      • main.dart にメインロジックが記載されている
      • ちゃんとテストコード widget_test.dart も用意されているのが素敵 :star:
    • Emulatorを用意して起動
      • AVD Managerから端末のVMを用意して起動する
      • +ボタンを押すと画面に表示された数値が増えていくサンプルアプリらしい
    • サンプルアプリの画像は前述の記事にキャプチャがあるので、そっちを見てください(という手抜き)

アプリを実装する

クソアプリの境界線ってどこだろう?うっかりちゃんと作ってしまうとクソではなくなってしまうので、ここは慎重にクソアプリを作る必要がある。

今回は、macOSを始めとして Google Chrome や Evernote でも実装されている流行りの DarkMode を搭載すべく「ダークモードへの切り替え」をこのアプリに実装してみることにする。

漢は黙ってCI

とはいえロジックに手を出し始めるのではなく、眼の前に動くコードとテストコードがあるなら、まずCIを回さないとね。ということでCircleCIでのビルドを設定しておく。

  • 生成されたサンプルプロジェクトをそのままコミット&GitHubへプッシュする。

次に挙げるサイトを参考にすると、すでにFlutter用のビルドコンテナが用意されているのが分かるので、単純に .circleci/config.yml を追加するだけで、CircleCI上でビルドが動くようになる。作業ログ

circleci/config.yml
 version: 2
 jobs:
   build:
     docker:
       - image: cirrusci/flutter
     steps:
       - checkout
       - run: flutter doctor
       - run: flutter test
       - run: flutter build -v apk

これで、branch push 時や、master マージ時にビルドが走るようになる。コケたら教えてくれるので、あんしんあんしん。

モード切り替え用のコントロール(Switch)を配置

よし、本筋に戻ってまずはスイッチを配置するぞ。ということでサンプルをググってみる。

これがシンプルにまとまっていて分かりやすい。他にもサンプルケースが色々あって良さげ。このサイトはGitBookで作られていて、元のリポジトリは ここ のようだ。

main.dart の内容をまるっとこのサンプルに書き換えて実行してみたら、ちゃんとスイッチのサンプルが表示された。

Kobito.zdsg1w.png

そうそう、それよそれ。
今回はタイトル付きのスイッチを使いたいので、この部分+ _onChanged2() 関数をパクればよろし。

main.dart
new SwitchListTile(
    value: _value2,
    onChanged: _onChanged2,
    title: new Text('Hello World', style: new TextStyle(fontWeight: FontWeight.bold, color: Colors.red)),
 )

実際には、こんなソースを child: Column()children: <Widget>[] の先頭に追加しました。
この時点ではまだ _changeDarkMode() 関数はテキトーです。

main.dart
Container(
  padding: EdgeInsets.all(40.0),
  child: SwitchListTile(
    value: _isDarkMode,
    onChanged: _changeDarkMode,
    title: Text('Dark mode', style: new TextStyle(fontWeight: FontWeight.bold)),
  ),
),

見た目はこんな感じに。

Kobito.JqiQUR.png

パーツを配置しただけで「Dark modeに切り替えられる感」が8割増しましたね。

いざ、DarkModeへ切り替え

残るは _changeDarkMode() 関数の実装だ。ということで試しに backgroundColor 指定だけblackで追加したら、文字は黒のままで画面全体が真っ黒になってしまったので、どうやら何か違うらしい。調べてみると Theme を切り替える必要がありそう。

Using Themes to share colors and font styles - Flutter

でもこの実装を真面目にやると面倒くさいなぁ、と調べ続けていたら、DynamicTheme というドンピシャなwidgetが公開されていたので、これを使おう。

pubspec.yaml のdependenciesに1行追加する。

pubspec.yaml
dependencies:
  ...(中略)
  dynamic_theme: ^1.0.0

main.dart の修正箇所はこんな感じ。(抜粋)

main.dart
import 'package:dynamic_theme/dynamic_theme.dart';

...(中略)

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return DynamicTheme(
      defaultBrightness: Brightness.light,
      data: (brightness) => ThemeData(
        primarySwatch: Colors.blue,
        brightness: brightness,
      ),
      themedWidgetBuilder: (context, theme) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: theme,
          home: MyHomePage(title: 'Flutter Dark Mode Sample'),
        );
      }
    );
  }
}

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

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool _isDarkMode = false;

  void _changeDarkMode(bool value) {
    setState(() {
      _isDarkMode = value;

      var _brightness = Brightness.light;
      if (_isDarkMode) {
        _brightness = Brightness.dark;
      }
      DynamicTheme.of(context).setBrightness(_brightness);
    });
  }
  ...()
}
  • 結果

    • スイッチのOn/OffでThemeが動的に切り替わり、憧れのDarkModeに!ヒャッホウ!! :night_with_stars: dark-mode-sample2.gif
    • うーん、、、冷静に見ると「だからどうした感」のあるクソアプリですね :star2:
    • 参考:作業ログ

感想

  • 簡単にスマホアプリが作れそう
    • 今回はアプリを最終ビルドするところまでやっていないけど、簡単な動作確認レベルならすぐイケる
  • dart はキャッチアップ楽ちん
    • エディタの補完も効けば何の苦もない
  • ソースコードの保存 → エミュレータへの自動反映、での動作確認が非常に快適
  • クソアプリ作ってみるの楽しい

GW後半に軽くプログラミングしてみたい方は、いかがでしょうか?

お粗末さまでした。

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10