2017-06-05 97 views
2

我試圖在自定義適配器中使用getFilter方法實現搜索篩選器。通過ArrayList爲陣列名稱進行自定義搜索

有兩種通過列表搜索的模型。

  • 搜索項目的title
  • 搜索項目的genre[]

但我只是在這裏談論genre)。

下面的代碼工作正常,但我需要的僅僅是一個更自定義的方式來搜索genre[]

我想要實現的是:(我想什麼):

multi-keyword搜索,每個分類均具有,分離。例如:genre1,genre2

(我做了什麼)

當我鍵入genre1,genre2則給出了在流派這個序列中的項目,它不會給genre1,genre3,genre2,或者只是genre1

你能幫忙嗎?

用getFilter:

@Override 
public Filter getFilter() { 
    Filter filter = new Filter() { 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      dataList = (List<ProductLocal>) results.values; 
      notifyDataSetChanged(); 
     } 
     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults results = new FilterResults(); 
      List<ProductLocal> filteredList = new ArrayList<>(); 
      constraint = constraint.toString().toLowerCase(); 
      for (int i = 0; i < dataListFilter.size(); i++) { 
       ProductLocal dataNames = dataListFilter.get(i); 

       String genreStr = ""; 
       for (String str : dataNames.getGenre()) { 
        genreStr += str + ","; 
       } 

       if (dataNames.getTitle().toLowerCase().startsWith(constraint.toString()) 
       || genreStr.toLowerCase().contains(constraint.toString())) { 
        filteredList.add(dataNames); 
       } 
      } 
      results.count = filteredList.size(); 
      results.values = filteredList; 
      return results; 
     } 

    }; 
    return filter; 
} 
+0

@DastakWall你想要可科特林回答所有的搜索字詞? –

回答

1

AFAIU你想要的歌曲相匹配的fiter如果任何這些2個條件:

  1. 歌曲的標題與全啓動搜索文本

  2. 該歌曲的類型包含由,(逗號)分隔的部分搜索文本

如果是這樣,請嘗試以下搜索邏輯:

 @Override 
     protected FilterResults performFiltering(CharSequence constraint) 
     { 
      FilterResults results = new FilterResults(); 
      List<ProductLocal> filteredList = new ArrayList<>(); 
      String searchText = constraint.toString().toLowerCase(); 
      String[] split = searchText.split(","); 
      ArrayList<String> searchGenres = new ArrayList<String>(split.length); 
      for (int i = 0; i < split.length; i++) 
      { 
       // remove spaces 
       String trim = split[i].trim(); 
       // skip empty entries 
       if (trim.length() > 0) 
        searchGenres.add(trim); 
      } 

      for (ProductLocal dataNames : dataListFilter) 
      { 
       // filter by title 
       if (dataNames.getTitle().toLowerCase().startsWith(searchText)) 
       { 
        filteredList.add(dataNames); 
       } 
       else 
       { 
        // filter by genres 
        // search for at least one common genre between song and search text 
        outer: 
        for (String songGenre : dataNames.getGenre()) 
        { 
         for (String searchGenre : searchGenres) 
         { 
          if (songGenre.toLowerCase().contains(searchGenre)) 
          { 
           filteredList.add(dataNames); 
           break outer; 
          } 
         } 
        } 
       } 
      } 
      results.count = filteredList.size(); 
      results.values = filteredList; 
      return results; 
     } 

這裏唯一棘手的地方是break outer;。這是同時從兩個for循環中分離出來的Java語法。這裏的想法是,如果我們找到了匹配的constraint和歌曲之間的一些流派,我們的歌曲添加到filteredList,不想再次添加它,如果有更多的匹配類型。

P.S.如果通過很多搜索類型過濾成爲性能問題,則可以考慮建立單一的正則表達式匹配一次或實施Aho–Corasick algorithm

0

您可以通過拆分,

String[] searmTearmArray= serachTerm.split(","); 

現在使用for循環中,您可以搜索這些詞語搜索詞。

+0

我試過了,這不起作用。 –

+0

什麼是錯誤 –

+0

沒有錯誤,但是當我在像'小提琴序列式風格,light'則給出了在流派這個序列的結果,它不會給有'小提琴,電的項目, light'。 –

1

請通過拆分約束字符串,如以下嘗試:

@Override 
public Filter getFilter() { 
    @SuppressWarnings("UnnecessaryLocalVariable") 
    Filter filter = new Filter() { 
     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      dataList = (List<ProductLocal>) results.values; 
      notifyDataSetChanged(); 
     } 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      FilterResults results = new FilterResults(); 
      List<ProductLocal> filteredList = new ArrayList<>(); 

      for (int i = 0; i < dataListFilter.size(); i++) { 
       ProductLocal dataNames = dataListFilter.get(i); 

       int count = 0; 
       String[] terms = constraint.toString().split(","); 

       for (int j = 0; j < terms.length; j++) { 

        String term = terms[j]; 
        for (String str : dataNames.getGenre()) { 

         if (str.equals(term) || str.contains(term)) { 
          count++; 
          if (count == terms.length) { 
           filteredList.add(dataNames); 
          } 
         } 
        } 
       } 
      } 

      results.count = filteredList.size(); 
      results.values = filteredList; 
      return results; 
     } 

    }; 
    return filter; 
} 
+0

這不起作用,對於第一個關鍵字來說很好,但是在插入'後,'列表返回空 –

+0

請嘗試編輯答案並讓我知道它是否有效。 –

+0

一樣的,但是這一次分裂後,名單將保持與第一次使用關鍵字找到的項目,沒有任何功能的任何其他輸入 –