2015-10-01 50 views
0

我想在android中实现搜索功能,通过从webservice收到的结果绑定数据。在android中实现搜索功能的有效方法

这是行得通的,但问题在于它的滞后性。 例如在输入第一个单词后,它会等待结果出现,然后输入下一个单词。

它是因为异步任务在第一个单词上运行而点击。但它烦人等待用户。

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

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 


       } 
      }); 

异步任务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"); 
      } 
     } 


    } 

Filter接口

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

    } 
+0

“高效的方式” 是使用适配器的过滤实现,请参阅'Filterable'接口 – pskink

+0

我没有让你第一次atleast我需要使用异步任务来获得结果 –

+0

再次,请参阅'android.widget.Filterable'接口 – pskink

回答

0

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

0

我会建议你做以下事情:

  • 使用相同的AsyncTask,不要忘记,取消以前的一个,因为他们可能只是在彼此叠加起来,因此,整个减缓事情
  • 里面你的AsyncTask的事:

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

每个输入的单词后我都没有发送web服务。只有在输入第一个单词的数据后才会绑定数据,但直到绑定数据时,用户必须等待或者电话处于不可用状态。 –