11

我使用ArrayAdapter将项目添加到自定义ListView并在Android应用中显示结果。我遇到的问题是,ArrayAdapter似乎等到所有项目都在它显示视图之前。也就是说,当我将这些项目添加到ArrayAdapter并调用notifyDataSetChanged时,它不会更新ListView以显示添加的项目。它将等待,直到添加所有项目并在显示项目之前调用GetView。Android - 使用ArrayAdapter一次添加并向ListView显示项目

我想要做的是在将它添加到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方法没有运气,因为我没有访问该方法中的视图。

任何帮助将受到欢迎:)

巴拉

回答

23

Android的用户界面是单线程的。每次向适配器添加条目时,您都不会从主应用程序线程向Android回复控制权。因此,在您返回控制权之前,Android没有机会显示您的条目,直到您将整个适配器填充为止,您才会这样做。

Here is an example显示使用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(); 
    } 
    } 
} 
相关问题