我正在尝试解决搜索栏的问题。它可以工作,但问题是如果我几乎同时按下两个键,应用程序只会搜索按下第一个键的单词。
以下是日志:
在这一个中,当我按 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
中的事件顺序有问题吗?被治疗?编辑:这是客户端代码。服务器端它只是一个简单的休息服务调用,它从数据库中获取数据。
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 项工作,我将尝试仅涵盖此模型代码中的基础知识。首先,您需要一个用于计时器和当前请求的字段。理想情况下,您还会有一个包含缓存数据的 map :
private UITimer delayedRequest;
private String currentSearch;
private Map<String, String> searchCache = new HashMap<>();
然后你需要像这样绑定(bind)一个监听器:
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/