🔑

【Flutter】ログイン画面のUXを爆上げする OS標準パスワード自動入力の実装術

に公開

はじめに

メールアドレスとパスワードを毎回手入力させるログイン画面は、離脱率を確実に引き上げます。iOSの iCloudキーチェーン や Android の Google パスワード マネージャー を正しく使ってもらうには、Flutter側で「これは認証フォームですよ」と OS に伝えるコードが必要です。本稿では、現時点での デファクトスタンダード な実装パターンを整理します。


🔑 結論:最低限そろえる 3 要素

要素 役割
AutofillGroup OS に「このフィールド群はログインフォームだよ」と伝える
autofillHints 各フィールドが ID なのかパスワードなのかを明示するメタデータ
keyboardType / textInputAction 入力体験を最適化し、誤入力と離脱を防ぐ

この 3 点を正しく設定してはじめて、OS 標準の自動入力候補が確実に表示され、保存ダイアログまで到達します。


実装サンプル

import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; // finishAutofillContext を使う場合に必要

class LoginPage extends StatefulWidget {
  const LoginPage({super.key});

  
  State<LoginPage> createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  final _emailController = TextEditingController();
  final _passwordController = TextEditingController();

  
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  void _login() {
    // TODO: ログイン処理を実装

    // ✅ ログイン成功後に呼ぶと OS が保存ダイアログを出せる
    TextInput.finishAutofillContext();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('ログイン')),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: AutofillGroup(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              TextField(
                controller: _emailController,
                decoration: const InputDecoration(
                  labelText: 'ログインID (メールアドレス)',
                ),
                autofillHints: const [
                  AutofillHints.username,
                  AutofillHints.email,
                ],
                keyboardType: TextInputType.emailAddress,
                textInputAction: TextInputAction.next,
                enableSuggestions: false,
                autocorrect: false,
              ),
              const SizedBox(height: 16),
              TextField(
                controller: _passwordController,
                decoration: const InputDecoration(
                  labelText: 'パスワード',
                ),
                obscureText: true,
                autofillHints: const [AutofillHints.password],
                keyboardType: TextInputType.visiblePassword,
                textInputAction: TextInputAction.done,
                enableSuggestions: false,
                autocorrect: false,
                onEditingComplete: _login,
              ),
              const SizedBox(height: 32),
              ElevatedButton(
                onPressed: _login,
                style: ElevatedButton.styleFrom(
                  minimumSize: const Size.fromHeight(50),
                ),
                child: const Text('ログイン', style: TextStyle(fontSize: 18)),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

各要素の深掘り

1. AutofillGroup

  • OS はグループ単位で「これは認証フォームのセットだ」と理解する
  • Scaffold 直下ではなく、関連フィールドだけを囲むと誤認識を防げる
  • 同一画面に別フォームがある場合はグループを分ける

2. autofillHints

Hint 使いどころ
AutofillHints.username メールアドレス以外の ID も含む汎用ログイン ID
AutofillHints.email メールアドレスと明示したい場合に併用
AutofillHints.password パスワードフィールド。obscureText とセットで使う

コツ: Username と Email は 両方 指定することで認識率が上がります。

3. キーボード・アクション設定

  • keyboardType で OS の専用キーボード (@キー、記号など) を出す
  • textInputActionnext / done にすると、ソフトキーボードのラベルが変わり遷移がスムーズ
  • enableSuggestions=false, autocorrect=false で意図しない候補を消せる(特にパスワード)

✅ ログイン成功時は finishAutofillContext

  1. ユーザーが Autofill で入力 → ログイン処理成功
  2. TextInput.finishAutofillContext() を呼ぶ
  3. OS が「この資格情報を保存しますか?」ダイアログを表示

呼び忘れると保存ダイアログが出ず、次回以降の自動入力も期待できません。ログイン API 成功 → トークン保存 → 画面遷移の直前が定位置です。


追加で押さえておきたい UX チューニング

  • フォーカス移動: FocusScope.of(context).nextFocus()onEditingComplete で呼ぶと、ユーザー操作を 1 アクション減らせる
  • バリデーション表示: まずは自動入力で通して、失敗したらエラーメッセージを出す(先にバリデーションすると保存済み情報が弾かれることがある)
  • MFA 連携: パスワード入力後に 2FA があるプロダクトは、finishAutofillContext を二段階で呼ぶとエコシステムと相性が良い
  • テスト端末: iOS は 設定 > パスワード でテストアカウントを登録、Android は Chrome で先に資格情報を保存しておくと検証が速い

チェックリスト

  • フォームが AutofillGroup で囲われている
  • メール欄に usernameemail の両ヒントを付与
  • パスワード欄に AutofillHints.passwordobscureText
  • TextInput.finishAutofillContext() を成功時に呼ぶ
  • 自動入力後のバリデーションで弾かない
  • テスト端末で保存ダイアログが出るところまで確認済み

よくある落とし穴

症状 原因と対策
自動入力候補が出ない AutofillGroup を忘れている / フォームが複数グループにまたがっている
パスワード保存ダイアログが出ない finishAutofillContext の呼び忘れ or 例外で未到達
メール欄に電話番号候補が出る keyboardTypetext のまま、ヒントが未指定
バリデーションで即エラー 自動入力後に TextFieldonChanged で無効化している。バリデーションタイミングを見直す

まとめ

  1. AutofillGroup でフォームを囲む
  2. autofillHints でフィールドの役割を宣言
  3. keyboardTypetextInputAction で UX を磨く
  4. ログイン成功時に TextInput.finishAutofillContext() を必ず呼ぶ

たったこれだけで、ユーザーは保存済みパスワードをワンタップで呼び出せるようになり、ログイン成功率と滞在時間が大幅に改善します。まだ未対応であれば、今すぐ取り込んで「入力が面倒なアプリ」から卒業しましょう!

Discussion