Chapter 05

Day4: Widget紹介, 画面遷移(Navigator)

fastriver
fastriver
2021.02.13に更新

今回はここまでやります

引き続きWidgetの説明

ログイン風のページを作ってみる

前回使ったプロジェクトを再利用しよう(別に)

[FIle] -> [Open Recent] -> [(保存したプロジェクトの名前)]

使う雛形(これでmain.dartの中身を入れ替える)

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Web Training',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
		  child: 
	  )
    );
  }
}

TextField

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController nameController; ////////////追加!

   ///////////////////////////////////////////追加!
  void initState() {
    super.initState();

    nameController = new TextEditingController();
  }

  
  void dispose() {////////////////////////////////////////追加!
    nameController.dispose();

    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: TextField( //////////////////////////////////変更
          controller: nameController,
        ),
      )
    );
  }
}

文字を入力してもらうWidget。TextEditingControllerというコントローラでテキストの変化などを管理するので、それを用意しなければならない。

ちょっと見た目をよくする

変更点

  • name変数を追加
  • Columnを挿入
  • Containerを挿入
  • Textを追加
  • TextFieldにonChangedを追加
class _MyHomePageState extends State<MyHomePage> {
  TextEditingController nameController;
  String name = ""; //////////////////////////////////追加!

  
  void initState() {
    super.initState();

    nameController = new TextEditingController();
  }

  
  void dispose() {
    nameController.dispose();

    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column( ////////////////////////////挿入
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Container( /////////////////////////////挿入
              width: 200,
              child: TextField(
                controller: nameController,
                onChanged: (text) { /////////////////追加!
                  setState(() {
                    name = text;
                  });
                },
              ),
            ),
            Text( ///////////////////////////////////追加!
              "ようこそ、$nameさん",
              style: TextStyle(
                fontSize: 16.0,
                color: Colors.grey
              ),
            )
          ],
        ),
      )
    );
  }
}

<iframe style="width:800px;height:400px;" src="https://dartpad.dev/embed-flutter.html?id=633dea51148dd75e5fe4c64039b6b084"></iframe>

いい感じ

Image

まずは画像を用意

1. imageというフォルダを作る

[Project] -> 上のプロジェクト名の部分を右クリック(上の画像の赤で囲った部分) -> [New] -> [Directory]

2. 適当な画像をフォルダ内に入れる

コピペできる(エクスプローラで画像をコピー > imageフォルダを右クリックしてpaste)

もしくはimageフォルダ右クリックで[open in Explore]から入れても良い

3. pubspec.yamlに記述

下の方にある

以下のように記述する(ファイル名はさっきのに準ずる)

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true
  
  #この2行を追加
  assets:
    - image/mouse.png

変更したら右上の[Pub get]を押して反映

4. 使う

Image.asset(
	"image/mouse.png",
    width: 100,
),

リソースを追加したらデバッグはやり直そう

Card

Materialな美しいカードが作れる

Card(
	child: //...
)

囲むだけ

<iframe style="width:800px;height:400px;" src="https://dartpad.dev/embed-flutter.html?id=134a37a1e979fd6f2b7658a879919771"></iframe>

上のは画像読み込めてない

Icon

Icon(
    Icons.favorite,
    color: Colors.green,
),

Material Iconのサイトに載っているIconは多分全部使える

AppBar

この部分

Scaffold(
    appBar: AppBar(
        title: Text("ログイン画面"),
    ),
	//...
)

ScaffoldのappBar引数に入れるだけ

Navigatorと画面遷移

違うページに遷移したいときはNavigatorという仕組みを使う。

新しいファイルに新しいページを書く

lib/下にsecond.dartを作る

libを右クリック -> [New] -> [Dart File]

import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ネクストページ"),
      ),
      body: Center(
        child: Text(
          "次のページだよ!",
          style: TextStyle(
            fontSize: 40.0
          ),
        ),
      ),
    );
  }
}

画面遷移処理を書く

ボタンを用意してこんな感じに書く

FlatButton(
    onPressed: () {
        Navigator.of(context).push(
            MaterialPageRoute(
                builder: (context) {
                    return SecondPage();
            	},
            ),
        );
    },
    child: Text("ログイン"),
)

やったね

左上の矢印を押すと戻れる

全体
main.dart

import 'package:flutter/material.dart';
import 'package:flutterwebtrainingday3/second.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Web Training',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  TextEditingController nameController;
  String name = "";

  
  void initState() {
    super.initState();

    nameController = new TextEditingController();
  }

  
  void dispose() {
    nameController.dispose();

    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ログイン画面"),
      ),
      body: Center(
        child: Card(
          child: Container(
            padding: EdgeInsets.all(16.0),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Image.asset(
                  "image/mouse.png",
                  width: 200,
                ),
                Icon(
                  Icons.favorite,
                  color: Colors.green,
                ),
                Container(
                  width: 200,
                  child: TextField(
                    controller: nameController,
                    onChanged: (text) {
                      setState(() {
                        name = text;
                      });
                    },
                  ),
                ),
                Text(
                  "ようこそ、$nameさん",
                  style: TextStyle(
                    fontSize: 16.0,
                    color: Colors.grey
                  ),
                ),
                FlatButton(
                  onPressed: () {
                    Navigator.of(context).push(
                      MaterialPageRoute(
                        builder: (context) {
                          return SecondPage();
                        },
                      ),
                    );
                  },
                  child: Text("ログイン"),
                )
              ],
            ),
          ),
        ),
      )
    );
  }
}

second.dart

import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("ネクストページ"),
      ),
      body: Center(
        child: Text(
          "次のページだよ!",
          style: TextStyle(
            fontSize: 40.0
          ),
        ),
      ),
    );
  }
}

おしまい

課題

  • ユーザ名とパスワードが一致しないと画面遷移できないようにしてみる
  • Cardの見た目をもっと追求する