SpineMagazine.com radio player & news reader for android

by jaymz on 2/07/2010

Quite a while back I was trying to get my head around the fairly complex ListView control for android and something I thought perfect for it was the set of radio shows over at spine magazine.

I have had this code sitting around for a while and I thought why not knock out the news code and release it and then just continue to work on it and update it. As the saying goes, release early, release often! I think it’ll be easy enough to add in reviews using the same sort of code to get the data and just re-using the show layout. This particular app was a lot more complicated than the django-reference thing, so here is some of what I’ve learned… You can get this in the marketplace now. Bug reports are expected & indeed welcome.

Warning! Technical crap follows.

It takes a bit of time to get your head around it, essentially you subclass the ArrayAdapter class with a container class to hold your list view elements. The ArrayAdapter is a templated class so you first need another class that is actually going to hold your data. This is were you’ll need to create a class for your data and then instantiate the ArrayList with this type. The code to hold my news post data is very simple:

package eu.jaymz.spinemag;
 
import android.util.Log;
 
public class NewsPost {
    private String title;
    private String description;
    private String date;
    private String author;
 
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public String getDate() {
        return date;
    }
    public void setDate(String date) {
        this.date = date;
    }
 
}

Then in my main activity class I cast the templated ArrayList to a NewsPost class:

ArrayList<NewsPost> spr_news = new ArrayList<NewsPost>();

With the data structure sorted I need a method in my ListView activity to actually fill in the ArrayList with data. This is very typically something along the lines of the following, here I read the JSON data from a URL, decode it and assign it to the class members, finally appending it to the ArrayList from earlier.

private void getPosts() {
        try {
            URL url = new URL("url for data");
            BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
            String str = in.readLine();
            in.close();
            spr_news = new ArrayList<NewsPost>();
            JSONObject json = new JSONObject(str);
            JSONArray posts = json.getJSONArray("posts");
            for(int x=0; x < posts.length(); x++) {
                JSONObject post_data = new JSONObject(posts.get(x).toString());
                NewsPost post = new NewsPost();
                post.setTitle(post_data.get("title").toString());
                post.setDescription(post_data.get("description").toString());
                post.setDate(post_data.get("date").toString());
                post.setAuthor(post_data.get("author").toString());
                spr_news.add(post);
                //Log.d("NEW", "added a post - "+post.getTitle());
            }
        } catch (Exception e) {
 
        }
        runOnUiThread(setPosts);
    }

With all the above in place the code is at the point where there is now an array full of structured data for our ArrayAdapter to show. To do this the ArrayAdapter needs subclassed to work with our earlier NewsPost classes members:

private class NewsAdapter extends ArrayAdapter<NewsPost> {
 
        private ArrayList<NewsPost> items;
 
        public NewsAdapter(Context context, int textViewResourceId, ArrayList<NewsPost> items) {
                super(context, textViewResourceId, items);
                this.items = items;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.post, null);
                }
                NewsPost o = items.get(position);
                if (o != null) {
                    /* hmm, this looks proper ugly */
                    TextView title = (TextView)v.findViewById(R.id.post_title);
                    TextView description = (TextView)v.findViewById(R.id.post_description);
                    TextView date = (TextView)v.findViewById(R.id.post_date);
                    TextView author = (TextView)v.findViewById(R.id.post_author);
 
                    description.setText(o.getDescription());
                    title.setText(o.getTitle());
                    author.setText(o.getAuthor());
                    date.setText(o.getDate());
                }
                return v;
        }
    }

All this code is really doing is loading the layout resource XML for our row and binding the data from the array elements members to views within the XML. Finally we need to tell the list view to update. Typically the above code has all been kicked off and ran in a thread, populating the ListView when it’s actually finished without stalling the phone itself.

for(int i=0;i<spr_news.size();i++) {
    n_adapter.add(spr_news.get(i));
}
m_ProgressDialog.dismiss();
n_adapter.notifyDataSetChanged();

All the above is doing is updating the ArrayAdapter and adding our ArrayList elements to display. We then signal that the data has changed which will cause the ListView itself to update. Simple! :) Again, I must make the point of how verbose this all feels when I’m coding in python all day. I’m sure it needs a good refactor to now but I’m a lot more familiar with the way android works with layouts and indeed strong typing :)

jaymzcd@googlemail.com

There is 1 comment in this article:

  1. 2/07/2010How are the related videos populated? | SEM says:

    [...] SpineMagazine.com radio player & news reader for android — jaymz.eu [...]