2014-03-25 55 views
2

嗨,大家好我有一個適配器擴展了ArrayAdapter類並重寫了一些Filterable方法。我使用此適配器在用戶鍵入AutocompleteTextView內時執行一些過濾。但是我看到,如果您鍵入的速度很快,則過濾項目的更新速度會變得非常慢。這是適配器類:如何加速Android中的AutocompleteTextView?

public class MunicipalitySearchAdapter extends ArrayAdapter<Municipality> { 

private ArrayList<Municipality> municipalities; 
private ArrayList<Municipality> allMunicipalities; 
private ArrayList<Municipality> suggestedMunicipalities; 
private int viewResourceId; 

@SuppressWarnings("unchecked") 
public MunicipalitySearchAdapter(Context context, int viewResourceId, ArrayList<Municipality> municipalities) { 
    super(context, viewResourceId, municipalities); 
    this.municipalities = municipalities; 
    this.allMunicipalities = (ArrayList<Municipality>) this.municipalities.clone(); 
    this.suggestedMunicipalities = new ArrayList<Municipality>(); 
    this.viewResourceId = viewResourceId; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View v = convertView; 
    if (v == null) { 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     v = inflater.inflate(this.viewResourceId, null); 
    } 
    Municipality municipality = municipalities.get(position); 
    if (municipality != null) { 
     TextView munNameTxtView = (TextView) v.findViewById(R.id.name); 
     TextView proSignTxtView = (TextView) v.findViewById(R.id.sign); 
     if (munNameTxtView != null) { 
      munNameTxtView.setText(municipality.getName()); 
     } 
     if (proSignTxtView != null) { 
      proSignTxtView.setText(municipality.getProvinceSign()); 
     } 
} 
    return v; 
} 


@Override 
public Filter getFilter() { 
    return municipalityFilter; 
} 

Filter municipalityFilter = new Filter() { 

    @Override 
    public String convertResultToString(Object resultValue) { 
     String str = ((Municipality) (resultValue)).getName(); 
     return str; 
    } 

    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 
     if (constraint != null) { 
      suggestedMunicipalities.clear(); 
      for (Municipality municipality : allMunicipalities) { 
       if (municipality.getName().toLowerCase(Locale.getDefault()).startsWith(constraint.toString().toLowerCase(Locale.getDefault()))) { 
        suggestedMunicipalities.add(municipality); 
       } 
      } 
      FilterResults filterRes = new FilterResults(); 
      filterRes.values = suggestedMunicipalities; 
      filterRes.count = suggestedMunicipalities.size(); 
      return filterRes; 
     } 
     else { 
      return new FilterResults(); 
     } 
    } 

    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     if (results != null && results.count > 0) { 
      @SuppressWarnings("unchecked") 
      ArrayList<Municipality> filteredMunicipalities = (ArrayList<Municipality>) results.values; 
      ArrayList<Municipality> supportMunicipalitiesList = new ArrayList<Municipality>(); 

      clear(); 
      for (Municipality mun : filteredMunicipalities) { 
       supportMunicipalitiesList.add(mun); 
      } 
      Iterator<Municipality> municipalityIterator = supportMunicipalitiesList.iterator(); 
      while (municipalityIterator.hasNext()) { 
       Municipality municipality = municipalityIterator.next(); 
       add(municipality); 
      } 
      notifyDataSetChanged(); 
     }   
    } 
}; 
} 

我想問一下,如果有人知道如何增加這種AutocompleteTextView的性能,使更新速度更快。我該怎麼辦?謝謝!

編輯:我createed這個類: 頂點: 公共類頂點{

private HashMap<Character, Vertex> vertexSons; 
private List<Integer> wordsIndexList; 
private List<Integer> prefixesIndexList; 
private int wordsNumber; 
private int prefixesNumber; 

public Vertex() { 
    vertexSons = new HashMap<Character, Vertex>(); 
    wordsIndexList = new ArrayList<Integer>(); 
    prefixesIndexList = new ArrayList<Integer>(); 
    wordsNumber = 0; 
    prefixesNumber = 0; 
} 

public boolean hasWords() { 
    if (wordsNumber > 0) { 
     return true; 
    } 
    return false; 
} 

public boolean hasPrefixes() { 
    if (prefixesNumber > 0) { 
     return true; 
    } 
    return false; 
} 

public void addVertexSon(Character character) { 
    vertexSons.put(character, new Vertex()); 
} 

public void addIndexToWordsIndexList(int index) { 
    wordsIndexList.add(index); 
} 

public void addIndexToPrefixesIndexList(int index) { 
    prefixesIndexList.add(index); 
} 

public HashMap<Character, Vertex> getVertexSons() { 
    return vertexSons; 
} 

public List<Integer> getWordsIndexList() { 
    return wordsIndexList; 
} 

public List<Integer> getPrefixesIndexList() { 
    return prefixesIndexList; 
} 

public int getWordsNumber() { 
    return wordsNumber; 
} 

public int getPrefixesNumber() { 
    return prefixesNumber; 
} 

public void increaseWordsNumber() { 
    wordsNumber++; 
} 

public void increasePrefixesNumber() { 
    prefixesNumber++; 
} 
} 

而特里:

public class Trie { 

private Vertex rootVertex; 

public Trie(List<Trieable> objectList, Locale locale) { 
    rootVertex = new Vertex(); 

    for (int i = 0; i<objectList.size(); i++) { 
     String word = objectList.get(i).toString().toLowerCase(locale); 
     addWord(rootVertex, word, i); 
    } 
} 

public Vertex getRootVertex() { 
    return rootVertex; 
} 

public void addWord(Vertex vertex, String word, int index) { 
    if (word.isEmpty()) { 
     vertex.addIndexToWordsIndexList(index); 
     vertex.increaseWordsNumber(); 
    } 
    else { 
     vertex.addIndexToPrefixesIndexList(index); 
     vertex.increasePrefixesNumber(); 
     Character fChar = word.charAt(0); 
     HashMap<Character, Vertex> vertexSons = vertex.getVertexSons(); 

     if (!vertexSons.containsKey(fChar)) { 
      vertex.addVertexSon(fChar); 
     } 

     word = (word.length() == 1) ? "" : word.substring(1); 
     addWord(vertexSons.get(fChar), word, index); 
    } 
} 

public List<Integer> getWordsIndexes(Vertex vertex, String word) { 
    if (word.isEmpty()) { 
     return vertex.getWordsIndexList(); 
    } 
    else { 
     Character fChar = word.charAt(0); 
     if (!(vertex.getVertexSons().containsKey(fChar))) { 
      return null; 
     } 
     else { 
      word = (word.length() == 1) ? "" : word.substring(1); 
      return getWordsIndexes(vertex.getVertexSons().get(fChar), word); 
     } 
    } 
} 

public List<Integer> getPrefixesIndexes(Vertex vertex, String prefix) { 
    if (prefix.isEmpty()) { 
     return vertex.getWordsIndexList(); 
    } 
    else { 
     Character fChar = prefix.charAt(0); 
     if (!(vertex.getVertexSons().containsKey(fChar))) { 
      return null; 
     } 
     else { 
      prefix = (prefix.length() == 1) ? "" : prefix.substring(1); 
      return getWordsIndexes(vertex.getVertexSons().get(fChar), prefix); 
     } 
    } 
} 

} 

和編輯這樣我的篩選:

Filter municipalityFilter = new Filter() { 



    @Override 
    public String convertResultToString(Object resultValue) { 
     String str = ((Municipality) (resultValue)).getName(); 
     return str; 
    } 

    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 

     if (constraint != null) { 
      String constraintString = constraint.toString().trim(); 
      suggestedMunicipalities.clear(); 

      List<Integer> wordsIndexesList = municipalityTrie.getWordsIndexes(municipalityTrie.getRootVertex(), constraintString); 
      for (int index : wordsIndexesList) { 
       suggestedMunicipalities.add(allMunicipalities.get(index)); 
      } 

      List<Integer> prefixesIndexesList = municipalityTrie.getPrefixesIndexes(municipalityTrie.getRootVertex(), constraintString); 
      for (int index : prefixesIndexesList) { 
       suggestedMunicipalities.add(allMunicipalities.get(index)); 
      } 

      FilterResults filterRes = new FilterResults(); 
      filterRes.values = suggestedMunicipalities; 
      filterRes.count = suggestedMunicipalities.size(); 
      return filterRes; 
     } 
     else { 
      return new FilterResults(); 
     } 
    } 

    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     if (results != null && results.count > 0) { 
      @SuppressWarnings("unchecked") 
      ArrayList<Municipality> filteredMunicipalities = (ArrayList<Municipality>) results.values; 
      ArrayList<Municipality> supportMunicipalitiesList = new ArrayList<Municipality>(); 

      clear(); 
      for (Municipality mun : filteredMunicipalities) { 
       supportMunicipalitiesList.add(mun); 
      } 
      Iterator<Municipality> municipalityIterator = supportMunicipalitiesList.iterator(); 
      while (municipalityIterator.hasNext()) { 
       Municipality municipality = municipalityIterator.next(); 
       add(municipality); 
      } 
      notifyDataSetChanged(); 
     }   
    } 
}; 

現在,我輸入AutoComp時會收到空指針警告leteTextView在這一行:

List<Integer> wordsIndexesList = municipalityTrie.getWordsIndexes(municipalityTrie.getRootVertex(), constraintString); 
      for (int index : wordsIndexesList) { 
       suggestedMunicipalities.add(allMunicipalities.get(index)); 
      } 

爲(INT指數:wordsIndexesList)聲明。我該怎麼辦?謝謝!

回答

4

你應該看看使用trie,這將是完美的自動完成。

這裏是一個樣子:

enter image description here

當你得到更多的字符,您可以進一步向下遍歷樹,可能的選項的數量將越來越小。

這會比每次查看整個列表快得多。


編輯:在反思我的回答後,我認爲一個更簡單的解決方案將是使用任何一種有序的地圖。 Checkout this answer for an example

+0

我試圖實現Trie,但在適配器類的過濾結果中出現空指針異常。請參閱我的編輯。 – tonix

+0

我已解決。現在它可以工作。但是,您是否知道爲什麼只有在輸入完整的單詞時才能看到自動完成的建議?我需要自動完成功能才能顯示可能的單詞的前綴... – tonix

+0

您是否實施了一個trie或使用地圖? – Tyler

相關問題