我正在尝试解决搜索栏的问题。它有效,但问题是,如果我几乎同时按下两个键,则该应用程序只会在按下第一个键的情况下搜索单词。
以下是日志:
在这一步中,当我先按P再按R时,它将起作用:
[EDT] 0:4:9,283-p
[EDT] 0:4:9,348-10
[EDT] 0:4:9,660-pr
[EDT] 0:4:9,722-3
第二个不是因为我几乎同时按下P和R:
[EDT] 0:4:35,237-p
[EDT] 0:4:35,269-pr
[EDT] 0:4:35,347-0
[EDT] 0:4:35,347-10
生成此处的日志以显示搜索到的String
和结果大小。如您所见,第一种情况在键入下一个字符之前得到结果,第二种情况在键入两个字符时得到所有结果。
主要问题是在第二种情况下,显示的是'p'字符串的结果,而不是'pr'的结果。
我正在将Toolbar
API中的搜索栏与addSearchCommand
和InfiniteContainer
一起使用以显示结果数据。
从addSearchCommand
处理事件的顺序是否会出现问题?
编辑:这是客户端代码。在服务器端,这只是一个简单的rest服务调用,可以从数据库中获取数据。
public static ArrayList<Patient>getSearchedPatient(int index,int amount, String word)
{
ArrayList<Patient> listPatient = null;
Response reponse;
try {
reponse = RestManager.executeRequest(
Rest.get(server + "/patients/search")
.queryParam("index", String.valueOf(index))
.queryParam("amount", String.valueOf(amount))
.queryParam("word", word),
RequestResult.ENTITIES_LIST,
Patient.class);
listPatient = (ArrayList<Patient>)reponse.getResponseData();
Log.p(""+listPatient.size());
} catch (RestManagerException e) {
LogError("", e);
}
return listPatient;
}
private static Response executeRequest(RequestBuilder req, RequestResult type, Class objectClass) throws RestManagerException
{
Response response = null;
try {
switch (type) {
case BYTES:
response = req.getAsBytes();
break;
case JSON_MAP:
response = req.acceptJson().getAsJsonMap();
break;
case ENTITY:
response = req.acceptJson().getAsProperties(objectClass);
break;
case ENTITIES_LIST:
response = req.acceptJson().getAsPropertyList(objectClass);
break;
default:
case STRING:
response = req.getAsString();
break;
}
} catch (Exception e) {
log().error("Erreur à l'exécution de la requête", e);
response = null;
}
if(response == null)
return null;
return response;
}
最佳答案
因此,这里的技巧很简单。不要发出请求...大多数用户输入的速度足够快,足以使您的网络连接速度饱和,因此您将看到有关不再相关的内容的完成建议。
这是一个不平凡的实现,我将在实现这种功能的Uber book中深入讨论。
解决方案是在缓存响应的延迟后发送请求,以避免重复请求,并且在适用时最好取消正在进行的请求。 Uber书中的解决方案完成了所有这3个工作,我将尝试仅介绍此样机代码中的基础知识。首先,您需要一个用于计时器和当前请求的字段。理想情况下,您还将拥有一个包含缓存数据的地图:
private UITimer delayedRequest;
private String currentSearch;
private Map<String, String> searchCache = new HashMap<>();
然后,您需要像这样绑定一个侦听器:
tb.addSearchCommand(e -> {
String s = (String)e.getSource();
if(s == null) {
if(delayedRequest != null) {
delayedRequest.cancel();
delayedRequest = null;
}
return;
}
if(currentSearch != null && s.equals(currentSearch)) {
return;
}
if(delayedRequest != null) {
delayedRequest.cancel();
delayedRequest = null;
}
currenSearch = s;
delayedRequest = UITimer.timer(100, false, () -> {
doSearchCode();
});
});
我这里没有包括缓存的使用,您需要在搜索方法中检查并填写结果代码。我也没有实施取消请求。
关于codenameone - 如何处理几乎同时按下的按键?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54692265/