Final steps: binding to the UI (again)

It's time for the last and final step – binding our data to the user interface. This section should look very familiar for those who have gone through the entire book, so I'll try to be brief but complete.

In the previous sections, we essentially hooked all the network requests together, both on the application side as well as on the server side, so that now we should be able to seamlessly make GET requests from any mobile application. We also looked at ways in which we could parse the resulting response (again, this was left as an exercise, as the response could come back in any number of ways) and convert the data from string form back into VideoGame object form.

So now let's think back to Chapter 6, Binding to the UI. In that chapter, we looked at two subclasses of ListAdapters – the BaseAdapter and the CursorAdapter . As you'll recall, the CursorAdapter is used when our data is stored into a SQLite database. The subsequent query into our SQLite database is returned in the form of a Cursor object which then gets wrapped by the CursorAdapter class. In our VideoGame example, we currently have a list of objects, not a Cursor. That's not to say that we couldn't store our results into a SQLite database, effectively making a cache (remember these?) on our application side and then issuing a query into our cache to get back a Cursor. But, for simplicity, let's stick with our list of VideoGame objects and simply use a BaseAdapter which is designed especially for such lists. The code for it might look like the following:

public class VideoGameBaseAdpater extends BaseAdapter {

    // REMEMBER CONTEXT SO THAT CAN BE USED TO INFLATE VIEWS
    private LayoutInflater mInflater;

    // LIST OF VIDEO GAMES
    private List<VideoGame> mItems = new ArrayList<VideoGame>();
    
    public VideoGameBaseAdpater(Context context, List<VideoGame> items) {
        // HERE WE CACHE THE INFLATOR FOR EFFICIENCY
        mInflater = LayoutInflater.from(context);
        mItems = items;
    }

    public int getCount() {
        return mItems.size();
    }

    public Object getItem(int position) {
        return mItems.get(position);
    }

    public long getItemId(int position) {
        return position;

    }

    public View getView(int position, View convertView, ViewGroup parent) {
        VideoGameViewHolder holder;

        // IF NULL THEN NEED TO INSTANTIATE IT BY INFLATING IT
        if (convertView == null) {
            convertView = mInflater.inflate(R.layout.list_entry, null);

            holder = new VideoGameViewHolder();
            holder.name_entry = (TextView) convertView.findViewById(R.id.name_entry);
            holder.type_entry = (TextView) convertView.findViewById(R.id.number_type_entry);

            convertView.setTag(holder);
        } else {
            // GET VIEW HOLDER BACK FOR FAST ACCESS TO FIELDS
            holder = (VideoGameViewHolder) convertView.getTag();
        }

        // EFFICIENTLY BIND DATA WITH HOLDER
        VideoGame v = mItems.get(position);
        holder.name_entry.setText(v.getName());

        String type = VideoGameConsole.convertIntToString(v.getConsoleType());
        holder.type_entry.setText(type);

        return convertView;
    }

    static class VideoGameViewHolder {
        TextView name_entry;

        TextView type_entry;
    }
    
}

So just like how in Chapter 6, Binding to the UI, we implemented a custom BaseAdpater that created a list of Contact objects – in this case, we're doing something extremely similar but for our VideoGame objects! Notice here that my VideoGameViewHolder only displays the name of the game and the type of the game and that I'm not doing anything with the image URL. Again, one could easily incorporate this into each row through using an ImageView, but that would require converting a URL into a Bitmap object – something that's not difficult to do but unnecessary in our case; you get the idea by now.

Now that this is done, we simply need to create an Activity which makes the GET request, takes the resulting list of VideoGames, and sets them as its ListAdapter by using the custom VideoGameBaseAdapter. The code for this is extremely simple:

public class VideoGameBaseAdapterActivity extends ListActivity {

    private List<VideoGame> games;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list);

        // MAKE GET REQUEST TO RETRIEVE GAMES
        games = GetVideoGamesAndroid.getGamesByType(VideoGameConsole.XBOX);

        // USE VIDEO GAME ADAPTER
        VideoGameBaseAdpater vAdapter = new VideoGameBaseAdpater(this, games);

        // SET THIS ADAPTER AS YOUR LIST ACTIVITY'S ADAPTER
        this.setListAdapter(vAdapter);
    }


    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        VideoGame vg = games.get(position);

        String name = vg.getName();
        System.out.println("CLICKED ON " + name);
    }
}

Once done, our end result looks like the following:

Final steps: binding to the UI (again)

And voila! Pat yourself on the back, as we've now just finished our first full-scale data-centric application! Now not only do we have a fully functional backend equipped with its own set of HTTP requests, but we've also built the beginning of a promising Android application that can make HTTP requests to this backend, obtain the results, and display them in a simple list.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.78.136