Reputation: 3139
Basically I created a separated RSS which works. I used DOMParsing and a custom adapter for the listview appearance. But now I decided that I want to have that list under a Tab representing a specific category of an rss feed(ie breaking news,educational new and so on). Here is my code.
public class FragmentA extends ListFragment {
ListView listView;
ArrayList<RowItem> items;
@Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_a, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
listView = (ListView)getView().findViewById(R.id.list_item);
//listView.setOnItemClickListener(this);
// create the RowItem list - used for storing one news feed
items = new ArrayList<RowItem>();
// start the background task to get the news feed
//new DownloadXMLTask(items).execute("http://feeds.bbci.co.uk/news/rss.xml");
new DownloadXMLTask(items).execute("http://www.nasa.gov/rss/dyn/breaking_news.rss");
}
private class RowItem {
String title = null;
String description = null;
String url = null;
public RowItem(String title,String url,String description) {
this.title = title;
this.description = description;
this.url = url;
}
}
private class DownloadXMLTask extends AsyncTask<String, Void, String> {
ArrayList<RowItem> items = null;
public DownloadXMLTask(ArrayList<RowItem> items) {
this.items = items;
}
// local helper method
private String getNodeValue(Element entry, String tag) {
Element tagElement = (Element) entry.getElementsByTagName(tag).item(0);
return tagElement.getFirstChild().getNodeValue();
}
private String downloadAndParseXML(String url) {
try {
InputStream in = new java.net.URL(url).openStream();
// build the XML parser
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
// parse and get XML elements
Document dom = db.parse(in);
Element documentElement = dom.getDocumentElement();
// we want all XML children called 'item'
NodeList nodes = documentElement.getElementsByTagName("item");
// for each 'item' do the following
for (int i = 0; i < nodes.getLength(); i++) {
Element entry = (Element) nodes.item(i);
// get the nodes from 'item' that you need
String title = getNodeValue(entry, "title");
//String description = getNodeValue(entry, "description");
String link = getNodeValue(entry, "link");
String description = getNodeValue(entry, "description");
// add them to your list
items.add(new RowItem(title,link,description));
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected String doInBackground(String... urls) {
if (urls.length <= 0)
return null;
return downloadAndParseXML(urls[0]);
}
protected void onPostExecute(String result) {
updateList(items);
}
}
public void updateList(ArrayList<RowItem> items) {
CustomArrayAdapter adapter = new CustomArrayAdapter(getActivity(),
R.layout.row, items);
listView.setAdapter(adapter);
}
// class used to have custom view for the list item
private class CustomArrayAdapter extends ArrayAdapter<RowItem> {
Context context;
List<RowItem> items;
private class ViewHolder {
public TextView title;
public TextView description;
}
public CustomArrayAdapter(Context context, int resource,
List<RowItem> items) {
super(context, resource, items);
this.context = context;
this.items = items;
}
@Override
public View getView(int position, View rowView, ViewGroup parent) {
// reuse the rowView if possible - for efficiency and less memory consumption
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.row, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.title = (TextView) rowView.findViewById(R.id.title);
viewHolder.description = (TextView) rowView.findViewById(R.id.desc);
rowView.setTag(viewHolder);
}
// set the view
ViewHolder holder = (ViewHolder) rowView.getTag();
RowItem item = items.get(position);
holder.title.setText(item.title);
holder.description.setText(item.description);
return rowView;
}
}
}
I get a NullPointer Exception inside the updatelist method which used to update the list of the retrieved data(title,ulr,link)..Obviously they are not but I can't think anything at the moment how to fix it.
09-21 16:07:41.310: E/AndroidRuntime(3678): FATAL EXCEPTION: main
09-21 16:07:41.310: E/AndroidRuntime(3678): java.lang.NullPointerException
09-21 16:07:41.310: E/AndroidRuntime(3678): at
com.example.tabstesting.FragmentA.updateList(FragmentA.java:159)
09-21 16:07:41.310: E/AndroidRuntime(3678):at
com.example.tabstesting.FragmentA$DownloadXMLTask.onPostExecute(FragmentA.java:152)
09-21 16:07:41.310: E/AndroidRuntime(3678): at
com.example.tabstesting.FragmentA$DownloadXMLTask.onPostExecute(FragmentA.java:1)
09-21 16:07:41.310: E/AndroidRuntime(3678): at
android.os.AsyncTask.finish(AsyncTask.java:631)
09-21 16:07:41.310: E/AndroidRuntime(3678): at
android.os.AsyncTask.access$600(AsyncTask.java:177)
Thank you in advance and sorry for the long code.
Upvotes: 1
Views: 263
Reputation: 35491
Ok, so I think I know what your problem is.
Inside fragment_a.xml
, you are declaring the ListView
as:
<ListView
android:id="@android:id/list"
// ... rest of properties
</ListView>
The first problem is that you are saying:
android:id="@android:id/list"
Which will use the ID "list" from the package android and not from your own resources. That is why it is not recognized in your code. Furthermore, you tried accessing element with id list_item
which isn't even present in your layout so you get a NullPointerException
because listView
is null
.
So, in your code where you are obtaining the ListView
, you should change:
listView = (ListView)getView().findViewById(R.id.list_item);
To:
listView = (ListView)getView().findViewById(android.R.id.list);
Upvotes: 1