Flutterの基礎を思い出す。

image

はじめに

こんにちは!Mukaigaです。

約3年前まで可茂IT塾でインターンしており、その時はFlutterでアプリ開発をお手伝いさせていただいておりました。 しかし、その後は業務委託、新卒での会社などでNext.jsやRailsを使用しており、すっかりweb方面ににシフトしてしまいました。

日頃、企業向けのサービスを開発しておりますが、個人としてはやはりエンタメ・サブカル等のジャンルなど、私生活に関わるアプリ作りに関わりたいです。

そこで個人開発として、久々にアプリに手を出そうと思いましたが、いざやろうとしたらすっかりFlutterが抜けていたので、復習してみます。

目的

Flutterアプリの基礎中の基礎を思い出す。

  • 環境構築
  • コンポーネント?の分離
  • ページ遷移

まずは

まずは、Getting startedを求めて、公式HPでもみていきましょう。

img1

おー、なんかカッコいいですね!特に真ん中のモノトーンの車のアプリ、デザインが好みです。

環境構築

早速右上に、get startedを見つけました。

書いてある通りに、環境構築を進めていきます。

img2

RecommendedにVSCodeで、Flutter拡張を使うのが良いとありますね。

以前はAndroid studioを使用していましたが、今回はVSCodeにしてみます。

$ flutter doctor

flutter doctorを使用すれば、不足している問題を教えてくれそうです。すごく懐かしい。

img3

一箇所Android toolchainって言うのがバツになっています・・・

今回Androidは考えていないので、多分大丈夫と信じて先に進みましょう。

早くコードを見たいです。

初めてのFlutterアプリ

次のステップは、アプリを作る見たいです。codelabに飛ばされ、そこにチュートリアルがありました。

https://codelabs.developers.google.com/codelabs/flutter-codelab-first?hl=ja#0

ここにも環境構築がありました。

Flutter: New Project

img4

コマンドパレットから、新しいプロジェクトを作成できそうです。

img5

おー、一瞬でベースが作成されました!面白い!

実行

右下の赤枠から、IOSシュミレーターを起動したて、デバッグを開始してみます。

img6

作られたコードを読んでみる

本当に久しぶりで、ほぼ初めてな気分なので、コードを丁寧に読んでいきます。

昔なら読み飛ばしていましたが、最近は地道にコードを理解していくことが重要だと気づいたので(当たり前のことかもですが。)読みます。

コメントが英語で書かれています。自分は英検準二級ですが、読めなかった(気分的に)ので翻訳をかけています。

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        // これはアプリケーションのテーマです。
        //
        // これを試してみてください: flutter run "でアプリケーションを実行してみてください。すると
        // 紫色のツールバーが表示されます。次に、アプリを終了せずに
        // 下のcolorSchemeのseedColorをColors.greenに変更してみてください。
        // アプリを終了せずに、 // 以下のcolorSchemeのseedColorをColors.greenに変更してみてください。
        // を押すか、コマンドラインを使った場合は 「r 」を押してください。
        // カウンタがゼロにリセットされなかったことに注目してください。
        // アプリケーションの状態はリロード中に失われません。状態をリセットするには、代わりにホット
        // 再起動を使用してください。
        //
        // これは値だけでなく、コードにも有効です: ほとんどのコード変更は
        // ほとんどのコード変更はホットリロードだけでテストできる。
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

まずはこの部分です。

void main() {
  runApp(const MyApp());
}

おそらく、アプリのエントリーポイントです。 runAppで定義されたMyAppを実行しているようです。

class MyApp extends StatelessWidget {
  const MyApp({super.key});

classで定義されたMyAppがあり、それはStatelessWidgetを継承していそうです。

StatelessWidgetが気になったので、調べてみましょう。

Flutter Docsに記述がありました。 https://docs.flutter.dev/get-started/fundamentals/widgets

翻訳をかけると次のように書かれています。

フレームワークは、ステートフルウィジェットとステートレスウィジェットという2つの主要なクラスのウィジェットを導入する。

ミュータブルな状態を持たないウィジェット(時間の経過とともに変化するクラスプロパティを持たない)は、StatelessWidgetのサブクラスです。Padding、Text、Iconなど、多くの組み込みウィジェットはステートレスです。独自のウィジェットを作成する場合、ほとんどの場合、ステートレス・ウィジェットを作成します。

一方、ウィジェットの固有の特性が、ユーザのインタラクションやその他の要因に基づいて変更される必要がある場合、そのウィジェットはステートフルです。たとえば、ユーザがボタンをタップするたびに増加するカウンタがある場合、カウンタの値がウィジェットのステートになります。この値が変更されると、UI の一部を更新するためにウィジェットをリビルドする必要があります。これらのウィジェットは、StatefulWidgetのサブクラスで、(ウィジェット自体はイミュータブルなので)ミュータブルなステートをStateのサブクラスである別のクラスに格納します。StatefulWidgetは、ビルド・メソッドを持ちません。代わりに、下の例に示すように、ユーザー・インターフェースは、Stateオブジェクトを通してビルドされます。

なるほど、StatufulWidgetは状態を持ち、再描画されるんですね。ちょっと思い出してきました。

実際MyAppは状態を持っていなさそうで、StatelessWidetなのも納得です。

次に気になるのはこちらでしょうか。

    return MaterialApp(

サンプルコードには、MaterialAppの定義はありません、なので用意されたクラスでしょうか。

https://api.flutter.dev/flutter/material/MaterialApp-class.html

api.flutter.devにありました。
チラッとoptionsを眺めていたら、DEBUGバナーを消せそうなものがありました。

debugShowCheckedModeBanner → bool Turns on a little "DEBUG" banner in debug mode to indicate that the app is in debug mode. This is on by default (in debug mode), to turn it off, set the constructor argument to false. In release mode this has no effect.

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false, // 追加
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

img7

消えました。スッキリ。

他にも気になる部分は多いですが、長くなるので今回は目的を達成するために進めます。

早速、目的である、コンポーネントの分離をやってみます。 コンポーネントと呼ぶべきではないかもしれません、ウィジェットと呼びます。

ウィジェットを他のファイルに分ける

MyHomePageを別ファイルに分けてみます。

Flutterチュートリアル(codelabのやつ)にやり方がありました。
Refactorメニューから、Extract Widgetを選択すると、自動で分離してくれるようです。

img8

おお!すごい、my_home_page.dartが作成され、そこにMyHomePageクラスが移動されました。

main.dart は以下のようになりました。

import 'package:flutter/material.dart';
import 'package:flutter_tutorial/my_home_page.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.green),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

勝手にこちらのimportが追加されました。
どうやら、importで相対パスを記述することで、他のファイルを読み込むことができるようです。

import 'package:flutter_tutorial/my_home_page.dart';

一方で、切り出したmy_home_page.dartは以下のようになりました。

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  ・・・

importパスは、material.dartしかありません。呼び出し側のみにあれば良さそうです。
これはNext.jsに近く、理解しやすいですね。

やり方がざっくり分かったので、次はページ遷移をやってみます。

ページ遷移

おそらく、必要なのは以下でしょうか。

  • 遷移を発火するためのボタン
  • 遷移先のページ

まずはボタンの用意からしてみます。 https://docs.flutter.dev/ui/widgets/material ここにありました。

他にも色々なウィジェットがあり、とても面白そうです。 img9

my_home_page.dartのColumnに、ボタンを追加してみます。

   children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
            FilledButton(
              child: const Text('次のページへ'),
              onPressed: () {
                // ...
              },

img10

できました!

次に、遷移先のページを作成します。

test_page.dartを作成し、以下のようにしてみました。

import 'package:flutter/material.dart';

class TestPage extends StatelessWidget {
  const TestPage({super.key});

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Text(
          "This is a test page",
        ),
      ),
    );
  }
}

そして、先ほど追加したボタンのhandlerに、遷移するロジックを書きます。

 onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(builder: (context) => const TestPage()),
                );
              },

遷移でき、test_pageが作成できました!

img11

最後に

今回は、基礎中の基礎をやってみました。

ネイティブアプリを自分でも作れると思うと、ワクワクしますよね!

まだまだアプリ開発する上では全然知識が足りたいので、コツコツ進めていきたいです。

お知らせ

可茂IT塾ではFlutter/Reactのインターンを募集しています!

可茂IT塾ではFlutter/Reactのインターンを募集しています!

可茂IT塾ではFlutter/Reactのインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More

タグ

Flutter (119)初心者向け (30)イベント (19)Google Apps Script (17)Nextjs (12)可茂IT塾 (10)React (8)Firebase (7)riverpod (6)ChatGPT (5)vscode (5)デザイン (5)新卒 (4)就活 (4)Figma (4)Dart (4)JavaScript (4)お知らせ (4)FlutterWeb (3)Prisma (3)NestJS (3)Slack (3)TypeScript (3)ワーケーション (3)インターン (3)設計 (2)線型計画法 (2)事例 (2)Git (2)Image (2)File (2)Material Design (2)経験談 (2)画像 (2)iOS (2)アプリ開発 (2)React Hooks (2)tailwindcss (2)社会人 (2)大学生 (2)RSS (1)Google (1)Web (1)CodeRunner (1)個人開発 (1)Android (1)Unity (1)WebView (1)Twitter (1)フルリモート (1)TextScaler (1)textScaleFactor (1)学生向け (1)supabase (1)Java (1)Spring Boot (1)shell script (1)正規表現 (1)table (1)テーブル (1)hooks (1)react (1)パワーポイント (1)趣味 (1)モンスターボール (1)CSS (1)SCSS (1)Swift (1)Cupertino (1)ListView (1)就活浪人 (1)既卒 (1)保守性 (1)iPad (1)シェアハウス (1)スクレイピング (1)PageView (1)画面遷移 (1)flutter_hooks (1)Gmail (1)GoogleWorkspace (1)ShaderMask (1)google map (1)Google Places API (1)GCPコンソール (1)Google_ML_Kit (1)Vercel (1)Google Domains (1)DeepLeaning (1)深層学習 (1)Google Colab (1)コード生成 (1)GitHub Copilot (1)オンラインオフィス (1)javascript (1)css (1)html (1)オブジェクト指向 (1)クラスの継承 (1)ポリモーフィズム (1)LINE Messaging API (1)LINE Notify (1)LINE (1)Bitcoin (1)bitFlyer (1)コミュニティー (1)文系エンジニア (1)build_runner (1)freezed (1)Freezed (1)ヒーター (1)作業効率 (1) (1)Flutter実践開発 (1) (1)permission_handler (1)flutter_local_notifications (1)markdown (1)GlobalKey (1)ValueKey (1)Key (1)アイコン (1)go_router (1)FireStorage (1)debug (1)datetime_picker (1)Apple Store Connect (1)FlutterGen (1)デバッグ (1)Widget Inspector (1)VRChat (1)API (1)検索機能 (1)Shader (1)Navigator (1)メール送信 (1)FlutterFlow (1)Firebase App Distribution (1)Fastlane (1)Dio (1)CustomClipper (1)ClipPath (1)カスタム認証 (1)アニメーション (1)Arduino (1)ESP32 (1)フリーランス (1)会社員 (1)mac (1)csv (1)docker (1)GithubActions (1)Dialog (1)BI (1)LifeHack (1)ショートカット (1)Chrome (1)高校生 (1)キャリア教育 (1)非同期処理 (1)生体認証 (1)BackdropFilter (1)レビュー (1)getAuth (1)クローズドテスト (1)PlayConsole (1)Algolia (1)コンサルティング (1)Symbol (1)

お知らせ

可茂IT塾ではFlutter/Reactのインターンを募集しています!

可茂IT塾ではFlutter/Reactのインターンを募集しています!

可茂IT塾ではFlutter/Reactのインターンを募集しています!可茂IT塾のエンジニアの判断で、一定以上のスキルをを習得した方には有給でのインターンも受け入れています。

Read More
U30可茂ITインターンハッカソン

U30可茂ITインターンハッカソン

12月28,29日開催。2日間でアプリ開発の企画から完成までを目指す!U30可茂ITインターンハッカソンを開催します。

Read More