11

我正在使用 ArrayAdapter 将项目添加到自定义 ListView 并在我的 Android 应用程序中显示结果。我遇到的问题是 ArrayAdapter 似乎要等到所有项目都在其中才显示视图。也就是说,当我将项目添加到 ArrayAdapter 并调用 notifyDataSetChanged 时,它不会更新 ListView 以显示添加的项目。它等到所有项目都被添加并在显示项目之前调用 GetView。

我想做的是在将它添加到 ListView 后立即显示该项目。这可能吗?

我相信相关代码如下:

r_adapter = new ReminderAdapater(Activity_ContentSearch.this, R.layout.search_listitem, myList);
listView.setAdapter(r_adapter);
...
r_adapter.notifyDataSetChanged();
r_adapter.clear();
for(int i = 0; i < myList.size(); i++)
{
    r_adapter.add(myList.get(i));
    r_adapter.notifyDataSetChanged();
}

如您所见,即使我在 add 方法之后调用 notifyDataSetChanged,它实际上并没有更新视图。在完成上述循环后,视图最终被更新(根据我所知道的,这是因为在这部分代码完成之前不会调用 GetView)。

我试图重写自定义 ArrayAdapter 的 add 方法,但没有成功,因为我无法访问该方法中的视图。

欢迎任何帮助:)

巴拉

4

1 回答 1

23

Android 的 UI 是单线程的。每次向适配器添加条目时,您都不会从主应用程序线程将控制权交还给 Android。因此,在您返回控制权之前,Android 没有机会显示您的条目,并且在您完全填充适配器之前您不会这样做。

这是一个示例,显示使用 an通过后台线程逐步AsyncTask填充。ArrayAdapter

/***
  Copyright (c) 2008-2012 CommonsWare, LLC
  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain   a copy
  of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  From _The Busy Coder's Guide to Android Development_
    http://commonsware.com/Android
*/

package com.commonsware.android.async;

import android.app.ListActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import java.util.ArrayList;

public class AsyncDemo extends ListActivity {
  private static final String[] items={"lorem", "ipsum", "dolor",
                                      "sit", "amet", "consectetuer",
                                      "adipiscing", "elit", "morbi",
                                      "vel", "ligula", "vitae",
                                      "arcu", "aliquet", "mollis",
                                      "etiam", "vel", "erat",
                                      "placerat", "ante",
                                      "porttitor", "sodales",
                                      "pellentesque", "augue",
                                      "purus"};
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    setListAdapter(new ArrayAdapter<String>(this,
                        android.R.layout.simple_list_item_1,
                        new ArrayList<String>()));

    new AddStringTask().execute();
  }

  class AddStringTask extends AsyncTask<Void, String, Void> {
    @Override
    protected Void doInBackground(Void... unused) {
      for (String item : items) {
        publishProgress(item);
        SystemClock.sleep(200);
      }

      return(null);
    }

    @SuppressWarnings("unchecked")
    @Override
    protected void onProgressUpdate(String... item) {
      ((ArrayAdapter<String>)getListAdapter()).add(item[0]);
    }

    @Override
    protected void onPostExecute(Void unused) {
      Toast
        .makeText(AsyncDemo.this, "Done!", Toast.LENGTH_SHORT)
        .show();
    }
  }
}
于 2010-01-25T10:54:03.417 回答