如何在 android 中通过软键盘编程将我的 EditText 输入限制为一些特殊字符,如反斜杠(/)、 tild (~)等

我正在开发一个键盘应用程序,但我得到了一个问题。 我想限制/阻止一些特殊的字符从软键盘编辑文本在 android 编程。

那么,有没有什么办法我可以限制任何特殊字符输入编辑文本在安卓系统。

如有任何意见,请回复。

先谢谢你。

96657 次浏览

检查显示 如何限制 Android EditText 字段中的特殊字符?这个链接

试试这个代码 我想这是最简单的方法。希望这对你有所帮助。

您可以创建正则表达式并在 onTextChanged 方法上检查它

yourEditText.addTextChangedListener(new TextWatcher() {


public void afterTextChanged(Editable s) {


// you can call or do what you want with your EditText here
yourEditText. ...


}


public void beforeTextChanged(CharSequence s, int start, int count, int after) {}


public void onTextChanged(CharSequence s, int start, int before, int count) {}
});

这应该会奏效:

InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (!Character.isLetterOrDigit(source.charAt(i))) {
return "";
}
}
return null;
}
};


edit.setFilters(new InputFilter[]{filter});

或者如果你更喜欢简单的方式:

<EditText android:inputType="text" android:digits="0123456789*,qwertzuiopasdfghjklyxcvbnm" />

试试这个可能对你有用

public class MainActivity extends Activity {


private EditText editText;
private String blockCharacterSet = "~#^|$%&*!";


private InputFilter filter = new InputFilter() {


@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {


if (source != null && blockCharacterSet.contains(("" + source))) {
return "";
}
return null;
}
};


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.editText);
editText.setFilters(new InputFilter[] { filter });
}


}

虽然晚了点,但对其他人可能有帮助。 您可以使用 xml 属性而不是编程方式。在 Single 布局中,可能有许多 edit Text,您希望仅在一个 EditText 中限制其中的特殊字符。因此,在 xml 中定义将帮助您解决这个问题。下面是限制特殊字符的代码,允许它们只输入字母和数字,如下所示

<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="@dimen/text10"
android:singleLine="true"
android:maxLines="1"
android:maxLength="16"
android:digits="abcdefghijklmnopqrstuvwxyz0123456789"/>

如果要添加空格,可以在最后一个数字之后给出空格。

  android:digits="0123456789qwertzuiopasdfghjklyxcvbnm "

对于那些可能面临的问题,同时增加空间,请添加一个空白空间与所有的字母。下面是一个例子 您还应该知道,在这种情况下,用户不能添加新行。

            <EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:digits="0123456789,a bcdefghijklmnopqrstuvwxyz"
android:maxLines="1"
android:singleLine="true" />

首先需要添加允许字符的 DigitsKeyListener,然后将 setRawInputType 添加到 edit 文本字段

edit_field.setKeyListener(DigitsKeyListener.getInstance("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"));




edit_field.setRawInputType(InputType.TYPE_TEXT_VARIATION_PERSON_NAME);

可以防止输入特殊字符:

yourEditText.addTextChangedListener(new TextWatcher() {
CharSequence previous;
public void afterTextChanged(Editable s) {
if(s.toString().contains("&^%$#*&(")){
s.clear();
s.append(previous.toString());
}
}


public void beforeTextChanged(CharSequence s, int start, int count, int after) {
previous = s;
}


public void onTextChanged(CharSequence s, int start, int before, int count) {}
});

不幸的是,公认的解决方案并不适用于所有情况。正确的解决方案是使用以下 InputFilter:

private InputFilter filter = new InputFilter() {
// An example pattern that restricts the input only to the lowercase letters
private static final Pattern restrictedChars = Pattern.compile("[a-z]*")


@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
final CharSequence replacementText = source.subSequence(start, end);
final CharSequence replacedText = dest.subSequence(dstart, dend);


if (source == null || restrictedChars.matcher(replacementText).matches()) {
return null; // Accept the original replacement
}


return replacedText; // Keep the original text
}
};

这种解决办法不同于公认的解决办法,因为它解决了以下问题:

  • 只有源的子序列是替换的,而不是完整的源
  • Source 不一定只包含新键入的文本,有时它是迄今为止键入的全文

Kotlin 版本的答案

class NameActivity : AppCompatActivity() {


var myFilter =
InputFilter { source, _, _, _, _, _ ->
try {
val c = source[0]
return@InputFilter if (Character.isLetterOrDigit(c)  || c == '_' || c == '.') {
"$c"
} else {
// here you can show error msg
""
}
} catch (e: Exception) {
}
null
}




override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_name)
val edittext = findViewById<EditText>(R.id.edittext)
edittext.filters = (arrayOf(myFilter))
}


}

这对我有用。

android:digits="÷×=%_-+#().,abcdefghijklmnopqrstuvwxyzA BCDEFGHIJKLMNOPQRSTUVWXYZ1234567890\n\u0020"

空间用途:

\u0020

新线路使用:

\n

使用时间选项:

android:singleLine="true"
android:maxLines="1"

希望对你有用。

接受的答案仍然允许用户粘贴不需要的字符。这个解决方案可行:


你要做的就是:

List<String> unwantedChars = new ArrayList<>(Arrays.asList("@", "€"));
editText.addTextChangedListener(new FilterUnwantedChars(editText, unwantedChars));

辅导员类别:

public class FilterUnwantedChars implements TextWatcher {


private List<String> unwantedChars;
private EditText editText;


private boolean listenToTextChange;


public FilterUnwantedChars(EditText editText, List<String> unwantedChars) {
this.unwantedChars = unwantedChars;
this.editText = editText;
this.listenToTextChange = true;
}


@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }


@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!listenToTextChange) {
listenToTextChange = true;
return;
}


String result = s.toString();
final String oldString = result;
for (String unwanted : unwantedChars) {
result = result.replace(unwanted, "");
}


if (!oldString.equals(result)) {
listenToTextChange = false;
int currentPos = editText.getSelectionStart()-1;
editText.setText(result);


try {
editText.setSelection(currentPos);
} catch (Exception e) {
// nothing
}
}
}


@Override
public void afterTextChanged(Editable s) { }


public void setEditText(EditText editText) {
this.editText = editText;
}


public EditText getEditText() {
return editText;
}


public List<String> getUnwantedChars() {
return unwantedChars;
}


public void setUnwantedChars(List<String> unwantedChars) {
this.unwantedChars = unwantedChars;
}
}


可以用 filters解决。

val regex = Regex("^[~#^|$%&*!]*$")
val filter = InputFilter { source, _, _, _, _, _ ->
return@InputFilter when {
source?.matches(regex) == true -> ""
else -> null
}
}
editText.filters = arrayOf(filter)

为了处理 copy-pasted文本,可以通过添加条件来检查输入的文本是否大于 1,现在看起来是这样的

val regex = Regex("^[~#^|$%&*!]*$")
val filter = InputFilter { source, _, _, _, _, _ ->
return@InputFilter when {
source?.matches(regex) == true -> ""
source.length > 1 -> source.trim { it.toString().matches(regex) } // Put your desired logic here, these sample logic was doing a trim/remove
else -> null
}
}
editText.filters = arrayOf(filter)