键入Android时动态搜索

时间:2016-02-26 05:22:25

标签: java php android mysql actionlistener

我有一个EditText字段,我为其实现了TextChangedListener。在afterTextChanged方法中,我调用了一个Volley方法,该方法将用户输入的文本发送到我的php脚本,然后查询在线mySQL数据库中的大约20k条记录,查找以用户输入为前缀的所有记录。然后将这些内容显示在屏幕上ListView给用户。当我以合理的速度键入或者在查看我的结果以查看我在寻找下一个字母之前是否出现了什么时,这非常有效。但是,如果我在不停止的情况下输入整个单词,或者输入整个单词,请将其删除并快速输入一个新单词,我相信一些用户会这样做,因为调用了很多Volley请求,搜索会变得迟钝。我正在考虑如何提高效率,这样即使用户输入速度非常快,也不会出现这些问题。我的代码如下:

TEXTCHANGEDLISTENER:

enter_search.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {

                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    if (enter_search.getText().toString().length() >=2) {
                        cityresults.clear();
                        queryCity(enter_search.getText().toString());
                    }
                    else {
                        cityresults.clear();
                        cityresults.add(new City("Please refine your search.",""));
                        ArrayAdapter<City> adapter = new EmptyAdapter();
                        final ListView listView = (ListView) findViewById(R.id.list_view);
                        listView.setAdapter(adapter);
                    }
                }
            });

VOLLEY:

public void queryCity(final String query) {

    request = new StringRequest(Request.Method.POST, SL_URL, new Response.Listener<String>() {
        @Override
        public void onResponse(String s) {
            try {
                cityresults.clear();
                JSONArray jsonArray = new JSONArray(s);
                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject a = jsonArray.getJSONObject(i);
                    cityresults.add(new City(a.getString("ascii_name"),(a.getString("timezone"))));
                }
                if (cityresults.isEmpty()) {
                    cityresults.add(new City("Please refine your search.",""));
                    ArrayAdapter<City> adapter = new EmptyAdapter();
                    final ListView listView = (ListView) findViewById(R.id.list_view);
                    listView.setAdapter(adapter);
                }
                else {
                    ArrayAdapter<City> adapter = new MyListAdapter();
                    final ListView listView = (ListView) findViewById(R.id.list_view);
                    listView.setAdapter(adapter);
                }


                }
             catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError volleyError) {

        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("search_query", query);
            return hashMap;
        }
    };
    queue.add(request);
}

1 个答案:

答案 0 :(得分:4)

即使我们遇到类似的问题。我们做的是,我们把时间段说1秒或2秒。因此,只要连续的键事件之间有1秒或2秒的时间间隔,我就会调用api,或者你可以说用户在编辑时需要花费很多时间/暂停而不是在编辑文本中编辑某些内容时调用api。

editText.addTextChangedListener(
 new TextWatcher() {
  @Override public void onTextChanged(CharSequence s, int start, int before, int count) {}
  @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

  private Timer timer = new Timer();
  private final long DELAY = 500; // milliseconds

  @Override
  public void afterTextChanged(final Editable s) {
   timer.cancel();
   timer = new Timer();
   timer.schedule(
    new TimerTask() {
     @Override
     public void run() {
      // refresh your list
     }
    },
    DELAY
   );
  }
 }
);