我有一个Android编程的问题。使用下面的代码,我想验证一个字符串匹配。它验证得很好,但是LogCat显示TextWatcher方法每次击键都会触发两次,我不知道为什么。我希望每次击键只触发一次。
你知道它为什么这样做吗?
我想这可能是因为我改变了文本的颜色,但在注释掉它之后并没有什么不同。
LogCat输出
03-31 03:37:25.269: I/BeforeText(676): Hit
03-31 03:37:25.269: I/OnText(676): Hit
03-31 03:37:25.269: I/AfterText(676): Hit
03-31 03:37:25.274: I/InvalidText(676): Incorrect Text.
03-31 03:37:25.274: I/Text Value(676): a
03-31 03:37:25.404: I/BeforeText(676): Hit
03-31 03:37:25.404: I/OnText(676): Hit
03-31 03:37:25.404: I/AfterText(676): Hit
03-31 03:37:25.404: I/InvalidText(676): Incorrect Text.
03-31 03:37:25.404: I/Text Value(676): a活动代码
public void onCreate(Bundle savedInstanceState) {
//...omitted
//Create Answer Field
textField = (EditText)this.findViewById(R.id.textField);
//Add validation to TextField
textField.addTextChangedListener(new TextWatcher(){
public void afterTextChanged(Editable s){
Log.i("AfterText","Hit");
if(textField.getText().toString().trim().equalsIgnoreCase("hello")){
Log.i("ValidText", "Text matched.");
answerField.setTextColor(Color.GREEN);
}
else{
Log.i("InvalidText", "Incorrect text.");
Log.i("Text Value", textField.getText().toString());
textField.setTextColor(Color.RED);
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){
//Do nothing
Log.i("BeforeText", "Hit");
}
public void onTextChanged(CharSequence s, int start, int before, int count){
//Do nothing
Log.i("OnText","Hit");
}
});
}发布于 2012-03-31 13:36:18
由于您的问题针对的是,因此每次击键都会触发两次TextWatcher方法。您已经在EditText上为验证字符串和设置颜色使用了TextWather for Make watch。
你可以在这里参考开发者站点上的TextWatcher文档。http://developer.android.com/reference/android/text/TextWatcher.html。
因为当您按下keystore时,它将以TextWatcher方法onTextChanged调用方式在EditText文本中进行更改,当您为EditText方法beforeTextChanged按任何键时,这将在我们开始编辑EditText时调用。
还有一件事是,当你在EditText中输入一个字符时,它会调用Textwather的所有三个方法,.Just sequence .Just different.and也引用这个问题Android TextWatcher.afterTextChanged vs TextWatcher.onTextChanged
所以没有任何错误会在EditText中调用两次来更改文本。
希望你能理解。
发布于 2014-01-28 05:40:57
我不认为这会对你有帮助,但在我的情况下,它似乎是卷帘键盘。
关键是,当swipe试图提出建议时,onchange方法似乎被调用了两次(一次来自EditText,另一次来自swipe键盘)。
我不知道这在您的代码中是否可行,但只要在您的EditText上尝试一下,看看会发生什么:
android:inputType="textNoSuggestions"你可以查看下一个讨论这个问题的网站:
http://support.swiftkey.net/forums/116693-2-bug-reports/suggestions/2994580-span-exclusive-exclusive-spans-cannot-have-a-zero-
如果我找到了解决方案,我会编辑这个答案。
编辑
我的结论是,我无法避免中间事件,也无法区分来自用户的真实更改事件和滑动更改事件。
根据您的实际问题,您应该尝试不同的解决方法。一种解决方法是将更新的信息保存在ConcurrentHashMap中,并在收到事件后100毫秒安排一个任务。同时,你应该设置一个"lastModified“日期。
在计划任务中,你应该问“从上次更新到现在已经过去100毫秒了吗?”,如果答案是否定的-->什么也不做(这意味着另一个事件已经到达,所以另一个更新任务将使用最后一个值执行)。
许多公司都有一个ReentrantLock来实现原子性。
如下所示:
private final ReentrantLock lock = new ReentrantLock();
private final ScheduledExecutorService scheduleExecutor = new ScheduledThreadPoolExecutor(1);
private Date lastModification = null;
private static final long UPDATE_WINDOW_IN_MILLISECONDS = 100;
protected class UpdateBusinessLogicTask implements Runnable {
private final String newVal;
public UpdateBusinessLogicTask(String newVal) {
super();
this.newVal = newVal;
}
@Override
public void run() {
//check current date
Date now = new Date();
//get lock to achieve atomicity
lock.lock();
// calculate elapsed time
long elapsedTime = lastModification.getTime() - now.getTime();
// free the lock --> you could free the lock after business logic, depends on your scenario
lock.unlock();
//if the time is less than the updating window (100 milliseconds)
if (elapsedTime < (UPDATE_WINDOW_IN_MILLISECONDS - 1)) {
// DO NOTHING!!
Log.d("TEST", "Dismiss update "+newVal);
} else {
Log.d("TEST", "Updating business with newVal: "+newVal);
// TODO implement business logic
}
}
};
protected void onCreate(Bundle savedInstanceState) {
EditText view = findViewById(R.id.nameEditText);
TextWatcher tw = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d("TEST", "New text event received, new val: " + s.toString());
lock.lock();
lastModification = new Date();
scheduleExecutor.schedule(new UpdateBusinessLogicTask(s.toString()), UPDATE_WINDOW_IN_MILLISECONDS, TimeUnit.MILLISECONDS);
lock.unlock();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
};
}发布于 2014-03-24 23:00:51
也许你有两个textWatchers,textField.addTextChangedListener方法被调用两次。
https://stackoverflow.com/questions/9952907
复制相似问题