👁️

Flutterで入力されたパスワードの表示・非表示を切り替える方法

2021/06/02に公開

こんにちは👋

今回はパスワード入力欄によくある、目のアイコンをクリックするとパスワードの文字の表示・非表示が切り替わるアレを作成したいと思います。

実装方法

この記事では TextFormField を使って実装しますが、TextFieldTextFormField のどちらでも同じ方法で実装できます。

そもそも入力された文字をどうやって非表示にするの?

方法は簡単で、TextFieldTextFormFieldobscureText プロパティに true を設定します。

TextFormField(
  obscureText: true
),

こんな感じになります。

入力フォームにアイコンを表示する

次に、入力フォームの右端にアイコンを表示してみましょう。アイコンを右端に表示するためには InputDecorationsuffixIcon プロパティを使います。

TextFormField(
  decoration: InputDecoration(
    labelText: 'Password',
    /* ここからアイコンの設定 */
    suffixIcon: IconButton(
      icon: Icon(Icons.visibility_off),
      onPressed: () {},
    ),
    /* ここまで */
  ),
),



ちゃんとアイコンが表示されました。

これで入力フォームの外見が出来上がったので、あとはユーザーがアイコンをタップしたときに入力値の表示を切り替えるだけです。

obscureText の真理値によって入力値の表示を切り替える

bool _isObscure = true;
/* ... */
TextFormField(
  obscureText: _isObscure,
  decoration: InputDecoration(
    labelText: 'Password',
    suffixIcon: IconButton(
      // 文字の表示・非表示でアイコンを変える
      icon: Icon(_isObscure ? Icons.visibility_off : Icons.visibility),
      // アイコンがタップされたら現在と反対の状態をセットする
      onPressed: () {
        setState(() {
          _isObscure = !_isObscure;
        });
      },
    ),
  ),
),

ここは Dart の文法を知っているかいないかだと思うのであまり説明することはありませんが、やっていることを簡単に説明すると、変数 _isObscuretrue なのか false なのかによって入力フォームに表示されているアイコンを変えています。そして、アイコンがタップされると _isObscure に現在の真理値と反対のものを入れて setState を使って状態の変化を伝えています。

出来上がりは以下のような感じになります。

良い感じだと思います。

それでは、最後にコード全体を載せて終わりにしたいと思います。ありがとうございました。

main.dart
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData.light(),
      home: MainPage(),
    );
  }
}

class MainPage extends StatefulWidget {
  
  _MainPageState createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  bool _isObscure = true;

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Sample App'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(32.0),
        child: Center(
          child: TextFormField(
            obscureText: _isObscure,
            decoration: InputDecoration(
              labelText: 'Password',
              suffixIcon: IconButton(
                icon: Icon(_isObscure ? Icons.visibility_off : Icons.visibility),
                onPressed: () {
                  setState(() {
                    _isObscure = !_isObscure;
                  });
                },
              ),
            ),
          ),
        ),
      ),
    );
  }
}

GitHubで編集を提案

Discussion