Flutter –设置电话号码文本字段

时间:2018-10-12 13:21:02

标签: flutter

我正在尝试创建一个文本字段,以正确格式化电话号码。我尝试使用

NumberFormat("+# ### ### ####");

但是它不会保留空格

我试图通过在前面添加一个+来简化它,但是设置偏移量时我不能退格。

class PhoneInputFormatter extends TextInputFormatter {
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    final text = newValue.text.replaceAll(RegExp(r'\D'), '');
    final offset = text.length + 1;

    return newValue.copyWith(
      text: text.length >= 1 ? '+$text' : '',
      selection: TextSelection.collapsed(offset: offset),
    );
  }
}

任何帮助将不胜感激

5 个答案:

答案 0 :(得分:2)

使用intl_phone_number_input中的pub.dev软件包。我认为这很容易。 跟随this link

答案 1 :(得分:1)

这应该有效:

class NumberTextInputFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    final int newTextLength = newValue.text.length;
    int selectionIndex = newValue.selection.end;
    int usedSubstringIndex = 0;
    final StringBuffer newText = new StringBuffer();
    if (newTextLength >= 1) {
      newText.write('+');
      if (newValue.selection.end >= 1) selectionIndex++;
    }
    if (newTextLength >= 3) {
      newText.write(newValue.text.substring(0, usedSubstringIndex = 2) + ' ');
      if (newValue.selection.end >= 2) selectionIndex += 1;
    }
    // Dump the rest.
    if (newTextLength >= usedSubstringIndex)
      newText.write(newValue.text.substring(usedSubstringIndex));
    return new TextEditingValue(
      text: newText.toString(),
      selection: new TextSelection.collapsed(offset: selectionIndex),
    );
  }
}
final _mobileFormatter = NumberTextInputFormatter();

TextFormField(
          keyboardType: TextInputType.phone,
          maxLength: 15,
          inputFormatters: <TextInputFormatter>[
            WhitelistingTextInputFormatter.digitsOnly,
            _mobileFormatter,
          ],
          decoration: InputDecoration(
            icon: Icon(Icons.phone_iphone),
            hintText: "Mobile*",
          ),
        )

答案 2 :(得分:0)

(仅美国,但很容易修改)我建议仅在模型中存储数字并格式化专门用于视图的数字。为此,我做了以下事情:

/// Human readable version of the phone number
String getFormattedPhoneNumber() {
  if (_phoneNumber.isEmpty) {
    return "";
  }

  String phoneNumber = _phoneNumber;
  bool addPlus = phoneNumber.startsWith("1");
  if (addPlus) phoneNumber = phoneNumber.substring(1);
  bool addParents = phoneNumber.length >= 3;
  bool addDash = phoneNumber.length >= 8;

  // +1
  String updatedNumber = "";
  if (addPlus) updatedNumber += "+1";

  // (222)
  if (addParents) {
    updatedNumber += "(";
    updatedNumber += phoneNumber.substring(0, 3);
    updatedNumber += ")";
  } else {
    updatedNumber += phoneNumber.substring(0);
    return updatedNumber;
  }

  // 111
  if (addDash) {
    updatedNumber += phoneNumber.substring(3, 6);
    updatedNumber += "-";
  } else {
    updatedNumber += phoneNumber.substring(3);
    return updatedNumber;
  }

  // 3333
  updatedNumber += phoneNumber.substring(6);
  return updatedNumber;
}

在您的TextInput onChanged方法中:

void setPhoneNumber(String phoneNumber) {
  if (phoneNumber.contains("\(") && !phoneNumber.contains("\)")) {
    // Remove the digit the user wanted to remove but couldn't b/c a paren
    // was in the way.
    phoneNumber = phoneNumber.substring(0, phoneNumber.length - 1);
  }

  // Only store the actual digits
  phoneNumber = phoneNumber.replaceAll(RegExp("[^0-9]"), "");

  // Don't let the user enter more digits than is possible
  int maxLength = phoneNumber.startsWith("1") ? 11 : 10;
  if (phoneNumber.length > maxLength) {
    phoneNumber = phoneNumber.substring(0, maxLength);
  }

  model.setPhoneNumber(phoneNumber);
  
  // Notify the UI to update based on new input
  notifyListeners();
}

答案 3 :(得分:0)

这是一种轻量级方法(在较旧的Android OS KitKit上无法正常工作),您可以在 MaskedInputFormater 类中设置所需的特定格式,使用插件:flutter_multi_formatter

import 'package:flutter_multi_formatter/flutter_multi_formatter.dart';

TextFormField(
  keyboardType: TextInputType.phone,
  autocorrect: false,
  inputFormatters: [
    MaskedInputFormater('(###) ###-####')
  ],
  // .. etc
);

就我而言,该应用只能在国内启动,因此我不希望电话号码UI中包含任何国际代码。所有的插件似乎都希望如此。

======================

更新1

刚刚在较旧的Android KitKat上进行了测试,很遗憾,该工具无法在其中正常运行。

但是,取决于应用程序和受众群体-如果您知道大多数用户都将拥有更高版本的操作系统,那么这对于将某些东西发布出去并不是一个不错的解决方案。

答案 4 :(得分:0)

RU号的解决方案。 我们有相同的数字,但是用不同的方式书写。 8900 .. = +7900 .. 同样,如果我们从9开始输入,它会自动变为9。> +79 ..

因此,此代码结果将为:+7(900)000-00-00

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

class NumberTextInputFormatter extends TextInputFormatter {
  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    final newTextLength = newValue.text.length;
    int selectionIndex = newValue.selection.end;
    int usedSubstringIndex = 1;
    final newTextBuffer = StringBuffer();

if (newTextLength >= 1) {
  if (newValue.text.startsWith(RegExp(r'[789]'))) {
    newTextBuffer.write('+7');
    if (newValue.text.startsWith('9')) {
      newTextBuffer.write('(9');
      selectionIndex = 4;
    }
    if (newValue.selection.end >= 1) selectionIndex++;
  }
}

if (newTextLength >= 2) {
  newTextBuffer
      .write('(' + newValue.text.substring(1, usedSubstringIndex = 2));
  if (newValue.selection.end >= 2) selectionIndex++;
}
if (newTextLength >= 5) {
  newTextBuffer.write(
      newValue.text.substring(usedSubstringIndex, usedSubstringIndex = 4) +
          ')');
  if (newValue.selection.end >= 4) selectionIndex++;
}
if (newTextLength >= 8) {
  newTextBuffer.write(
      newValue.text.substring(usedSubstringIndex, usedSubstringIndex = 7) +
          '-');
  if (newValue.selection.end >= 7) selectionIndex++;
}
if (newTextLength >= 10) {
  newTextBuffer.write(
      newValue.text.substring(usedSubstringIndex, usedSubstringIndex = 9) +
          '-');
  if (newValue.selection.end >= 9) selectionIndex++;
}

// Dump the rest.
if (newTextLength > usedSubstringIndex) newTextBuffer.write(newValue.text.substring(usedSubstringIndex, newTextLength));

return TextEditingValue(
  text: newTextBuffer.toString(),
  selection: TextSelection.collapsed(offset: selectionIndex),
);


}

}