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

标签 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 中的事件顺序有问题吗?被治疗?
编辑:这是客户端代码。服务器端它只是一个简单的休息服务调用,它从数据库中获取数据。
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/

相关文章:

java - 代号 一个日历更改选定日期的样式

parse-platform - (Proguard) 服务器构建错误代号一

sqlite - codenameone 在 sqlite 中将 boolean 值存储为 true/false,而它们应该是 1/0

codenameone - 如何更改 Codename One 中 SpanLabel 的字体?

java - 代号一 - 存储敏感数据

java - 代号一 - 在 iOS 上屏蔽和取消屏蔽密码字段

java - 从数组循环创建动态按钮时,代号一给出 java NullPointerException 错误

codenameone - 为什么在代号一中禁止使用带有两个点的版本字符串?

java - 如何避免 codenameone 中的表单重叠?

java - 适用于 Android、iOS 和黑莓的 Codenameone 应用内计费