如何处理几乎同时按下的按键?

时间:2019-02-14 14:04:58

标签: codenameone

我正在尝试解决搜索栏的问题。可以,但是问题是,如果我几乎同时按下两个键,则该应用程序只会在按下第一个键的情况下搜索单词。

以下是日志:

在此示例中,当我按 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;

}

1 个答案:

答案 0 :(得分:1)

因此,这里的技巧很简单。不要发出请求...大多数用户输入的速度足够快,足以使您的网络连接速度饱和,因此您将看到完成建议,这些建议指的是不再相关的内容。

这是一个不平凡的实现,我在实现这种功能的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();
    });
});

我这里没有包括缓存的使用,您需要在搜索方法中检查并填写结果代码。我也没有实施取消请求。