我正在尝试解决搜索栏的问题。它有效,但问题是,如果我几乎同时按下两个键,则该应用程序只会在按下第一个键的情况下搜索单词。
以下是日志:
在这一步中,当我先按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中的搜索栏与addSearchCommandInfiniteContainer一起使用以显示结果数据。
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/

10-10 23:31