gpt4 book ai didi

android - EditText 长度过滤器无法正常工作

转载 作者:行者123 更新时间:2023-11-30 00:06:35 28 4
gpt4 key购买 nike

首先我不得不说我在 SO 上阅读过类似的问题和答案,这个问题基本上是 this question 的重复和许多其他问题,但对这些问题的回答并不像我想要的那样。

问题:

像这样以编程方式在我的 EditText 上设置长度过滤器:

editText.setFilters(new InputFilter[]{new LengthFilter(10)} );

它唯一做的就是隐藏超出 EditText 限制的文本。它仍然在建议框中显示长(无限制)文本,我必须删除(退格)每个经过的字母,然后才能删除 EditText 中显示的内容。

建议的解决方案:

  1. 将 InputType 设置为 textFilter

    我以编程方式这样做了:

    editText.setInputType( InputType.TYPE_TEXT_VARIATION_FILTER );

    它隐藏了建议,但无限文本仍然存在,我仍然必须使用退格键删除不应该出现的字母。

  2. 将 InputType 设置为 textNoSuggestions|textVisiblePassword

    我以编程方式执行了此操作(也必须添加 TYPE_CLASS_TEXT 否则它将不起作用):

    editText.setInputType( InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD );

    这个确实有效,但问题是它停止了“手势输入”并将字体更改为等宽字体。

更好的解决方案?
如您所见,如果没有其他问题,这两种方法实际上并不能正常工作。还有其他我错过的方法吗?如果我想保持手势输入和建议,是否应该只使用 TextWatcher

最佳答案

我最终改用了 TextWatcher。我不确定这是否是执行此操作的最佳方法,但它确实适用于建议,并且不会关闭手势输入或更改字体样式。这是我的做法(我对 Android 很陌生,所以如果需要改进,请随时告诉我)。

我在评论中添加了一个示例来阐明发生了什么。

制作这些全局变量:

private boolean mWatcherIsBlocked = false;
private String mBeforeChange;
private String mFilteredString;
private int mCursorPosition = 0;

然后创建 TextWatcher 并将其添加到您的 EditText

final int maxLength = 10; // desired length limit

/**
* lets say our EditText is showing "abcdefgh". We select "cdef" from it and
* paste a new text "ijklmnop" in the middle. What we should get according to
* our maxLength is this:
* (1) "ab" (0th up to the letter from before_change_text we were selecting) +
* (2) "ijklmn" (part of the text we pasted minus the number of letters the whole
* after_change_text goes over the 10 letter limit) +
* (3) "gh" (last part of before_change_text that wasn't selected)
*
* so the new text has to be "abijkmngh"
*/

TextWatcher textWatcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// get before_change_text if textWatcher isn't blocked
if (!mWatcherIsBlocked) mBeforeChange = s.toString();
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (!mWatcherIsBlocked){
// get after_change_text if textWatcher isn't blocked
String after = s.toString();
// if after_change_text's length is bigger than the limit
if (after.length() > maxLength) {
// see how much it goes over the limit
int over = after.length() - maxLength;
// add parts (1) and (2) like our example above
String st = mBeforeChange.substring(0, start) + // (1)
after.substring(start, start + count - over); // (2)
// get where the cursor position should be after pasting (
// = after the last letter we could paste = length of (1) + (2) )
mCursorPosition = st.length();
// now add part (3) of our text to the first two
st += mBeforeChange.substring(
mBeforeChange.length() - (maxLength - st.length()),
mBeforeChange.length());
// now assign this new text to a global variable
mFilteredString = st;
} else {
// if after_change_text hasn't gone over the limit assign it
// directly to our global variable
mFilteredString = s.toString();
}
}
}
@Override
public void afterTextChanged(Editable s) {
// if filtered text is not the same as unfiltered text
// or textWatcher is not blocked
if (!mFilteredString.equals(s.toString()) && !mWatcherIsBlocked) {
// block textWatcher to avoid infinite loops created by setText
// (this might not work as I well as I think!)
mWatcherIsBlocked = true;
// set new text to our EditText
editText.setText(mFilteredString);
// set its cursor position
editText.setSelection(mCursorPosition);
// unblock the textWatcher
mWatcherIsBlocked = false;
}
}
};

// add the TextWatcher to our EditText
editText.addTextChangedListener(textWatcher);

关于android - EditText 长度过滤器无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48869190/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com