duanshai4484 2016-02-26 05:22
浏览 78
已采纳

键入Android时动态搜索

I have an EditText field for which I implemented an TextChangedListener. In the afterTextChanged method I call a Volley method which sends the text the user has input to my php script which then queries around 20k records in an online mySQL database for all records which have the user input as a prefix. These are then displayed on screen in a ListView to the user. This works very well when I type at a reasonable pace or when I view my results to see if what I am looking for has appeared before typing the next letter. However, if I type the whole word without stopping, or type a whole word, delete it and type a new word very fast, which I'm sure some users will do, the search becomes laggy since so many Volley requests are called. I am thinking about how to improve the efficiency of this, so that even when the user types very fast, these problems won't arise. My code is below:

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条回答 默认 最新

  • doubu4406 2016-02-26 05:26
    关注

    Even we faced similar kind of issue. What we did was, we put a time period say 1 second or 2 second. So i will call the api whenever there is a time gap of 1 or two seconds between consecutive key events or you can say user takes this much time/pause in typing instead of calling the api everytime something is edited in the edittext.

    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
       );
      }
     }
    );
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 这个电路是如何实现路灯控制器的,原理是什么,怎么求解灯亮起后熄灭的时间如图?
  • ¥15 matlab数字图像处理频率域滤波
  • ¥15 在abaqus做了二维正交切削模型,给刀具添加了超声振动条件后输出切削力为什么比普通切削增大这么多
  • ¥15 ELGamal和paillier计算效率谁快?
  • ¥15 file converter 转换格式失败 报错 Error marking filters as finished,如何解决?
  • ¥15 ubuntu系统下挂载磁盘上执行./提示权限不够
  • ¥15 Arcgis相交分析无法绘制一个或多个图形
  • ¥15 关于#r语言#的问题:差异分析前数据准备,报错Error in data[, sampleName1] : subscript out of bounds请问怎么解决呀以下是全部代码:
  • ¥15 seatunnel-web使用SQL组件时候后台报错,无法找到表格
  • ¥15 fpga自动售货机数码管(相关搜索:数字时钟)