无法使我的AutocompleteTextView快速运行。我怎样才能做到这一点?

时间:2014-03-29 16:14:53

标签: java android filter android-arrayadapter autocompletetextview

这令人沮丧,我花了一周的时间试图找出如何在Android中提高自定义autocompleteTextView的性能,并且什么都没有。我甚至实现了一个Trie来保留列表项的一些索引,以便在过滤时恢复它们,但是徒劳(我想我使用它不正确或者问题出在其他地方)。我已经实现了FilterSearchTaskFragment以保持对上次启动任务的引用,并在用户在autocompleteTextView中快速键入多个字符时停止它。

在performFiltering()方法和publishResults()中,我已经设置了一些控件来恢复实际运行任务的状态(通过调用isCancelled()方法),以便尽快完成但是什么,或者更好我在ADT模拟器中测试应用程序时稍微增加了性能,但在真实设备(我的平板电脑)上似乎事情保持不变...为什么?我在弄什么?

我用Google搜索以找到一些有用的答案,但我找不到任何有同样问题的人。我甚至在这里问过SO,有人告诉我使用装载机,有人告诉我使用Handler,但是当事情发生时,没有人回复我,我也不知道如何使用它们我的情况。 我正在使用自定义的对象列表(我正在过滤一些我以前从MySQL数据库恢复的市政数据)。这是我写的所有代码:

首先是FilterSearchTaskFragment:

public class FilterSearchTaskFragment extends Fragment {

private TaskCallbacks filterSearchTaskCallbacks;

private static int taskNum;

public interface TaskCallbacks {
    void onPreExecute();
    void onPostExecute();
    void performFilterSearch();
}

private AsyncFilterSearchAbstractTask filterSearchTask;
private boolean running;

@Override 
public void onAttach(Activity activity) {
    super.onAttach(activity);
    if (activity instanceof TaskCallbacks) {
        filterSearchTaskCallbacks = (TaskCallbacks) activity;
    }
    else {
        throw new ClassCastException(activity.toString() + " must implement the FilterSearchTaskFragment.TaskCallbacks interface!");
    }
}

@Override 
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);
}

// Start the background filter search task
public void start() {
    filterSearchTask = new AsyncFilterSearchAbstractTask();
    filterSearchTask.execute();
    taskNum++;
    running = true;
}

public int getTaskNum() {
    return taskNum;
}

// Cancel the execution of the background filter search task
public void cancel() {
    filterSearchTask.cancel(true);
    filterSearchTask = null;
    running = false;
}

public boolean isRunning() {
    return this.running;
}

public boolean isCancelled() {
    if (filterSearchTask.isCancelled()) {
        return true;
    }
    return false;
}

// Background filter search 
private class AsyncFilterSearchAbstractTask extends AsyncTask<Void, Void, Void> {

    @Override 
    protected void onPreExecute() {
        filterSearchTaskCallbacks.onPreExecute();
        running = true;
    }

    @Override
    protected Void doInBackground(Void... nothings) {
        filterSearchTaskCallbacks.performFilterSearch();
        return null;
    }

    @Override
    protected void onCancelled() {
        Log.i("TASK CANCELLED", "THE TASK NUMBER " + getTaskNum() + " HAS BEEN CANCELLED");
    }

    @Override
    protected void onPostExecute(Void nothing) {
        filterSearchTaskCallbacks.onPostExecute();
        running = false;
    }
}
 }

它有一个我的Activity实现的接口(TaskCallbacks):

public void onPreExecute() {    
}

public void performFilterSearch() {
    if (!filterSearchTask.isCancelled()) {
        adapter.setFilterSearchTask(filterSearchTask);
        adapter.setConstraint(constraint);
        adapter.setStartChangeOffset(startChangeOffset);
        adapter.setBeforeChars(beforeChars);
        adapter.setCountCharsThatReplacedBefore(countCharsThatReplacedBefore);
        adapter.setNotifyOnChange(false);
        if (!filterSearchTask.isCancelled()) {
            adapter.getFilter().filter(constraint);
        }
    }
}

public void onPostExecute() {

}

过滤器工作委托给自定义适配器,它包含Filter实现,这里是类:

public class MunicipalitySearchAdapter extends ArrayAdapter<Municipality> {

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

FilterSearchTaskFragment filterSearchTask;

private List<Trieable> triableList;

private Trie municipalityTrie;

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;
    this.triableList = new ArrayList<Trieable>();
    for (Municipality mun : allMunicipalities) {
        triableList.add(mun);
    }
    municipalityTrie = new Trie(triableList, Locale.ITALY);
}

@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);
        TextView regNameTxtView = (TextView) v.findViewById(R.id.regionName);

        if (munNameTxtView != null) {
            munNameTxtView.setText(municipality.getName());
        }
        if (proSignTxtView != null) {
            proSignTxtView.setText(municipality.getProvinceSign());
        }
        if (regNameTxtView != null) {
            regNameTxtView.setText(municipality.getRegionName());
        }
    }
    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) {
        FilterResults filterRes = new FilterResults();

        if (constraint == null || constraint.length() == 0) {
            filterRes.values = allMunicipalities;
            filterRes.count = allMunicipalities.size();
        }

        else {
            String constraintString = constraint.toString().trim().toLowerCase(Locale.ITALY);
            suggestedMunicipalities.clear();

            List<Integer> wordsIndexesList = municipalityTrie.getWordsIndexes(municipalityTrie.getRootVertex(), constraintString);                  
            if (wordsIndexesList != null) {
                for (int i = 0; i<wordsIndexesList.size() && !filterSearchTask.isCancelled(); i++) {
                    int index = wordsIndexesList.get(i);
                    suggestedMunicipalities.add(allMunicipalities.get(index));
                }
            }

            List<Integer> prefixesIndexesList = municipalityTrie.getPrefixesIndexes(municipalityTrie.getRootVertex(), constraintString);
            if (prefixesIndexesList != null) {
                for (int i = 0; i<prefixesIndexesList.size() && !filterSearchTask.isCancelled(); i++) {
                    int index = prefixesIndexesList.get(i);
                    suggestedMunicipalities.add(allMunicipalities.get(index));
                }
            }

            filterRes.values = suggestedMunicipalities;
            filterRes.count = suggestedMunicipalities.size();                   
        }           

        return filterRes;
    }

    @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>();
            notifyDataSetChanged();
            clear();
            if (!filterSearchTask.isCancelled()) {
                for (int i = 0; i < filteredMunicipalities.size() && !filterSearchTask.isCancelled(); i++) {
                    Municipality mun = filteredMunicipalities.get(i);
                    supportMunicipalitiesList.add(mun);
                }
                Iterator<Municipality> municipalityIterator = supportMunicipalitiesList.iterator();
                while (municipalityIterator.hasNext() && !filterSearchTask.isCancelled()) {
                    Municipality municipality = municipalityIterator.next();
                    add(municipality);
                }
            }

            notifyDataSetInvalidated();

        }
    }                   
};
}

过滤操作中使用的Trie类是:

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.getPrefixesIndexList();
    }
    else {
        Character fChar = prefix.charAt(0);
        if (!(vertex.getVertexSons().containsKey(fChar))) {
            return null;
        }
        else {
            prefix = (prefix.length() == 1) ? "" : prefix.substring(1);
            return getPrefixesIndexes(vertex.getVertexSons().get(fChar), prefix);
        }
    }
}

}

每个节点都由Trie的顶点表示,这是类:

public class Vertex {

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++;
}
 }

最后,我在这里实例化适配器(在我的Activity中)并向AutocompleteTextView添加一个监听器:

adapter = new MunicipalitySearchAdapter(getApplicationContext(), R.layout.municipality_list_item, ListaComuni);
                municipalityEditTxt.setAdapter(adapter);
                municipalityEditTxt.addTextChangedListener(new TextWatcher() {

                    @Override
                    public void onTextChanged(CharSequence s, int start, int before, int count) {
                        constraint = s;
                        startChangeOffset = start;
                        beforeChars  = before;
                        countCharsThatReplacedBefore = count;

                        if (filterSearchTask.isRunning()) {
                            filterSearchTask.cancel();
                        }
                        filterSearchTask.start();
                    }

                    @Override
                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    }

                    @Override
                    public void afterTextChanged(Editable s) {          
                    }
                });

municipalityEditText是AutocompleteTextView参考。 所以如果你们这里的某个人遇到同样的问题,你能不能告诉我你是如何让它顺利运作的?请回答我,因为我卡住了!

谢谢!

0 个答案:

没有答案