Flutterの基本的なウィジェットを使ってログイン画面を作ってみよう
~Flutter入門編~

 

はじめまして。

今年4月から新卒入社した

「イーサン」です。

よろしくお願いします。

エンジニア

イーサン

最近日本酒にハマってて、

「日本酒会」イベントなんかにも参加してます。

(お酒っておいしい。。。)

 

エンジニア

イーサン

 

早速本題に入ります。

この記事で紹介するのはFlutterというフレームワークです。

先日ロジカルスタジオで開催されたフロントエンド勉強会で「Flutterが今アツい!」という情報を聞き、私も勉強を始めました。

 

そもそもFlutterって何?

Flutterとは、クロスプラットフォームアプリ開発を支援するオープンソースフレームワークで、

一つのコードでモバイル、ウェブ、デスクトップアプリのビルド、テストが可能です。

モバイルに関しては、iOS、Androidの両方に対応しています。

 

Flutterを使った開発においては、ホットリロード機能を搭載しているため、コードの結果がすぐに反映され、スピーディな開発ができます。

言語はDartが使用されています。FlutterもDartも開発元はGoogleです。

 

Flutter(フラッター)は、Googleによって開発されたフリーかつオープンソースのUIのSDKである。 単一のコードベースから、Android、iOS、Linux、macOS、Windows、Google Fuchsia向けの クロスプラットフォームアプリケーションを開発するために利用される。

出典 Wikipedia

公式ドキュメント:Flutter Dev

 

 

最近の動向

今年(2022年)、Flutter 3.0がリリースされ、正式にLinux, Macアプリを支援することになったため、全てのデスクトップアプリの開発が可能になりました。

また、モバイルでは折りたたみ式デバイス支援及び、iOSデバイスのプロモーションディスプレイ機能を支援するようになりました。

さらに、普通のアプリだけではなくカジュアルゲームの開発できるようにゲームツールキットの支援も始めました。

 

速いスピードで開発がされているフレームワークで、エンジニアの間で人気がドンドン上がっているそうです。

 

エンジニア

イーサン

 

 

ここからは実際に手を動かしながらFlutterを体験していきましょう。

今回はFlutterでよく使われるウィジェット(UIを構築するパーツ)をいくつか紹介しながら、

簡易的なログイン画面を作っていこうと思います。

 

前提として、Flutterの開発環境が整っている状態から始めていきます。

 

ログイン画面を作ってみよう

Android Studioで新しいFlutter Projectを作ります。

画像はFlutterプロジェクトの初期ディレクトリ構成です。

libフォルダのmain.dartからプロジェクトが実行されます。

main.dartの基本構造

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: Scaffold(
            body: Text(
         'Login Screen',
                style: TextStyle(
                    fontSize: 30
                )
            )
        )
    );
  }
}

main.dartの基本構造です。

「home」が画面に出力される部分で、基本的には Scaffoldウィジェットを使います。

 

Scaffoldウィジェットの紹介

Scaffoldウィジェットは、ウィジェットを配置するための枠のようなものです

HTMLでいうところのbodyですね。

この中に様々なウィジェットを置いて画面を作っていきます。

Scaffold(
  appBar: ウィジェット(トップバー),
  body: ウィジェット(中身),
  bottomNavigationBar: ウィジェット(下のナビゲーションバー),
  floatingActionButton: ウィジェット(画面に固定されているボタン)
)

 

Textウィジェット

Textウィジェットは文字通り画面にテキストを出力してくれます。

home: Scaffold(
  body: Text(
     'Loading Screen',
      style: TextStyle(
            fontSize: 30,
       color: Colors.red
      ),
    ),
  )

styleから文字の大きさ、文字の色などを変更できます。

試しにフォントサイズを30、文字色を赤にしてみました。

 

TextFieldウィジェット

TextFiledウィジェットはユーザー側のキーボード入力を受け付けるウィジェットです。

メールアドレスやパスワードの入力欄が必要なログイン画面には必須のウィジェットですね。

TextField(
  decoration: InputDecoration(
       labelText: "password"
  ),
  obscureText: true
)

decorationから装飾が可能で、ボーダーをつけたり、隣にアイコンを表示させたりできます。

ここではpasswordというラベルテキストを入れてみました。

また、obscureTextをtrueにすることによって入力値が見えなくすることも可能です。

 

Column, Row ウィジェット

ウィジェットの整列にはColumnウィジェットとRowウィジェットがよく使われます。
Columnウィジェットは縦方向、Rowウィジェットは横方向を整列させます。

CSSで言うところの「display: flex」に似ていますね。

 

今回はText, TextFieldウィジェットを縦並びするためにColumnウィジェットを使います。

body: Column(
  children: [
    Text(
      'Login Screen'
      style: TextStyle(
        color:Colors.red,
        fontSize: 30
      )
    ),
    TextField(
      decoration: InputDecoration(
        labelText: " e-mail"
      )
    ),
    TextField(
      decoration: InputDecoration(
        labelText: "password
      ),
      obscureText:true
    ),
  ]
)

きれいに整列されました。

 

Buttonウィジェット

ログインボタンを作るために、Buttonウィジェットを使っていきましょう。

Buttonウィジェットはその名前の通り、ボタンの役割を担うウィジェットです。

 

Buttonウィジェットにはいくつか種類があるので、気になった方はぜひ調べてみてください。

今回はElevatedButtonというButtonウィジェットを使っていきます。

ElevatedButton(
  onPressed: () {},
  child: Text('ログイン')
)

 

ボタンの大きさを調整したい場合は、親のウィジェットとしてContainerウィジェットを作り、そのContainerウィジェットのwidthを調整することで、ボタンの大きさも調整できます。

widthの値は数字で指定することもできますがduble.infinityで指定すればwidthが親ウィジェットのwidthに合わせられます。

Container(
  child: ElevatedButton( onPressed: () {},  
    child: Text('ログイン') 
  ),
  width: double.infinity
)

 

ウィジェットにpaddingを指定

各ウィジェットにpaddingを指定したい場合は、親要素としてpaddingウィジェットを作成し、

その中にpaddingを指定したいウィジェットを子要素として配置します。

 

また、paddingの値はEdgeInsetsというクラスで指定します。

指定方法はこんな感じです。

 

・EdgeInsets.all( 値 ) → 全方向に値を入れたい場合に使う

・EdgeInsets.only( 入れたい方向: 値 ) → 指定の方向にだけ値を入れたい場合に使う

・EdgeInsets.symmetric( vertical: 上下の値, horizontal: 左右の値 ) → 上下と左右に別々の値を入れたい場合に使う

・EdgeInsets.fromLTRB( 左, 上, 右, 下 )  → 上下左右をそれぞれ別の値を入れたい場合に使う

今回はEdgeInsets.allを使い、全方向に20pxのpaddingを指定しています。

body: Padding(
  padding: EdgeInsets.all(20),
  child: Column(
      ..
)

 

Imageウィジェット

こちらも名前の通り、画像を出力するウィジェットです。

まずはプロジェクト内に画像を格納するディレクトリを作成します。

今回は「asset/img」ディレクトリを作成し、その中に画像を格納します。

 

次に、プロジェクト内にある「pubspec.yml」の「uses-material-design」の下に「asset」を書いてその欄に「asset/img」のパスを指定します。

 

これで準備完了です。

Imageウィジェットを使って画像を出力しましょう。引数にパスを指定します。

Image.asset('asset/img/logo.png')

しっかり画像が出力されましたね。

 

完成

紹介したウィジェットを組み合わせて

ログイン画面を作るとこんな感じになります。

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context){
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Logical-Studio'),
        ),
        body: Padding(
          padding: EdgeInsets.all(20),
          child: Column(
            children: [
              Image.asset('asset/img/logo.png'),
              TextField(
                decoration: InputDecoration(
                  labelText: 'e-mail'
                )
              ),
              TextField(
                decoration: InputDecoration(
                  labelText: 'password'
                ),
                obscureText: true,
              ),
              Container(
                child: ElevatedButton(
                  onPressed: () {},
                  child: Text('ログイン')
                ),
                width: double.infinity
              )
            ],            
          )
        )
      )
    );
  }
}

かなりシンプルですが、いい感じの見た目になりました!

終わりに

今回は基礎的なウィジェットをいくつか紹介しつつ、簡単なログイン画面を作ってみました。

ウィジェットの使い方次第でさらにリッチな見た目にできるので、ぜひ色々と工夫して作ってみてください。

 

次回勉強会のお知らせ

8月19日にロジカルスタジオで勉強会が開催されます。

テーマは「初心者にも向けるJavaScriptフロントエンドのお話」です。

ご興味ある方はぜひご参加ください。

詳細

・タイトル:初心者にも向ける勉強会#5 JavaScriptフロントエンドのお話

・日時:2022年8月19日(金) 19:00~21:00

・場所:株式会社ロジカルスタジオ 大阪府大阪市中央区久太郎町4-2-1 本町イシカワビル4階

・connpass : JavaScriptフロントエンドのお話

 

 

 

弊社ロジカルスタジオでは
現在、フロントエンドエンジニアやバックエンドエンジニア、デザイナー、ディレクターなどの
一緒に楽しく働ける仲間を募集しております!

気になる方はこちらからどうぞ!▼