Android - 使用 ArrayAdapter 一次向 ListView 添加和显示项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2130546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android - Adding and showing items to ListView one at a time using an ArrayAdapter
提问by Bara
I'm using an ArrayAdapter to add items to a custom ListView and showing the results in my Android app. The problem I'm having is that the ArrayAdapter seems to wait until all items are in it before it shows the view. That is to say, when I'm adding the items to the ArrayAdapter and I call notifyDataSetChanged, it does not update the ListView to show the added item. It waits until all items are added and GetView is called before showing the items.
我正在使用 ArrayAdapter 将项目添加到自定义 ListView 并在我的 Android 应用程序中显示结果。我遇到的问题是 ArrayAdapter 似乎要等到所有项目都在其中才显示视图。也就是说,当我将项目添加到 ArrayAdapter 并调用 notifyDataSetChanged 时,它不会更新 ListView 以显示添加的项目。它会等到所有项目都添加完毕并在显示项目之前调用 GetView。
What I would like it to do is to show the item immediately after adding it to the ListView. Is this possible?
我希望它做的是在将项目添加到 ListView 后立即显示该项目。这可能吗?
I believe the relevant code is the following:
我相信相关代码如下:
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();
}
As you can see, even though I am calling notifyDataSetChanged after the add method, it does not actually update the view. After it has finished the above loop the view is finally updated (based on what I know, that's because GetView isn't called until after this section of the code is done).
如您所见,即使我在 add 方法之后调用 notifyDataSetChanged ,它实际上并没有更新视图。完成上述循环后,视图最终更新(根据我所知道的,这是因为在此部分代码完成后才会调用 GetView)。
I tried to override the add method of my custom ArrayAdapter with no luck, since I don't have access to the view in that method.
我试图覆盖我的自定义 ArrayAdapter 的 add 方法,但没有运气,因为我无权访问该方法中的视图。
Any help would be welcome :)
欢迎任何帮助:)
Bara
巴拉
回答by CommonsWare
Android's UI is single-threaded. You are not giving control back to Android from the main application thread each time you add an entry to the adapter. Hence, Android does not get a chance to display your entries until you return control, and you're not doing that until you have populated your adapter in its entirety.
Android 的 UI 是单线程的。每次向适配器添加条目时,您都不会从主应用程序线程将控制权交还给 Android。因此,在您返回控制权之前,Android 没有机会显示您的条目,并且在您完全填充适配器之前您不会这样做。
Here is an exampleshowing the use of an AsyncTask
to fill an ArrayAdapter
progressively via a background thread.
这是一个示例,显示了使用 anAsyncTask
来ArrayAdapter
通过后台线程逐步填充 an 。
/***
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();
}
}
}