简体   繁体   中英

What android:inputType should I use for entering an IP Address and hostname?

I am building a small Android app where the user will enter an IP address or a hostname into an EditText widget. 90% of the time they will be entering an IP address, the rest of the time - a hostname.

So naturally, I want to make it easy for them to enter an IP address, but the ability to switch to alpha numerics for hostname entry is important.

I can't seem to find a good inputType. The numberDecimal initially seemed like a good shot, but it only allows one dot.

Ideally, I'd like to start with a standard keyboard that had the ?123 button pressed.

How do I get there?

Try using android:inputType="number" , but also set android:digits="0123456789." . Works for me.

If you use inputType="phone" you gain access to a cut down keyboard containing Numbers and a Period character - this doesn't restrict the input with regards to the amount of Periods you can enter.

Please see this answer for validation while being entered.

This works perfectly keyboard with numbers and decimal by adding android:inputType="number|numberDecimal" and android:digits="0123456789."

Example

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

You can use your own input filter for that

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

use this :

<EditText
    android:id="@+id/txtIP"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    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"/>

worked for me

Maybe if you use 2 radiobutton, one shows an edittext for host, the other one shows 4 numeric edittext for IP, then, once the user submit data you concat all 4 edittext values with dots between them, something like this, edittext1.getText() + "." + edittext2.getText() + "." edittext3.getText() + "." edittext4.getText() so you can obtain a validated IP address like that but obviously it will imply more work.

Here is the code that allows you to display a soft keyboard with only numbers and a dot (but allows you to enter multiple dots).

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

I think your only option is..

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

You could possible check the Text for 3 dots a IP address contains

I think you need to use TextWatcher for validation, register it with TextView.addTextChangedListener() method and use Pattern.DOMAIN_NAME and Pattern.IP_ADDRESS (Android 2.2+).

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

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

SKTs answer is working pretty well until the InputFilter passes Spannables . Spannables are tricky to handle which is described for example ins answers of this question . In this case, returning "" for invalid input will replace the whole text by an empty string. I've adapted the solution also to handle this case. Here is the code, differing the types, in 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
})

Try using android:inputType="textUri" . It works especially well when you want hostname or IP address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM