【问题标题】:Efficient way to implement Search functionality in android在android中实现搜索功能的有效方法
【发布时间】:2015-10-02 06:02:14
【问题描述】:

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

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

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

任何可以使事情顺利进行的建议或更改。

    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


                }
            });

异步任务获取搜索标签

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();
            }
        }

    }

【问题讨论】:

  • “高效方式”是使用adapter的过滤实现,见Filterableinterface
  • 我第一次没有得到你,我需要使用异步任务来获得结果
  • 再看android.widget.Filterable接口
  • 我使用了 searchadapter.getFilter() 并且还制作了filter 接口

标签: android android-asynctask android-search


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我会建议你做以下事情:

    • 使用相同的 AsyncTask,不要忘记取消前一个,因为它们可能只是相互叠加,从而减慢了整个过程
    • 在你的 AsyncTask 里面做:

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

    【讨论】:

    • 我不会在输入每个单词后发送 web 服务。只有在第一个单词类型的数据被绑定之后。​​但直到数据被绑定之前,用户必须等待或手机处于不可用状态。跨度>
    猜你喜欢
    • 1970-01-01
    • 2011-03-03
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-12
    相关资源
    最近更新 更多