我是Android新手。
我想放入一个用户可以输入IP地址的文本框...但是如何限制用户只输入数字? ......以及如何验证?
我可以使用现成的ip-address-textbox吗?
谢谢!
魔
答案 0 :(得分:13)
我发现有效的方法是将EditText
设置为使用android:inputType="phone"
,因此输入仅限于数字,句号和少数其他字符。但是,这只会让您输入IPV4地址,因为它只是数字。要进行验证,您必须获取输入文本并手动解析。
就现成的输入小部件而言,我没有遇到过。
答案 1 :(得分:9)
除了Erich所说的,你可以使用android:digits =“0123456789。”禁止除数字和小数点以外的任何内容。
答案 2 :(得分:8)
您可以使用:
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);
答案 3 :(得分:7)
对于验证,regular-expressions.info有一个很好的正则表达式字符串,可用于测试有效(0-255)范围内的IP:
\ B(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] ?)\ b'/ p>
答案 4 :(得分: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
}
});
}
}
答案 5 :(得分:0)
我正在使用此TextWatcher:
PySys System Test Framework (version 0.9.2): Console run test helper
Usage: pysys.py run [option]* [tests]*
where [option] includes;
-h | --help print this message
-r | --record record the test results in the working directory
-p | --purge purge the output subdirectory on test pass
-v | --verbosity STRING set the verbosity level (CRIT, WARN, INFO, DEBUG)
-a | --type STRING set the test type to run (auto or manual, default is both)
-t | --trace STRING set the requirement id for the test run
-i | --include STRING set the test groups to include (can be specified multiple times)
-e | --exclude STRING set the test groups to exclude (can be specified multiple times)
-c | --cycle INT set the the number of cycles to run the tests
-o | --outdir STRING set the name of the test output subdirectory
-m | --mode STRING set the user defined mode to run the tests
-n | --threads INT set the number of worker threads to run the tests (defaults to 1).
A value of 0 sets to the number of available CPUs
-X KEY=VALUE set user defined options to be passed through to the test and
runner classes. The left hand side string is the data attribute
to set, the right hand side string the value (True of not specified)
and where [tests] describes a set of tests to be run. Note that multiple test sets can be specified,
where none are given all available tests will be run. If an include group is given, only tests that
belong to that group will be run. If an exclude group is given, tests in the group will not be run.
The following syntax is used to select a test set;
test1 - a single testcase with id test1
:test2 - upto testcase with id test2
test1: - from testcase with id test1 onwards
id1:id2 - all tests between tests with ids test1 and test2
e.g.
pysys.py -vDEBUG --include MYTESTS test1:test4 test7
pysys.py -c2 -Xhost=localhost test1:
答案 6 :(得分:0)
<EditText
android:id="@+id/ip_address"
android:inputType="number|numberDecimal"
android:digits="0123456789."
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
为我工作
答案 7 :(得分:0)
基于我在kotlin中编写的NathanOliver's and enneract's代码,这是一个在删除一个点时插入一个点的变体。
class IpAddressEditText : AppCompatEditText {
constructor(context: Context) : super(context) {
init()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
init()
}
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
init()
}
private fun init() {
// phone input type to show the numeric keyboard in all kinds of devices
inputType = InputType.TYPE_CLASS_PHONE
// restrict the input of the characters specified in string bellow
keyListener = DigitsKeyListener.getInstance("0123456789.")
// InputFilter decides what can be typed
filters = arrayOf(InputFilter { source, start, end, dest, dstart, dend ->
if (end > start) {
val inputString = dest.toString()
val substring = inputString.substring(0, dstart) + source.subSequence(start, end) + inputString.substring(dend)
if (!substring.matches("^\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3}(\\.(\\d{1,3})?)?)?)?)?)?".toRegex())) {
// do not allow the input of:
// segments with more than 3 characters and less than 1;
// segments != 4;
return@InputFilter ""
} else {
val splits = substring.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
for (i in splits.indices) {
// don't allow a segment with a value more than 255
if (Integer.valueOf(splits[i]) > 255) {
return@InputFilter ""
}
}
}
}
null
})
// TextWatcher notifies what was typed
addTextChangedListener(object : TextWatcher {
var isDeleting = false
var lastCount = 0
override fun afterTextChanged(editable: Editable) {
if (!isDeleting) {
val inputString = editable.toString()
val segmentList = inputString.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val lastSegment = segmentList[segmentList.size - 1]
// each segment of the ip can have max size of 3 characters and a max value of 255
if (lastSegment.length == 3 || lastSegment.length == 2 && Integer.parseInt(lastSegment) > 25) {
// add a dot automatically if the conditions met
editable.append('.')
return
}
} else {
// add a dot in the same position where it was deleted
editable.insert(selectionStart, ".")
}
}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
isDeleting = lastCount >= count
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
// do nothing
}
})
}
}
答案 8 :(得分:0)
这是通过显示只有数字和一个点的软键盘限制用户只能输入数字和点的代码(但允许您输入多个点 s).
etIpAddress.setInputType(InputType.TYPE_CLASS_NUMBER);
etIpAddress.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL);
etIpAddress.setKeyListener(DigitsKeyListener.getInstance(false,false));
etIpAddress.setKeyListener(DigitsKeyListener.getInstance("0123456789."));