Flutter TextFormFieldのカスタムinputFormatters @初心者
TextFormFieldのカスタムinputFormatters
TextFormFieldのinputFormattersをつかって下記の様に文字数制限をしてました。
/// 文字数 12文字まで
inputFormatters: [
LengthLimitingTextInputFormatter(12),
],
ただ、こちらだと半角の場合認識されず12文字以上入力できてしまう状態になりました。
ぐぬぬしていて出来なかったので他を参考にカスタムinputFormattersを作成することにしました。
カスタムinputFormattersを作成
今回作成したのが下記カスタムinputFormattersになります。
全角だろうが、半角だろうが12文字以上は入力できないようにしています。
/// カスタムの文字数フォーマッター
class CustomInputFormatter extends TextInputFormatter {
/// コンストラクタ
CustomInputFormatter(this.maxLength);
/// 長さ
final int maxLength;
/// 半角
final RegExp halfRegExp = RegExp(r'[\u0020-\u007E\uFF61-\uFF9F]');
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
final text = newValue.text;
var total = 0;
var index = 0;
// 12文字以内のリスト作成
final charsList = <String>[];
// whileでチェック
while (index < text.length && total < maxLength) {
final char = text[index];
/// 全角、半角でも一文字とする
final length = halfRegExp.hasMatch(char) ? 1 : 1;
// 全体の長さ
total += length;
if (total > maxLength) {
// 12文字以上break
break;
}
/// 全部リストに入れる
charsList.add(char);
index++;
}
/// 配列を文字列
final newText = charsList.join();
// テキストが変更された場合、新しい値を返す
if (newText != newValue.text) {
return TextEditingValue(
text: newText,
selection: TextSelection.collapsed(offset: newText.length),
);
}
return newValue;
}
}
まず半角はどこから?
まずこちらの企業様の記事を参照させてもらいました。
記事内に、'[\u0020-\u007E\uFF61-\uFF9F]'が半角(数字も含む)と記載あったのでこちらから調べました。
カスタムinputFormatters作成方法
こちらの記事を参考にしました。いろんな所から情報収集!
コード説明
まずはクラス宣言。TextInputFormatterを継承したクラスを宣言します。
class CustomInputFormatter extends TextInputFormatter {
正規表現
こちらで文字列の半角判断するための正規表現を使用します。
final RegExp halfRegExp = RegExp(r'[\u0020-\u007E\uFF61-\uFF9F]');
TextEditingValue
ユーザーがテキスト入力または削除するたびに表示されます。
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
oldValue:変更前のテキスト
newValue:変更後のテキスト
while文で一文字ずつチェック
while (index < text.length && total < maxLength) {
final char = text[index];
/// 全角、半角でも一文字とする
final length = halfRegExp.hasMatch(char) ? 1 : 1;
// 全体の長さ
total += length;
if (total > maxLength) {
// 12文字以上break
break;
}
/// 全部リストに入れる
charsList.add(char);
index++;
}
テキストの返却
if (newText != newValue.text) {
return TextEditingValue(
text: newText,
selection: TextSelection.collapsed(offset: newText.length),
);
}
return newValue;
newTextとnewValue.textが異なる場合、テキストを更新します。
更新して新しいTextEditingValueを返す処理になります。
text: 更新されたテキスト
selection: カーソルの位置をテキストの末尾に設定します。
変更がない場合は、元のnewValueをそのまま返します。
TextEditingValueとは?
TextEditingValueは、Flutterでテキスト入力フィールドの状態を表すクラスです。このクラスは以下の情報を持っています。
text:現在のテキスト内容
selection:テキスト内の選択範囲(カーソルの位置や選択されているテキストの範囲)
このメソッドは、新しいTextEditingValueを返すことで、テキストフィールドの内容を更新します。
使い方
TextField(
inputFormatters: [
CustomInputFormatter(12), /// 制限したい文字数を渡す。
],
),
以上でカスタムinputFormatters の作成終わりです。
初めて作成しましたが、よくできたかなと思います。
ただ、backend側で処理するのが通例とのことなので、出来るならサーバー側で処理しましょう。
以上。
Discussion