我应该用什么android:inputType来输入IP地址?

时间:2011-12-28 22:15:12

标签: java android android-layout android-widget

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

很自然地,我希望进行优化以便让他们轻松输入IP地址,但是切换到字母数字输入主机名的能力非常重要。

我似乎无法找到一个好的inputType。 numberDecimal最初似乎是一个很好的镜头,但它只允许一个点。

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

我如何到达那里?

13 个答案:

答案 0 :(得分:52)

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

答案 1 :(得分:40)

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

输入时请参阅this answer进行验证。

答案 2 :(得分:20)

这通过添加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"/>

答案 3 :(得分:13)

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

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);

答案 4 :(得分:5)

使用它:

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

答案 5 :(得分:2)

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

为我工作

答案 6 :(得分:1)

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

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

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

答案 7 :(得分:1)

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

请参阅:
Android: How can I validate EditText input?
Validating IP in android

答案 8 :(得分:1)

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

答案 9 :(得分:1)

这是允许您显示仅包含数字和一个点(但允许您输入多个点)的软键盘的代码。

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

答案 10 :(得分:0)

也许如果您使用2个radiobutton,一个显示主机的edittext,另一个显示IP的4个数字edittext,然后,一旦用户提交数据,您将所有4个edittext值连接在它们之间,如下所示,edittext1 .getText()+“。” + edittext2.getText()+“。” edittext3.getText()+“。” edittext4.getText(),这样你就可以获得一个经过验证的IP地址,但显然它会带来更多的工作。

答案 11 :(得分:0)

尝试使用android:inputType="textUri"。当您需要主机名或IP地址时,它可以正常工作。

答案 12 :(得分:0)

SKT的答案运行良好,直到InputFilter通过Spannables。跨度难以处理,例如在this question的ins答案中进行了描述。在这种情况下,返回""进行无效输入将用一个空字符串替换整个文本。我也修改了解决方案来处理这种情况。这是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
})