如何在异步填充后刷新ListView

时间:2012-04-27 19:24:13

标签: android listview android-asynctask

我设置函数返回包含ArrayListdoInBackground函数中ListView数据的AsyncTask,并在onPostExecute()中设置notifyDataSetCahnged()

但是,尽管arraylist中有数据,但是在列表视图中还是没有反映出来? 为什么?

public class E0XMLParsing_RSSExampleActivity extends Activity {

    ListView lvFeeds;
    FeedsAdapter feedsAdapter;
    ArrayList<Feed> listOfFeeds;
    ProgressDialog progress;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        listOfFeeds = new ArrayList<Feed>();
        lvFeeds = (ListView) findViewById(R.id.listFeeds);
        feedsAdapter = new FeedsAdapter(getApplicationContext(), R.layout.row, listOfFeeds);
        String url = "http://www.aljazeera.com/Services/Rss/?PostingId=200772215035764169";
        progress = ProgressDialog.show(this, "Aljazeera RSS", 
                                    "Please wait while downloading the RSS feeds ...");
        new DownloadRSS().execute(url);
    }


    private class DownloadRSS extends AsyncTask<String,Integer,ArrayList<Feed>>{

        @Override
        protected ArrayList<Feed> doInBackground(String... urls) {
            XMLParser parser = new XMLParser();

            return parser.getFeedsList(urls[0]);
        }

        protected void onPostExecute(ArrayList<Feed> listOfFeeds2){
            progress.dismiss();
            listOfFeeds = listOfFeeds2;
            feedsAdapter.notifyDataSetChanged();
        }

    }

FeedAdapter

public class FeedsAdapter extends ArrayAdapter<Feed>{

    public ArrayList<Feed> listOfFeeds= null;
    Context context;
    public FeedsAdapter(Context context,int textViewResourceId,ArrayList<Feed> feeds) {
        super(context,textViewResourceId,feeds);
        this.listOfFeeds = feeds;
        this.context = context;
    }

    @Override
    public View getView(int position, View view,ViewGroup parent){
        View v= view;
        if (v!=null){
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.row,null);
            Feed f = listOfFeeds.get(position);

            TextView lblTitle = (TextView) v.findViewById(R.id.lblTitle);
            TextView lblDescription = (TextView) v.findViewById(R.id.lblDescription);
            TextView lblDate = (TextView) v.findViewById(R.id.lblDate);

            lblTitle.setText(f.title);
            lblDescription.setText(f.description);
            lblDate.setText(f.date);
        }

        return v;
    }

3 个答案:

答案 0 :(得分:4)

当您致电listOfFeeds = listOfFeeds2;时,它会为您的对象 listOfFeeds 设置新对象引用,并且无法在适配器上调用 notifyDataSetChanged 。要解决此问题,您可以在 onPostExecute 中执行两项操作。

首先:

listOfFeeds.clear();
listOfFeeds.addAll(listOfFeeds2);
feedsAdapter.notifyDataSetChanged();

* 在此方法中,您正在清除 listOfFeeds 并从第二个对象推送项目,导致不更改适配器的数据对象引用。因此,您需要调用notifyDataSetChanged来更新列表

第二

feedsAdapter = new FeedsAdapter(getApplicationContext(),
       R.layout.row, listOfFeeds);
listOfFeeds.setAdapter(feedsAdapter);

* 在这种方法中,您只需设置新的适配器。所以你不需要在这里调用notifyDataSetChanged

答案 1 :(得分:0)

我不确定这是否能回答您的问题,但为了更新您的ListView,首先您需要更新适配器,然后在ListView上设置适配器,最后再次绘制ListView

ArrayAdapter<String> myAdapter = new ArrayAdapter<String>(this, R.layout.simple_list_item_1, myNewStringArray);
myListView.setAdapter(myAdapter);
myListView.invalidate() //if you perform the re-draw in UI thread
// OR myListView.postInvalidate() if you perform the re-draw in non-UI thread

答案 2 :(得分:-1)

onPostExecute()中,将所有数据放入runOnUiThread()来电:

runonuithread () {
    feedsAdapter.notifyDataSetChanged();
}