Текстовое поле IP-адреса в Android?
Я абсолютно не знаком с Android.
Я хотел бы разместить текстовое поле, где пользователь может ввести IP-адрес... но как я могу ограничить пользователя только вводить числа?... и как я могу проверить?
Есть ли готовый ip-адрес-текстовое поле "там", которое я могу использовать?
Спасибо!
колдунства
Ответы
Ответ 1
Для подтверждения regular-expressions.info имеет хорошую строку регулярного выражения, которую вы могли бы использовать для тестирования IP в допустимом диапазоне (0-255)
\ Ъ (25 [0-5] | 2 [0-4] [0-9] |? [01] [0-9] [0-9]?) (25 [0-5]. | 2 [0-4] [0-9] | [01] [0-9] [0-9]) (25 [0-5] |?. 2 [0-4] [0-9] | [ 01] [0-9] [0-9]) (25 [0-5] |?. 2 [0-4] [0-9] |? [01] [0-9] [0-9]?)\б
Ответ 2
Что я нашел, что работает, это установить EditText
для использования android:inputType="phone"
, поэтому вход ограничивается цифрами, периодом и несколькими другими символами. Однако это позволит вам вводить адреса IPV4, поскольку они только цифры. Для проверки вам нужно будет получить входной текст и проанализировать его вручную.
Что касается готовых входных виджетах, я не сталкивался с ними.
Ответ 3
В дополнение к тому, что сказал Эрих, вы можете использовать android: digits = "0123456789." запретить ничего, кроме цифр и десятичной точки.
Ответ 4
Вы можете использовать:
EditText ipAddress = (EditText)findViewById(R.id.ip_address);
InputFilter[] filters = new InputFilter[1];
filters[0] = new InputFilter() {
@Override
public CharSequence filter(CharSequence source, int start, int end,
android.text.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;
}
};
ipAddress.setFilters(filters);
Ответ 5
Это, я думаю, самое полное из существующих решений для этого (по крайней мере, что я нашел). Единственное улучшение, которое я могу себе представить, - это реализовать новый KeyListener
, чтобы сдержать ввод лучше, но я не уверен, что это практически возможно, учитывая, как IME работают с макетами и т.д.
public class IPAddressText extends EditText {
public IPAddressText(Context context) {
super(context);
setInputType(InputType.TYPE_CLASS_PHONE);
setFilters(new InputFilter[] { new InputFilter(){
@Override
public CharSequence filter(CharSequence source, int start, int end, android.text.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;
}
}
});
addTextChangedListener(new TextWatcher(){
boolean deleting = false;
int lastCount = 0;
@Override
public void afterTextChanged(Editable s) {
if (!deleting) {
String working = s.toString();
String[] split = working.split("\\.");
String string = split[split.length - 1];
if (string.length() == 3 || string.equalsIgnoreCase("0")
|| (string.length() == 2 && Character.getNumericValue(string.charAt(0)) > 1)) {
s.append('.');
return;
}
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (lastCount < count) {
deleting = false;
}
else {
deleting = true;
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Nothing happens here
}
});
}
}
И поскольку это то, что я фактически использовал, вот версия EditTextPreference
:
public class IPAddressPreference extends EditTextPreference {
public IPAddressPreference(Context context) {
super(context);
getEditText().setInputType(InputType.TYPE_CLASS_PHONE);
getEditText().setFilters(new InputFilter[] { new InputFilter(){
@Override
public CharSequence filter(CharSequence source, int start, int end, android.text.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;
}
}
});
getEditText().addTextChangedListener(new TextWatcher(){
boolean deleting = false;
int lastCount = 0;
@Override
public void afterTextChanged(Editable s) {
if (!deleting) {
String working = s.toString();
String[] split = working.split("\\.");
String string = split[split.length - 1];
if (string.length() == 3 || string.equalsIgnoreCase("0")
|| (string.length() == 2 && Character.getNumericValue(string.charAt(0)) > 1)) {
s.append('.');
return;
}
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (lastCount < count) {
deleting = false;
}
else {
deleting = true;
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Nothing happens here
}
});
}
}
Ответ 6
Я использую этот TextWatcher:
public class IPTextWatcher implements TextWatcher
{
private static String LOG_TAG = "IPTextWatcher";
private EditText editText;
private BarcodeTextWatcher.ChangeListener listener = null;
public IPTextWatcher( EditText editText )
{
this.editText = editText;
}
private static final String IPADDRESS_PATTERN =
"^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
"([01]?\\d\\d?|2[0-4]\\d|25[0-5])$";
@Override
public void afterTextChanged( Editable s )
{
Log.v( LOG_TAG, s.toString() );
if( !s.toString().matches( IPADDRESS_PATTERN ) )
{
String ip = format( s.toString() );
editText.removeTextChangedListener( this );
editText.setText( ip );
editText.setTextKeepState( ip );
Selection.setSelection( editText.getText(), ip.length() );
editText.addTextChangedListener( this );
if( listener != null )
listener.onChange();
}
}
public static String format( String value )
{
String userInput = "" + value.replaceAll( "[^\\d\\.]", "" );
StringBuilder ipBuilder = new StringBuilder();
String[] address = userInput.split("\\.");
String glue = null;
for( String part : address )
{
if( glue != null ) ipBuilder.append( glue );
int p = Integer.valueOf( part );
if( p >= 256 )
{
int i = 1;
do
{
p = Integer.valueOf( part.substring( 0, part.length() -i ) );
i++;
}
while( p >= 256 );
}
ipBuilder.append( p );
glue = ".";
}
if( userInput.charAt( userInput.length()-1 ) == '.' )
ipBuilder.append( "." );
return ipBuilder.toString();
}
@Override
public void onTextChanged( CharSequence s, int start, int before, int count )
{
}
@Override
public void beforeTextChanged( CharSequence s, int start, int count, int after )
{
}
}
Ответ 7
<EditText
android:id="@+id/ip_address"
android:inputType="number|numberDecimal"
android:digits="0123456789."
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
работал у меня