Flutterでいい感じのログインフォームを実装する
こんにちは!
はじめまして!福岡でフロントエンドエンジニアをしているなつめです!
今回はFlutterですぐに使えるログインフォームについて書きました。
コメント・スキ・いいね!・バッジ・厳しいご意見など、なんでももらえると嬉しいです!どしどしお待ちしております!
対象読者
- サクッとログインフォームを実装したい人
- でも最低限のUIは欲しい人
- テンプレっぽいログインフォームを探している人
こんなログインフォームを実装します
完成形はこんな感じ
通常時
バリデーション時
全体のコードは最後に記述しています!
では行きましょう!
1.textFormFieldを使う
Flutterにはバリデーションを付けることができるTextFormFieldというものがあるので、今回はこれを使っていきます。
書き方
例:メールアドレスのフォームの場合
TextFormField(
autovalidateMode: AutovalidateMode.onUserInteraction,
validator: ValidateText.email,
onChanged: (text) {
//フォームに入力された時の処理
},
),
ポイント
1.ユーザーが入力した時にバリデーションを行いたいのでAutovalidateModeをonUserInteractionに設定
2.validatorにバリデーションするための関数を設定(後述します)
2.パスワードの表示の切り替え
書き方
TextFormField(
decoration: const InputDecoration(
//TextFormFieldの右側にアイコンを表示
suffixIcon: IconButton(
icon: Icon(isVisible? Icons.visibility : Icons.visibility_off) ,
onPressed: () {
//アイコンが押された時に表示・非表示をのstateを切り替える
setState(!isVisible);
},
),
),
//テキストの表示を制御
obscureText: !isVisible,
),
ポイント
1.suffixIconにパスワード表示・非表示を切り替えるアイコンを設定
2.アイコンが押された時にsetStateでisVisibleの値を反転し、表示・非表示を切り替える
3.テキストの表示を制御するobscureTextにisVisibleを渡してテキストの表示・非表示も切り替える
3.バリデーション
書き方
例:パスワードのバリデーションの場合
class ValidateText {
static String? password(String? value){
//TextFormFieldに値が入されたときだけvalidateする
if(value != null){
String pattern = r'^[a-zA-Z0-9]{6,}$';
RegExp regExp = RegExp(pattern);
if(!regExp.hasMatch(value)){
//正規表現の条件にマッチしていない時だけエラー文を返す
return '6文字以上の英数字を入力してください';
}
}
}
}
ポイント
1.入力値が正規表現とマッチしているかチェックする関数を別に定義
2.正規表現で入力値が正規表現とマッチしているかチェック
ちなみにr'正規表現'のrはエスケープ()なしで文字列で記号を扱いたいときに付ける接頭辞らしいです。
RegExpについては正規表現による文字列チェックを行うための呪文のようなものだと思ってだいじょうぶです!(たぶん)
詳しく知りたい方は下記を参照
以下サンプルコード
import 'package:flutter/material.dart';
class LoginPage extends StatefulWidget {
_State createState() => _State();
}
class _State extends State<LoginPage> {
String? email;
String? password;
bool isVisible = false;
void toggleShowPassword () {
setState(() {
isVisible = !isVisible;
});
}
void setEmail (String email) {
this.email = email;
}
void setPassword (String password) {
this.password = password;
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("ログイン"),
),
body: Center(
child:Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
TextFormField(
autovalidateMode:
AutovalidateMode.onUserInteraction,
validator: ValidateText.email,
decoration: const InputDecoration(
filled: true,
hintText: 'Email'
),
onChanged: (text) {
setEmail(text);
},
),
const SizedBox(
height: 16,
),
TextFormField(
autovalidateMode:
AutovalidateMode.onUserInteraction,
validator: ValidateText.password,
decoration: InputDecoration(
suffixIcon: IconButton(
icon: Icon(isVisible? Icons.visibility : Icons.visibility_off) ,
onPressed: () {
toggleShowPassword();
},
),
filled: true,
hintText: 'Password'),
onChanged: (text) {
setPassword(text);
},
obscureText: !isVisible,
),
const SizedBox(
height: 16,
),
ElevatedButton(
onPressed: () {
//ここにログイン処理を書く
},
child: const Text("ログイン"),
),
],
)
),
],
),
),
);
}
}
class ValidateText {
static String? password(String? value){
if(value != null){
String pattern = r'^[a-zA-Z0-9]{6,}$';
RegExp regExp = RegExp(pattern);
if(!regExp.hasMatch(value)){
return '6文字以上の英数字を入力してください';
}
}
}
static String? email(String? value){
if(value != null){
String pattern = r'^[0-9a-z_./?-]+@([0-9a-z-]+\.)+[0-9a-z-]+$';
RegExp regExp = RegExp(pattern);
if(!regExp.hasMatch(value)){
return '正しいメールアドレスを入力してください';
}
}
}
}
参考記事
Author And Source
この問題について(Flutterでいい感じのログインフォームを実装する), 我々は、より多くの情報をここで見つけました https://zenn.dev/urakawa_daiki/articles/a87b0b49a2fc9e著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol