在android中实现搜索功能的有效方法

时间:2015-10-01 06:00:07

标签: android android-asynctask android-search

我正在尝试在android中实现搜索功能,数据通过从webservice收到的结果进行绑定。

这是有效的,但问题是它有点滞后。 例如,在键入第一个单词后,它会等待结果,然后键入下一个单词。

这是因为异步任务在第一次单击时运行。但它让用户等待烦人。

任何可以使事情顺利进行的建议或改变。<​​/ p>

    public MultiAutoCompleteTextView editText1;
    ArrayList<setFilterItems> searchFilter=new ArrayList<setFilterItems>();

editText1.addTextChangedListener(new TextWatcher() {

                @Override

                public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                    // When user changed the Text


                    String cs1= cs.toString();

                    if (cs1.length() == 1) {
                        System.out.println("Size : "+searchFilter.size());
                        //if(searchFilter.size()<1) {
                            try {
                                result = new getSearchTags(cs.toString().toLowerCase(Locale.US)).execute().get();
                                System.out.println("yeh hai mera result " + result);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            } catch (ExecutionException e) {
                                e.printStackTrace();
                            }
                        //}else{
                        //     searchadapter.getFilter().filter(cs.toString().toLowerCase(Locale.US));
                        //}
                        //searchadapter.getFilter().filter(cs.toString().toLowerCase(Locale.US));
                    }
                    if (result.equals("1")) {
                                try {
                                    System.out.println("Pehle Baar");
                                    searchadapter.getFilter().filter(cs.toString().toLowerCase(Locale.US));
                                    }
                    catch(Exception e)
                                   {
                                    //System.out.println(e.getMessage().toString());
                                   }
                        }

                }

                @Override
                public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
                    //TODO Auto-generated method stub
                }

                @Override
                public void afterTextChanged(Editable arg0) {
                    //TODO Auto-generated method stub


                }
            });
  

ASYNC TASK getSearchTags

public class getSearchTags extends AsyncTask<String, Void, String> {
        private final String empId;

        public getSearchTags(String empId) {
            this.empId = empId;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected String doInBackground(String... params) {
            String result= Utils.getSearchTags(connString + "/GetSearchAutoComplete", empId);
            System.out.println("result :" + result + "||");
            if (null == result || result.length() == 2) {
                System.out.println("No results");
                return "0";
            }
            else {
                searchFilter.clear();
                try {

                    JSONArray jsonArray=new JSONArray(result);
                    System.out.println("Length :"+jsonArray.length());
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject objJson = jsonArray.getJSONObject(i);
                        setFilterItems objItem = new setFilterItems();
                        objItem.setID(objJson.getString("tag_id"));
                        objItem.setImage(objJson.getString("tag_type"));
                        objItem.setName(objJson.getString("tag_name"));

                        searchFilter.add(objItem);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("Exception:" + e.getLocalizedMessage() + "||");

                }
                return "1";
            }
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);
            if(result=="1") {
                //setAdapterToListview();
                searchadapter = new searchRowAdapter(MainActivity_old.this, R.layout.searchrow, searchFilter);
                editText1.setAdapter(searchadapter);
                editText1.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
                searchadapter.notifyDataSetChanged();
                editText1.showDropDown();
                System.out.println("Success");
            }else{
                System.out.println("Error");
            }
        }


    }
  

过滤界面

private class NameFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults filterResults = new FilterResults();
            if (constraint == null || constraint.length() == 0) {
                filterResults.values = originalList;
                filterResults.count = originalList.size();
            } else {
                final String lastToken = constraint.toString().toLowerCase();
                final int count = originalList.size();
                final List<setFilterItems> list = new ArrayList<setFilterItems>();
                setFilterItems contact;

                for (int i = 0; i < count; i++) {
                    contact = originalList.get(i);
                    if (contact.getName().toLowerCase().contains(lastToken)
                            || contact.getName().toLowerCase().startsWith(lastToken)) {
                        list.add(contact);
                    }
                }

                filterResults.values = list;
                filterResults.count = list.size();
            }
            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            list = (List<setFilterItems>) results.values;
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

    }

2 个答案:

答案 0 :(得分:0)

我还有一篇与良好搜索算法相关的帖子。经过大量的试验,在家中进行错误和测试。我做了一些运作正常的事情。没有时间敲定它,但这是一个很好的起点。
我的解决方案是一次加载所有数据,比如搜索第一个字母,抓取数据并将其存储在内存中,一旦用户输入字母,取出之前加载的列表。它将比从服务器加载更快。 一旦用户按下,问题就会出现。
我做的就像删除整个缓存并从服务器加载,每次用户按下时。
如果你愿意,你可以看看:
https://github.com/toaderandrei/loadcart
Stak post:
Live Search in Android
事情可以简化,这意味着它可以做得更好,简化一点。 例如,线程的数量以及与它们的交互。 希望它可以提供帮助。

答案 1 :(得分:0)

我建议你做以下事情:

  • 使用相同的AsyncTask,不要忘记取消之前的AsyncTask,因为它们可能只是相互堆叠,从而减慢了整个事情。
  • AsyncTask内部执行:

    protected void doInBackground(Void... args) {
        Thread.setPriority(MIN_PRIORITY)
        ...
    }