我需要一种方法来检测EditText是否已被用户输入内容或应用程序以编程方式更改文本而更改。这样做的任何标准方式?我想我总是可以做一些hackish,比如在setText()
之前取消TextWatcher并在之后重新设置它,但是必须有一个更好的方法来做到这一点......对吗?
我尝试检查EditText是否在TextWatcher中聚焦,但是由于EditTexts在滚动时无论如何都“半随机”聚焦,因此没有什么帮助......
背景
我在每个listitem都有一个带有EditTexts的ListView。我已经整理出了存储EditTexts值的基本问题,以便在用户滚动时重用。
我还有一个TextWatcher,用于汇总所有EditTexts中的值,并在用户编辑任何EditTexts的内容时显示总和。
问题是,当我滚动列表并且我的自定义适配器重新输入bindView()
上的EditTexts中的存储值时,这也会触发TextWatchers afterTextChanged()
方法,导致滚动延迟因为总结功能被触发了。
答案 0 :(得分:46)
很久以前就已经解决了这个问题,但对于那些在这里寻找答案的人来说,这就是我所做的:
在我即将以编程方式更改它,更改值,然后将Tag重置为null之前,我最终将EditText的Tag设置为某个任意值。然后在我的TextWatcher.afterTextChanged()方法中,我检查Tag是否为null,以确定它是用户还是更改了值的程序。像魅力一样工作!
这样的事情:
edit.setTag( "arbitrary value" );
edit.setText( "My Text Value" );
edit.setTag(null);
然后
public void afterTextChanged(Editable s) {
if( view.getTag() == null )
// Value changed by user
else
// Value changed by program
}
答案 1 :(得分:7)
接受的答案完全有效,但我有另一种方法;
@Override
public void onTextChanged(CharSequence charSequence,
int start, int before, int count) {
boolean userChange = Math.abs(count - before) == 1;
if (userChange) {
}
}
通过检查更改是否是单个字符来工作。 这不是一个万无一失的解决方案,因为可能会错过复制粘贴操作,并且也会错过单个字符的非用户更改。 根据您的使用情况,这可能是一个可行的解决方案。
答案 2 :(得分:1)
对我有帮助的一件事是拥有boolean canListenInput字段。在观察者中使用它。
email.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if (canListenInput) {
emailChanged = true;
}
}
});
在以编程方式更改文本之前清除它。将其设置在onAttachedToWindow中,(在状态之后)恢复:
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
canListenInput = true;
}
答案 3 :(得分:0)
根据您的用例(例如,当用户键入另一个字段时,您正在自动填充此字段),您还可以检查视图是否具有焦点,例如:
<input ... :value="getTimeSlot1Start(index)" @input="setTimeSlot1Start(index)" />
答案 4 :(得分:-1)
您可以通过添加:
来完成此操作private String current = "";
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(!s.toString().equals(current)){
[your_edittext].removeTextChangedListener(this);
//Format your string here...
current = formatted;
[your_edittext].setText(formatted);
[your_edittext].setSelection(formatted.length());
[your_edittext].addTextChangedListener(this);
}