Thursday, June 24, 2010

Apply custom adapter to ListView for RSS Reader

With the help of the exercise "Custom ArrayAdapter, with different icons", we know how to create our custom ListView. Now we go back to the old exercise of RSS Reader "A simple RSS reader III, show details once item clicked".

Apply custom adapter to ListView for RSS Reader
Modify the Rss Reader exercise to have a custom ListView, in which both title and PubDate will be displayed on each item in the ListView.

Create /res/layout/row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="@+id/listtitle"
android:textSize="22px"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/listpubdate"
android:textSize="10px"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>


Modify AndroidRssReader.java to create a new class MyCustomAdapter extends ArrayAdapter, with getView() overrided. setListAdapter using the custom adapter.
package com.exercise.AndroidRssReader;

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

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class AndroidRssReader extends ListActivity {

private RSSFeed myRssFeed = null;

public class MyCustomAdapter extends ArrayAdapter<RSSItem> {

public MyCustomAdapter(Context context, int textViewResourceId,
List<RSSItem> list) {
super(context, textViewResourceId, list);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
//return super.getView(position, convertView, parent);

View row = convertView;

if(row==null){
LayoutInflater inflater=getLayoutInflater();
row=inflater.inflate(R.layout.row, parent, false);
}

TextView listTitle=(TextView)row.findViewById(R.id.listtitle);
listTitle.setText(myRssFeed.getList().get(position).getTitle());
TextView listPubdate=(TextView)row.findViewById(R.id.listpubdate);
listPubdate.setText(myRssFeed.getList().get(position).getPubdate());

if (position%2 == 0){
listTitle.setBackgroundColor(0xff101010);
listPubdate.setBackgroundColor(0xff101010);
}
else{
listTitle.setBackgroundColor(0xff080808);
listPubdate.setBackgroundColor(0xff080808);
}

return row;
}
}

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

try {
URL rssUrl = new URL("http://www.gov.hk/en/about/rss/govhkrss.data.xml");
SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
XMLReader myXMLReader = mySAXParser.getXMLReader();
RSSHandler myRSSHandler = new RSSHandler();
myXMLReader.setContentHandler(myRSSHandler);
InputSource myInputSource = new InputSource(rssUrl.openStream());
myXMLReader.parse(myInputSource);

myRssFeed = myRSSHandler.getFeed();

} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

if (myRssFeed!=null)
{
TextView feedTitle = (TextView)findViewById(R.id.feedtitle);
TextView feedDescribtion = (TextView)findViewById(R.id.feeddescribtion);
TextView feedPubdate = (TextView)findViewById(R.id.feedpubdate);
TextView feedLink = (TextView)findViewById(R.id.feedlink);
feedTitle.setText(myRssFeed.getTitle());
feedDescribtion.setText(myRssFeed.getDescription());
feedPubdate.setText(myRssFeed.getPubdate());
feedLink.setText(myRssFeed.getLink());

MyCustomAdapter adapter =
new MyCustomAdapter(this, R.layout.row, myRssFeed.getList());
setListAdapter(adapter);

}
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
Intent intent = new Intent(this,ShowDetails.class);
Bundle bundle = new Bundle();
bundle.putString("keyTitle", myRssFeed.getItem(position).getTitle());
bundle.putString("keyDescription", myRssFeed.getItem(position).getDescription());
bundle.putString("keyLink", myRssFeed.getItem(position).getLink());
bundle.putString("keyPubdate", myRssFeed.getItem(position).getPubdate());
intent.putExtras(bundle);
startActivity(intent);
}
}


Download the files.

next: Simple RSS Reader, with Options Menu to reload RSS




7 comments:

Unknown said...

Really enjoying your feed reader! Only question is how can we add a menu option to refresh the feed?

Erik said...

hello thpoul,

Do you means add a menu option to reload the feed manually? Please refer Simple RSS Reader, with Options Menu to reload RSS

Unknown said...

so obvious... Thank you so much!

One more question if I may.

Is it possible to have a dynamic thumbnail in the list? This would mean that the myRssFeed.getThumbnail() should be defined in the RSSHandler.java

BitmapFactory.Options bmOptions;
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
bm = LoadImage(myRssFeed.getThumbnail(), bmOptions);

Thomas G. James said...

This is a great tutorial and a great resource to have!

When the description is displayed, it cuts the description short - even in the details.xml. How do you change the amount of description that is allowed to be displayed?

Again, thanks for your knowledge and for sharing.

Rishabh said...

Really enjoying your feed reader.
Only question is how can Rss Reader read the description part if it contains HTML tags in it?

Unknown said...

Hi , Thanks for your good Tutorial
Why ListView is dark?i want to have white ListView!
Please Help Me
Thank

Erik said...

Hello Mahya Khorrami,

You can change background of the ListView, and TextColor.

Or, you have to know more about Styles and Themes: http://developer.android.com/guide/topics/ui/themes.html