LowFieldTheory
LowFieldTheory

Reputation: 1773

Android - after notifyDataSetChanged ListView remains blank

It's hours I search for something, but it doesn't seem to help.. Android Studio doesn't launch any error, but the screen remains blank. Why?

package org.newapp;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import org.xml.sax.SAXException;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import saxrssreader.*;


public class MainActivity extends Activity {

    private ArrayAdapter<RssItem> rssItemsArrayAdapter;
    ListView codeLearnLessons;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        RssItem[] rssItems = new RssItem[]{};
        rssItemsArrayAdapter = new ArrayAdapter<RssItem>(this, android.R.layout.simple_list_item_1, rssItems);
        new WebCall().execute(rssItems);
        codeLearnLessons = (ListView)findViewById(R.id.listView1);
        codeLearnLessons.setAdapter(rssItemsArrayAdapter);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    private class WebCall extends AsyncTask<RssItem, Void, Void>  {

        @Override
        protected Void doInBackground(RssItem... items) {
            URL url = null;
            try {
                url = new URL("http://www.somewpsite.com/feed");
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
            try {
                ArrayList<RssItem> listItems = RssReader.read(url).getRssItems();
                items = listItems.toArray(new RssItem[listItems.size()]);
                final int l = items.length;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        codeLearnLessons.invalidateViews();
                        rssItemsArrayAdapter.notifyDataSetChanged();
                        Log.i("rec", "rec" + l);
                    }
                });
            } catch (SAXException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPreExecute() {
            /*ProgressDialog mDialog = new ProgressDialog(MainActivity.this);
            mDialog.setMessage("Please wait...");
            mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            mDialog.setIndeterminate(true);
            mDialog.setCancelable(false);
            mDialog.show();*/
        }
    }


}

Upvotes: 0

Views: 563

Answers (2)

Larry Schiefer
Larry Schiefer

Reputation: 15775

The issue is that your using a ArrayList which only has scope inside of the AsyncTask.doInBackground() method. Since it is not given to the adapter, the notifyDataSetChanged() does nothing. You'll need to replace the existing array like this:

rssItemsArrayAdapter.clear();
rssItemsArrayAdapter.addAll(listItems);
rssItemsArrayAdapter.notifyDataSetChanged();

Having said that, you also really need to change your use of AsyncTask. There's no need to call runOnUiThread() from within your doInBackground() as the AsyncTask will automatically run its onPostExecute() on the UI thread. Have your doInBackground() method return your new ArrayList<RssItem> and create an onPostExecute() override method which adjusts the adapter as shown above.

Upvotes: 2

Christian
Christian

Reputation: 4641

You are passing your items to the AsyncTask but in the AsyncTask you declare them new with the content of your result. You never pass the items to your ArrayAdapter back. Make them a property of your class instance.

Edit - Example:

rssItemsArrayAdapter.clear();
rssItemsArrayAdapter.addAll(items);

and afterwards

rssItemsArrayAdapter.notifyDataSetChanged();

Upvotes: 0

Related Questions