【问题标题】:What android:inputType should I use for entering an IP Address and hostname?我应该使用什么 android:inputType 来输入 IP 地址和主机名?
【发布时间】:2012-01-29 12:29:34
【问题描述】:

我正在构建一个小型 Android 应用程序,用户将在其中将 IP 地址或主机名输入到 EditText 小部件中。 90% 的时间他们将输入 IP 地址,其余时间 - 主机名。

当然,我想让他们更容易输入 IP 地址,但切换到字母数字输入主机名的能力很重要。

我似乎找不到好的输入类型。 numberDecimal 最初看起来不错,但它只允许一个点。

理想情况下,我想从按下?123 按钮的标准键盘开始。

我怎么去那里?

【问题讨论】:

  • 我认为唯一的选择是 EditText 类型的文本。您可能需要为 IP 添加验证。
  • 别忘了,IP 地址将在 1995 年开始使用 a-f:...

标签: java android android-layout android-widget


【解决方案1】:

尝试使用android:inputType="number",但也要设置android:digits="0123456789."。对我有用。

【讨论】:

  • 再次阅读问题并注意到您也希望能够输入主机名。我的回答对此不起作用,但它会调出标准的“数字”键盘并允许多个点。
  • 可以digits 中添加大小写字母和连字符,但这有点乱。不过,它起作用。
  • 这是完美的解决方案
  • 使用 Android 6.0,number 没有显示点,而 numberDecimal 显示了。
  • 对于键入“192.168.1.111”,numbernumberDecimaldigits 在我的三星 Note 9 (Android 9.0) 上不起作用。它只是不允许我输入第二个点。我使用Patterns.IP_ADDRESS.matcher("192.168.1.111").matches() 来验证我的代码中的输入。
【解决方案2】:

如果您使用inputType="phone",您可以访问包含数字和句点字符的精简键盘 - 这不会限制您可以输入的句点数量。

请在输入时查看this answer 进行验证。

【讨论】:

  • 谢谢,我认为这是一个很好的答案。对于只需要数字(例如 IP 地址)的字段,用键盘调出真是太烦人了。验证显然是关键,但您甚至为此提供了一个链接!赞一个。
  • 在 Android Marshmallow 23 上,键盘上的句点按钮已替换为 * 和 #。因此 inputType="phone" 不应用于 IP 地址输入字段。使用 android:inputType="numberDecimal" 和 android:digits="0123456789."而是按照其他问题中的建议
  • 使用 Patterns 为我工作,numbernumberDecimaldigits 没有工作。
  • 不幸的是,这仍然允许用户输入*#(/),
【解决方案3】:

通过添加 android:inputType="number|numberDecimal" 和 android:digits="0123456789",这可以完美地使用数字和小数键盘。

例子

 <EditText
    android:id="@+id/ip_address"
    android:inputType="number|numberDecimal"
    android:digits="0123456789."
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>

【讨论】:

  • 完美解决方案
  • 这是完美的解决方案。谢谢!
  • 不幸的是,这对我在 API 级别 27 上不起作用。它只允许一位小数
  • 适用于 Pixel 3a XL、android 11 API 30 和 Samsung android 7.0 API 24。谢谢!
【解决方案4】:

您可以为此使用自己的输入过滤器

final EditText text = new EditText(ServerSettings.this);
InputFilter[] filters = new InputFilter[1];
filters[0] = new InputFilter() {
    @Override
    public CharSequence filter(CharSequence source, int start,
            int end, Spanned dest, int dstart, int dend) {
        if (end > start) {
            String destTxt = dest.toString();
            String resultingTxt = destTxt.substring(0, dstart) +
            source.subSequence(start, end) +
            destTxt.substring(dend);
            if (!resultingTxt.matches ("^\\d{1,3}(\\." +
                    "(\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3})?)?)?)?)?)?")) { 
                return "";
            } else {
                String[] splits = resultingTxt.split("\\.");
                for (int i=0; i<splits.length; i++) {
                    if (Integer.valueOf(splits[i]) > 255) {
                        return "";
                    }
                }
            }
        }
    return null;
    }
};
text.setFilters(filters);

【讨论】:

  • 谢谢。这个答案正是我所需要的。
  • 不适用于 spannables,因为在某些情况下整个输入会被空字符串替换。请参阅 Łukasz Sromeks 的回答stackoverflow.com/questions/3349121/…
【解决方案5】:

使用这个:

<EditText
    android:id="@+id/txtIP"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:digits="0123456789."
 />

【讨论】:

    【解决方案6】:
    <EditText
        android:id="@+id/ip_address"
        android:inputType="number|numberDecimal"
        android:digits="0123456789."
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    

    为我工作

    【讨论】:

    • 使用number|numberDecimal 只允许一个点。
    • 也添加android:digits="0123456789."
    • 我的错误。在 Android 上使用 inputType + digits 可以正常工作,但在具有自定义对话框实现的 FireOS(Amazon Android fork)上却不行。
    【解决方案7】:

    我认为你唯一的选择是..

    EditText android:inputType="text" ... />
    

    您可以检查 IP 地址包含的 3 个点的文本

    【讨论】:

    • 用户想要相同的文本框需要处理主机名和IP,数字可以将它限制为只有数字。因为DOTS,连IP都进不去。
    • "number" 不会让你切换到字母,不会让你输入点。
    • 我认为您唯一的选择是文本。然后,您可以检查 IP 地址的一致性,以确保小数点到位。
    【解决方案8】:

    我认为您需要使用TextWatcher 进行验证,使用TextView.addTextChangedListener() 方法注册并使用Pattern.DOMAIN_NAMEPattern.IP_ADDRESS(Android 2.2+)。

    见:
    Android: How can I validate EditText input?
    Validating IP in android

    【讨论】:

    • 这是验证 - 我得到了那部分。我现在只关心让用户更轻松,而不是让用户点击额外的键。
    【解决方案9】:

    您可以扩展 DigitsKeyListener (source) 并将 filter() 函数(将检查 ip 模式或字符串主机名的验证)和 getInputType() 更改为 return InputType.TYPE_CLASS_PHONE;

    【讨论】:

      【解决方案10】:

      也许如果您使用 2 个单选按钮,一个显示主机的编辑文本,另一个显示 IP 的 4 数字编辑文本,然后,一旦用户提交数据,您将所有 4 个编辑文本值与它们之间的点连接起来,就像这样,edittext1 .getText() + "." + 编辑文本2.getText() + "." edittext3.getText() + "." edittext4.getText() 这样您就可以获得一个经过验证的 IP 地址,但显然这意味着更多的工作。

      【讨论】:

      • 天哪,我讨厌应用程序试图让输入 IP 地址“更容易”。猜猜看,如果我知道 IP 地址是什么,我可能会找到“。”按钮。
      • @gladed 嗯,这个想法是为了方便 IP 验证并使用户输入更容易
      • 您可以根据 Patterns.IP_ADDRESS 轻松验证字符串。对于用户而言,在 IP 地址的不同字段之间来回点击从未如此简单。您是否见过带有单独区号/3 位前缀/4 位后缀字段的电话拨号器?还是带有不同名称/域字段的电子邮件小部件?请不要这样做。
      【解决方案11】:

      这里的代码允许您显示一个只有数字和一个点的软键盘(但允许您输入多个点)。

      etIpAddress.setInputType(InputType.TYPE_CLASS_NUMBER);
      etIpAddress.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
      etIpAddress.setKeyListener(DigitsKeyListener.getInstance(false,false));
      etIpAddress.setKeyListener(DigitsKeyListener.getInstance("0123456789."));
      

      【讨论】:

        【解决方案12】:

        InputFilter 超过Spannables 之前,SKT 的答案运行良好。 Spannables 处理起来很棘手,例如this question 的答案。在这种情况下,为无效输入返回 "" 会将整个文本替换为空字符串。我也调整了解决方案来处理这种情况。这是 Kotlin 中不同类型的代码:

        val ipAddressFilters = arrayOf(InputFilter { source, start, end, dest, dstart, dend ->
            if (end > start) {
                val toCheck = if (source is Spannable) {
                    source.toString()
                } else {
                    val destString = dest.toString()
                    destString.substring(0, dstart) + source.subSequence(start, end) + destString.substring(dend)
                }
                if (!toCheck.matches("^\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3})?)?)?)?)?)?".toRegex())) {
                    return@InputFilter if (source is Spannable) { dest } else { "" }
                } else {
                    val splits = toCheck.split("\\.".toRegex()).toTypedArray()
                    for (i in splits.indices) {
                        if (splits[i] != "" && Integer.valueOf(splits[i]) > 255) {
                            return@InputFilter if (source is Spannable) { dest } else { "" }
                        }
                    }
                }
            }
            null
        })
        

        【讨论】:

          【解决方案13】:

          尝试使用android:inputType="textUri"。当您需要主机名或 IP 地址时,它尤其适用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-05-20
            • 2021-01-18
            • 1970-01-01
            • 1970-01-01
            • 2021-04-29
            • 1970-01-01
            • 1970-01-01
            • 2015-06-17
            相关资源
            最近更新 更多