1

我有一個AutocompleteTextView與ArrayAdapter一起工作。當文本更改時,適配器將從web服務更新。這個更新是在AsyncTask中完成的,這是一個很好的做法。這或多或少地起作用,因爲每次按下按鍵後的建議都基於按下的上一個按鍵中檢索的字符串。 這個頁面有幾個相關的問題,但沒有一個答案適用於我。無論如何,我有一個解決方案,但效率低下,我不知道爲什麼「官方解決方案」失敗。ArrayAdapter從AutoCompleteTextAdapter中的Webservice晚到更新

我認爲關鍵在於在後臺調用ArrayAdapter的函數。這一點,我在異步調用做web服務:

private class DoAutoCompleteSearch extends AsyncTask<String, Void, Map<String, String>> { 

    @Override 
    protected Map<String, String> doInBackground(String... params) { 

     // Ask the webservice for data 
     Map<String, String> autoComplete = GetResource.dataList(params[0]); 
     return autoComplete; 
    } 

    @Override 
    protected void onPostExecute(Map<String, String> result) { 

     //mAutoCompleteAdapter.clear(); * This should work but does not * 

/* If it is set a new adapter in the AutoCompleteTextView, the whole thing works properly */ 

    mAutoCompleteAdapter = new ArrayAdapter<String>(mAutoCompleteAdapter.getContext(), android.R.layout.simple_dropdown_item_1line); 
    mACTV.setAdapter(mAutoCompleteAdapter); 

     for (Map.Entry<String, String> entry : result.entrySet()) { 
      mAutoCompleteAdapter.add(entry.getKey()); 
     } 
    } 
} 

我試圖與mAutoCompleteAdapter.clear(),並設置mAutoCompleteAdapter.notifyDataSetChanged()無處不在,但它是無用的。

回答

2

我也嘗試了很多讓這種方法工作,但沒有比自己更好的成功。但我找到了另一種方法來實現你想要的東西;擴展ArrayAdapter並實現Filterable。該類將從數據庫中,當由工作線程AutoCompleteTextView稱爲做實際取:

public class MyAutoCompleteAdapter extends ArrayAdapter<String> implements Filterable { 

    private List<String> mData = new ArrayList<String>(); 
    private Server mServer; 

    public MyAutoCompleteAdapter(Server server, Context context, int textViewResourceId) { 
     super(context, textViewResourceId); 
     mServer = server; 
    } 

    @Override 
    public int getCount() { 
     return mData.size(); 
    } 

    @Override 
    public String getItem(int index) { 
     return mData.get(index); 
    } 

    @Override 
    public Filter getFilter() { 
     Filter myFilter = new Filter() { 
      @Override 
      protected FilterResults performFiltering(CharSequence constraint) { 
       // This method is called in a worker thread 

       FilterResults filterResults = new FilterResults(); 
       if(constraint != null) { 
        try { 
         // Here is the method (synchronous) that fetches the data 
         // from the server 
         List<String> results = mServer.searchForItems(constraint.toString()); 
         filterResults.values = results; 
         filterResults.count = results.size(); 
        } 
        catch(Exception e) {} 

       } 
       return filterResults; 
      } 

      @Override 
      protected void publishResults(CharSequence contraint, FilterResults results) { 
       if(results != null && results.count > 0) { 
        mData = (List<String>)results.values; 
        notifyDataSetChanged(); 
       } 
       else { 
        notifyDataSetInvalidated(); 
       } 
      } 
     }; 
     return myFilter; 
    } 
} 

編輯:我已經改善了上面的代碼,因爲我有時會遇到異常java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification。爲了解決這個問題,我將mData更新爲publishResults()

0

此代碼片段在我的應用程序中爲我工作。把這個在您的活動包含ListView

@Override 
public void onActivityResumed() // 
{ 
    if (favoritesHaveChanged(activity, productString)) // 
    { 
     m_adapter.clear(); 
     performAsyncTaskWithCallBack(activity); 
    } 
} 

的回調將是被觸發事件偵聽器。通常使用AsyncTasks,您可以在AsyncTask中使用。