android-EditText长度过滤器无法正常工作
首先,我必须说,我在这里读过类似的问题和答案,所以这个问题基本上是和其他许多问题的重复,但是这些问题的答案并不是我想要的那样 问题: 以编程方式在我的EditText上设置长度筛选器,如下所示:android-EditText长度过滤器无法正常工作,android,android-edittext,android-inputtype,android-input-filter,Android,Android Edittext,Android Inputtype,Android Input Filter,首先,我必须说,我在这里读过类似的问题和答案,所以这个问题基本上是和其他许多问题的重复,但是这些问题的答案并不是我想要的那样 问题: 以编程方式在我的EditText上设置长度筛选器,如下所示: editText.setFilters(new InputFilter[]{new LengthFilter(10)} ); 它所做的唯一一件事就是在EditText中隐藏超出限制的文本。它仍然在建议框中显示长(无限)文本,我必须删除(退格)每个字母,然后才能删除编辑文本中显示的内容 建议的解决方案:
editText.setFilters(new InputFilter[]{new LengthFilter(10)} );
它所做的唯一一件事就是在EditText中隐藏超出限制的文本。它仍然在建议框中显示长(无限)文本,我必须删除(退格)每个字母,然后才能删除编辑文本中显示的内容
建议的解决方案:
textFilter
通过编程,我做到了这一点:
editText.setInputType( InputType.TYPE_TEXT_VARIATION_FILTER );
它隐藏了建议,但无限文本仍然存在,我仍然必须使用退格删除不应该存在的字母textNoSuggestions | textVisiblePassword
我通过编程实现了这一点(必须添加
TYPE\u CLASS\u TEXT
,否则它将无法工作):
这一个确实有效,但问题是它停止了“手势输入”,并将字体更改为单空格如您所见,如果没有其他问题,这两种方法实际上无法工作。有没有其他我错过的方法。如果我想保持手势输入和建议,我应该只使用
文本观察程序吗?我最终使用了文本观察程序。我不确定这是否是最好的方法,但它确实可以提供建议,并且不会关闭手势输入或更改字体样式。下面是我是如何做到的(我对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);
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);