This article  will explain how to make a custom adapter for a ListView used to display a list of items. For those of you not familiar with how to bind a ListView to a list of items here is a brief overview. First you need an ArrayList of a certain type and an ArrayAdapter of the same type. In the constructor of the ArrayAdapter you pass in the context, a layout id and the ArrayList of the same type and set the lists adapter to the ArayAdapter. This simply displays a list calling toString() on every item which means you have to override toString()  on your type or the objects memory reference will be displayed.

This approach is good for displaying a simple list but what if we wanted to display the name and number of a contact or just two pieces of data from the same type in each list item. For those of you familiar with Asp.Net and the GridView we could just put binding tags in our markup but that isn’t the case with Android. To start we need to make a class the extends the BaseAdapter class and override a few methods. For this example we will be displaying a list of games. We will just be displaying the game id and its name.

The first thing we need to do is create the View we will be using in the adapter. For this will we be creating a simple class that extends LinearLayout that contains two TextViews for our display. This class is very simple, it contain two TextViews with methods to set their text and a constructor that defines the layout of the items. In the constructor all we do is instantiate the TextViews and set their text. Here is the View class.

   1: public class GameView extends LinearLayout {
   2:  
   3:     TextView txtName;
   4:     TextView txtID;
   5:     
   6:     public GameView(Context context, Game game) {
   7:         super(context);
   8:         this.setOrientation(VERTICAL);
   9:         
  10:         txtName = new TextView(context);
  11:         txtID = new TextView(context);
  12:         
  13:         txtID.setText(String.valueOf(game.getID()));
  14:         txtName.setText(game.getName());
  15:         
  16:         addView(txtID, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
  17:         addView(txtName, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
  18:     }
  19:     
  20:     public void setID(long value) { txtID.setText(String.valueOf(value)); }
  21:     public void setName(String value) { txtName.setText(value); }
  22:  
  23: }

 

Next we need to make our class that overrides the BaseAdapter class. Here is the start of our class and the methods we need.

   1: public class GameAdapter extends BaseAdapter {
   2:     
   3:     @Override
   4:     public int getCount() {
   5:             return 0;
   6:     }
   7:  
   8:     @Override
   9:     public Object getItem(int arg0) {
  10:         return 0;
  11:     }
  12:  
  13:     @Override
  14:     public long getItemId(int arg0) {
  15:         return 0
  16:     }
  17:  
  18:     @Override
  19:     public View getView(int arg0, View arg1, ViewGroup arg2) {
  20:         
  21:     }
  22: }

 

The first thing we need to do is create a constructor. We will pass in the context and a list of games to be used by the Adapter.

   1: Context _context;
   2: ArrayList<Game> games;
   3:  
   4: public GameAdapter(Context context, ArrayList<Game> _games) {
   5:     _context = context;
   6:     games = _games;
   7: }

 

Now that we have all the data we need we just need to fill in the methods we overrode. The most important one is getView which will instantiate an instance of our custom view class and assign it the appropriate values. The other three methods are used to get the current item or count of items. Again we are doing nothing special other than creating a view and assigning its values. Here is the complete code for the Adapter class.

   1: public class GameAdapter extends BaseAdapter {
   2:  
   3:     Context _context;
   4:     ArrayList<Game> games;
   5:     
   6:     public GameAdapter(Context context, ArrayList<Game> _games) {
   7:         _context = context;
   8:         games = _games;
   9:     }
  10:     
  11:     @Override
  12:     public int getCount() {
  13:         if (games != null)
  14:             return games.size();
  15:         else
  16:             return 0;
  17:     }
  18:  
  19:     @Override
  20:     public Object getItem(int arg0) {
  21:         return games.get(arg0);
  22:     }
  23:  
  24:     @Override
  25:     public long getItemId(int arg0) {
  26:         return games.get(arg0).getID();
  27:     }
  28:  
  29:     @Override
  30:     public View getView(int arg0, View arg1, ViewGroup arg2) {
  31:         GameView gv;
  32:         if (arg1 == null)
  33:             gv = new GameView(_context, games.get(arg0));
  34:         else {
  35:             gv = (GameView) arg1;
  36:             gv.setID(games.get(arg0).getID());
  37:             gv.setName(games.get(arg0).getName());
  38:         }
  39:         return gv;
  40:     }
  41: }

 

To use this in an activity simply crate a ListView, the custom adapter and set the ListView’s adapter to our custom adapter and see the results. Here is some code to get you going.

   1: public class ScoreKeeper extends Activity {
   2:  
   3:     ArrayList<Game> games;
   4:     GameAdapter myAdapter;
   5:     
   6:     /** Called when the activity is first created. */
   7:     @Override
   8:     public void onCreate(Bundle savedInstanceState) {
   9:         super.onCreate(savedInstanceState);
  10:         setContentView(R.layout.main);
  11:  
  12:         lstGames = (ListView)findViewById(R.id.lstGames);
  13:         
  14:         games = db.getAllGames();
  15:  
  16:         myAdapter = new GameAdapter(this, games);
  17:         lstGames.setAdapter(myAdapter);
  18:     }
  19: }

 

That’s all there is to it. I know this is pretty much the android’s example minus putting creating your own ListView class but I wanted to show how to do this since it will lead into my next post on creating your own Adapter for handling AutoCompletes in android. Plus it shows you can use the default ListView rather than creating your own. Hope you will find this useful.