Search code examples
androidonclickrssandroid-listfragment

Listfragment onclick error


I'm writing a little RSS Reader for Android with predefined URLs. I created a ListFragment to show the elements of the RSS feed, that uses an async task to get the content.
My biggest problem right now is, that the onListItemClick won't work.

public class List_Fragment extends ListFragment {
private final String TAG = RSSMain.class.getSimpleName();
// URL to read from
private final String[] URL_POOL = new String[] { "http://www.jugendnetz-berlin.de/de/arbeitswelt/rss.php",
        "http://www.jugendnetz-berlin.de/de/aktuelles/neues/rss/rss.php", "http://www.jugendnetz-berlin.de/de/arbeitswelt/rss.php"};
private String URL_RSS;
public int index = 0;
private Callbacks mCallbacks = sDummyCallbacks;
private static Content content;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    content = new Content();
    URL_RSS = URL_POOL[index];
    System.out.println(URL_RSS);
    // Start parsing feed
    new ReadRssFeedTask(getActivity()).execute();

}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

}

public interface Callbacks {
    /**
     * Callback for when an item has been selected.
     */
    public void onItemSelected(String url);
}

private static Callbacks sDummyCallbacks = new Callbacks() {
    @Override
    public void onItemSelected(String url) {
    }
};


public class ReadRssFeedTask extends AsyncTask<Void, Void, Void> {

    private ProgressDialog dialog;
    private HttpClient client;
    private HttpGet httpGet;
    private HttpResponse response;

    public ReadRssFeedTask(Activity activity) {
        client = new DefaultHttpClient();
        httpGet = new HttpGet(URL_RSS);
        response = null;
        dialog = new ProgressDialog(activity);
    }

    protected void onPreExecute() {
        dialog.setTitle("Bitte warten");
        dialog.setMessage("Der RSS Feed wird vom Server geladen.");
        dialog.show();
    }

    @Override
    protected Void doInBackground(Void... tmp) {
        try {
            response = client.execute(httpGet);
        } catch (ClientProtocolException e) {
            Log.e(TAG, "Falsches Protokoll" + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "URL ist falsch, URL:" + URL_RSS + e.getMessage());
        }

        if (response != null) {
            StatusLine statusLine = response.getStatusLine();

            if (statusLine.getStatusCode() == 200) {
                HttpEntity entity = response.getEntity();

                try {
                    SAXParserFactory spf = SAXParserFactory.newInstance();
                    SAXParser sp = null;
                    try {
                        sp = spf.newSAXParser();
                    } catch (ParserConfigurationException e) {
                        Log.e(TAG, "Fehler:" + e.getMessage());
                    } catch (SAXException e) {
                        Log.e(TAG, "Fehler im Handler" + e.getMessage());
                    }

                    XmlHandler myHandler = new XmlHandler(content);

                    try {

                        sp.parse(entity.getContent(), myHandler);
                    } catch (SAXException e) {
                        Log.e(TAG,
                                "Fehler beim Parsen. Fehler:"
                                        + e.getMessage());
                    } catch (IOException e) {
                        Log.e(TAG,
                                "URL " + URL_RSS
                                        + " konnte nicht geöffnet werden!"
                                        + e.getMessage());
                    }

                } catch (IllegalStateException e) {
                    e.printStackTrace();
                }

            } else {
                Log.i(RSSMain.class.getSimpleName(),
                        "Der Server antwortet mit anderem Statuscode als 200.");
            }
        } else {
            Log.i(RSSMain.class.getSimpleName(),
                    "Keine Internetverbindung.");
        }

        return null;
    }

    protected void onExecute(Void result) {
        if (dialog.isShowing()) {
            dialog.dismiss();
        }


    }

    protected void onPostExecute(Void result) {
        // End dialog feed when completely parsed
        if (dialog.isShowing()) {
            dialog.dismiss();
        }

        // fill list with data
        setListAdapter(new CustomAdapter(getActivity(),
                android.R.layout.simple_list_item_1, XmlHandler.myContent));

    }
}

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    // Activities containing this fragment must implement its callbacks.
    if (!(activity instanceof Callbacks)) {
        throw new IllegalStateException(
                "Activity must implement fragment's callbacks.");
    }

    mCallbacks = (Callbacks) activity;
}

@Override
public void onDetach() {
    super.onDetach();

    // Reset the active callbacks interface to the dummy implementation.
    mCallbacks = sDummyCallbacks;
}

@Override
public void onListItemClick(ListView listView, View view, int position,
        long id) {
    super.onListItemClick(listView, view, position, id);

    // Notify the active callbacks interface (the activity, if the
    // fragment is attached to one) that an item has been selected.
    mCallbacks.onItemSelected(XmlHandler.myContent.get(position)
            .getUrl(position));
}
}  

The style xml for its activity is

<FrameLayout android:id="@+id/fragment_placeholder" android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:focusable="false"/>

<fragment android:name="com.johko.jugendnetz_berlin.destellenangebote.List_Fragment"
    android:id = "@+id/feedListe"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
     />

The Logcat says the following:

  11-21 21:30:49.848: E/AndroidRuntime(764): java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(16908298, class android.widget.ListView) with Adapter(class com.johko.jugendnetz_berlin.destellenangebote.CustomAdapter)]

Solution

  • Looks like you forgot to notify the list adapter of new data.

    Try getListAdapter().notifyDataSetChanged(); after you added/changed the data.