Android,ArrayAdapter的add()函数无法正常工作

我有一个ArrayAdapter(myAdapter)附加到AutoCompleteTextView(textView)组件。
一旦用户按下一个字符,我想用包含这个字符的项目来填充AutoCompleteTextView的下拉列表。
我使用AsyncTask(使用Web服务)来检索项目。

我打电话myAdapter.add(项目),但下拉列表是空的。
每次添加之后,我添加了一个调用myAdapter.getCount(),并且每次都显示为零。 调用notifyDataSetChanged()没有帮助。
我甚至试图添加简单的string对象,而不是我的自定义对象,无济于事。
我究竟做错了什么?

编辑:我改变了以下build议的代码,但仍然无济于事。
一般来说,我所做的是在我的自动完成文本视图中更改了文本之后,我调用一个新的AsyncTask并将其input的文本和一个Handler(请参阅afterTextChanged())传递给它。 任务检索与文本相关的对象,一旦完成Handler的handleMessage()被调用。 在handleMessage()我试图填充适配器的对象。 但是适配器的下拉列表仍然是空的。

这是我的代码:

public class AddStockView extends Activity implements OnClickListener, OnItemClickListener, TextWatcher { ArrayAdapter<Stock> adapter; AutoCompleteTextView textView; Vector<Stock> stocks; public AddStockView() { // TODO Auto-generated constructor stub stocks = new Vector<Stock>(); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.add_stock_view); findViewById(R.id.abort_button).setOnClickListener(this); adapter = new ArrayAdapter<Stock>(this, android.R.layout.simple_dropdown_item_1line, stocks); //adapter.setNotifyOnChange(true); textView = (AutoCompleteTextView) findViewById(R.id.search_edit_text); textView.setAdapter(adapter); textView.setOnItemClickListener(this); textView.addTextChangedListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch (v.getId()) { case R.id.abort_button: finish(); break; case R.id.search_edit_text: break; } } @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // TODO Auto-generated method stub Stock stockToAdd = (Stock)parent.getAdapter().getItem(position); //TODO: Add the above stock to user's stocks and close this screen finish(); } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); getMenuInflater().inflate(R.layout.menu, menu); CategoryMenu.getInstance().populateMenu(menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { CategoryMenu.getInstance().menuItemSelected(item, this); return false; } @Override public boolean onPrepareOptionsMenu(Menu menu) { return true; } @Override public void afterTextChanged(Editable text) { // TODO Auto-generated method stub if (text.toString().equals("")) return; new AppTask().execute(new AppTask.Payload(Consts.taskType.SEARCH_STOCK, new Object[] {text, handler}, this)); } @Override public void beforeTextChanged(CharSequence a0, int a1, int a2, int a3) { // TODO Auto-generated method stub } @Override public void onTextChanged(CharSequence a0, int a1, int a2, int a3) { // TODO Auto-generated method stub } private void addStockItemsToAdapter(Vector<Object> dataItems) { for (int i = 0; i <dataItems.size(); i++) { Stock stk = (Stock)dataItems.elementAt(i); stocks.add(stk); } } public void populateAdapter() { addStockItemsToAdapter(ContentReader.getInstance.getDataItems()); adapter.notifyDataSetChanged(); int size = adapter.getCount(); // size == 0 STILL!!!! textView.showDropDown(); } final Handler handler = new Handler() { public void handleMessage(Message msg) { populateAdapter(); } }; } 

Rob非常感谢

你在哪里调用addItemsToAdapter()? 你能告诉我们,你如何试图添加简单的string到你的适配器?

编辑:在评论中的有用的代码示例:

 adapter = new ArrayAdapter<Stock>(this, android.R.layout.simple_dropdown_item_1line, stocks); adapter.notifyDataSetChanged(); textView.setAdapter(adapter); 

我有同样的问题。 在检查了ArrayAdapter和AutoCompleteTextView源代码之后,我发现问题是简而言之:

  • 原始对象列表存储在ArrayAdapter.mObjects
  • 但是, AutoCompleteTextView启用了ArrayAdapter的筛选,这意味着将新对象添加到ArrayAdapter.mOriginalValues ,而mObjects包含已筛选的对象。
  • ArrayAdapter.getCount()总是返回mObjects的大小。

我的解决scheme是重写ArrayAdapter.getFilter()返回一个非过滤的filter。 这种方式mOriginalValuesnull并且在所有情况下都使用mObjects

示例代码:

 public class MyAdapter extends ArrayAdapter<String> { NoFilter noFilter; /* ... */ /** * Override ArrayAdapter.getFilter() to return our own filtering. */ public Filter getFilter() { if (noFilter == null) { noFilter = new NoFilter(); } return noFilter; } /** * Class which does not perform any filtering. * Filtering is already done by the web service when asking for the list, * so there is no need to do any more as well. * This way, ArrayAdapter.mOriginalValues is not used when calling eg * ArrayAdapter.add(), but instead ArrayAdapter.mObjects is updated directly * and methods like getCount() return the expected result. */ private class NoFilter extends Filter { protected FilterResults performFiltering(CharSequence prefix) { return new FilterResults(); } protected void publishResults(CharSequence constraint, FilterResults results) { // Do nothing } } } 

用一个向量或数组创build一个数组适配器:

 ArrayAdapter(Context context, int textViewResourceId, T[] objects) 

通过初始化你的arrayadapter,你将使它侦听对象数组。 不要将项目添加到适配器或清除适配器,在“对象”数组中添加并清除它。 在这个数组调用之后改变

 adapter.notifyDataSetChanged(); 

进一步来说

 ArrayAdapter<YourContentType> yourAdapter = new ArrayAdapter<YourContentType> (this,R.id.OneOfYourTextViews,YourDataList); yourAdapter.notifyDataSetChanged(); aTextView.setText(yourAdapter.isEmpty() ? "List is empty" : "I have too many objects:)"); 

这应该在加载YourDataList后,我检查你的代码,你确定处理程序调用addStockItemsToAdapter()然后再看看你的适配器是空的或不? 你还应该检查股票向量是否有任何元素。