Flutter でログイン画面を実装します。

まずは、どのデバイスでも対応できるように、画面サイズを取得します。

詳しくは、前回をご確認ください。

class _LoginState extends State<Login> {
  double? _deviceWidth, _deviceHeight;

  @override
  Widget build(BuildContext context) {
    _deviceWidth = MediaQuery.of(context).size.width;
    _deviceHeight = MediaQuery.of(context).size.height;

    return Scaffold();
  }
}

次に、ログイン画面を構成します。

横のスペースをデバイスサイズの 5%取るために、horizontal_deviceWidth! * 0.05を指定します。

ログイン画面の構成は、上から順に、タイトル、フォーム、送信ボタンになります。

均等に並ぶよう、mainAxisAlignmentMainAxisAlignment.spaceAroundを指定します。

また、どのくらいのスペースを占有するかを指定するために、mainAxisSizeMainAxisSize.maxを指定します。

さらに、横幅を中央揃いにするために、crossAxisAlignmentCrossAxisAlignment.centerを指定しましょう。

タイトルを表示します。

class _LoginState extends State<Login> {
  double? _deviceWidth, _deviceHeight;

  @override
  Widget build(BuildContext context) {
    _deviceWidth = MediaQuery.of(context).size.width;
    _deviceHeight = MediaQuery.of(context).size.height;

    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.symmetric(
            horizontal: _deviceWidth! * 0.05,
          ),
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceAround,
              mainAxisSize: MainAxisSize.max,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                const Text(
                  'ログイン',
                  style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

画面を確認すると、

image2

タイトルが表示されました。

次に、ボタンを作成します。

Columnchildrenの中に、MaterialButtonを設定します。

minWidth、_deviceWidth! * 0.5を指定します。

heightは、_deviceHeight! * 0.06にします。

colorで色を指定し、ボタン名は『ログイン』とします。

ボタンを押した後の動作は、後ほど実装します。

children: [
  const Text(
    'ログイン',
    style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
  ),
  MaterialButton(
    onPressed: () {},
    minWidth: _deviceWidth! * 0.5,
    height: _deviceHeight! * 0.06,
    color: Colors.blueAccent,
    child: const Text(
      'ログイン',
      style: TextStyle(
          color: Colors.white, fontWeight: FontWeight.bold),
    ),
  )
],

画面を確認すると、

image3

ログインボタンができました。

メールアドレスとパスワードが入力できるよう、フォームを作成します。

emailpasswordを作成します。

class _LoginState extends State<Login> {
  double? _deviceWidth, _deviceHeight;

  String? _email;
  String? _password;

TextMaterialButtonの間にContainerを設定します。

フォームの高さは、_deviceHeight! * 0.2とします。

Containerの中にFormを設定します。

フォームの値を保存するために key が必要になるので、keyを作成します。

key、lobalKey<FormState>()で作成できます。

class _LoginState extends State<Login> {
  double? _deviceWidth, _deviceHeight;

  final GlobalKey<FormState> _loginKey = GlobalKey<FormState>();

  String? _email;
  String? _password;

key_loginKeyを指定します。

children: [
  const Text(
    'ログイン',
    style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
  ),
  Container(
    height: _deviceHeight! * 0.2,
    child: Form(
      key: _loginKey,
    ),
  ),
  MaterialButton(
    onPressed: () {},
    minWidth: _deviceWidth! * 0.5,
    height: _deviceHeight! * 0.06,
    color: Colors.blueAccent,
    child: const Text(
      'ログイン',
      style: TextStyle(
          color: Colors.white, fontWeight: FontWeight.bold),
    ),
  )
],

フォームの中を構成します。

構成内容は、ログイン画面の構成と同様にしました。

child: Form(
  key: _loginKey,
  child: Column(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    mainAxisSize: MainAxisSize.max,
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [],
  ),
),

childrenの中に、メールアドレスとパスワードのフィールドを作成します。

フィールドは、TextFormFieldで作成します。

decorationで placeholder を設定します。

InputDecorationhintTextに『メールアドレス』を指定します。

入力内容を保存するために、onSavedを使用します。

値を状態管理しましょう。

child: Form(
  key: _loginKey,
  child: Column(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    mainAxisSize: MainAxisSize.max,
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
      TextFormField(
        decoration:
            const InputDecoration(hintText: 'メールアドレス'),
        onSaved: (_value) {
          setState(() {
            _email = _value;
          });
        },
      ),
    ],
  ),
),

メールアドレスと同様にパスワードのフィールドを作成します。

obscureTexttrueにすることで、入力内容を隠すことができます。

child: Form(
  key: _loginKey,
  child: Column(
    mainAxisAlignment: MainAxisAlignment.spaceAround,
    mainAxisSize: MainAxisSize.max,
    crossAxisAlignment: CrossAxisAlignment.center,
    children: [
      TextFormField(
        decoration:
            const InputDecoration(hintText: 'メールアドレス'),
        onSaved: (_value) {
          setState(() {
            _email = _value;
          });
        },
      ),
      TextFormField(
        obscureText: true,
        decoration: const InputDecoration(hintText: 'パスワード'),
        onSaved: (_value) {
          setState(() {
            _password = _value;
          });
        },
      ),
    ],
  ),
),

画面を確認してみましょう。

image4

ログイン画面が完成しました。

最後に、ログインボタンをタップすると、値の内容を受け渡すようにします。

値を保存するには、先程作成した_loginKey の currentState で save を使います。

また、printで値の内容を表示させます。

void_loginを作成し、その中でprintを作成します。

class _LoginState extends State<Login> {
  double? _deviceWidth, _deviceHeight;

  final GlobalKey<FormState> _loginKey = GlobalKey<FormState>();

  String? _email;
  String? _password;

  void _login() {
        _loginKey.currentState!.save();
    print("メールアドレス: $_email");
    print("パスワード: $_password");
  }

_loginMaterialButtononPressedに指定します。

では、一通り完成したので、動作確認します。

image5

メールアドレスとパスワードを入力した状態で、ログインボタンをタップすると、

image6

メールアドレスとパスワードを受け取ることができました。

次回は、Flutter で Firebase を使用するために設定し、ログインを実装します。

ブログ一覧