Menu

RowAdapter - Android Adapters Made Simple

By Luke Deighton

RowAdapter is an Open Source Library to simplify writing code for adapters. It aims to provide a bridge between the old and the new, an "Adapter of Adapters". It provides a common API to work with the various Adapter implementations. It also provides further encapsulation by handling View Types meaning that your Adapter Code can be reused in one or many different adapters without the need to worry about View Type Counts.

The RowAdapter library focuses solely on binding data to views. It can be used for either a ListView, RecyclerView or ExpandableListView with an option to use the View Holder pattern. It gives the possibility of starting with a ListView and then converting to RecyclerView as it becomes more roboust, without requiring many changes to your code.

The basic usage of the library involves creating 'RowTypes' that know how to bind a particular set of data to a set of views. The interface should seem relatively familiar!

View createView(LayoutInflater inflater, ViewGroup parent, int position);
void bindView(View view, int position);

Most of the time you can use any subtype of the interface with a few exceptions including the RecyclerView, which enforces the View Holder pattern and therefore requires a sub type of ViewHolderRow. The createView method gives you the option to inflate or instantiate a new View and place any first time initialisation code here, such as setting a custom typeface (although you should really be using a custom textview/library to handle typefaces). The bindView method is where you recycle a previous view and bind the data to the view.

RowAdapter

Firstly create your own class that implements RowType (or a subtype). InflatedRow automatically inflates a layout from resources and requires a layout in its constructor. Only the bindView method requires code and getItem() can be called to retrieve the data.

public class SimpleTextRow extends InflatedRow<String> {
  private int mTextViewResId;

  public SimpleTextRow(String item, @LayoutRes int layoutResId, @IdRes int textViewResId) { 
    super(item, layoutResId);
    mTextViewResId = textViewResId;
  }

  @Override 
  public void bindView(View view, int position) { 
    ((TextView) view.findViewById(mTextViewResId)).setText(getItem()); 
  }
}

Once you have created your RowTypes you can simply build up your rows as a List<RowType> or using the RowBuilder class:

RowBuilder rowBuilder = new RowBuilder()
 .add(new HeaderRow("hello"))
 .add(new SimpleTextRow("simple", R.layout.row_header, R.id.textview))
 .add(new ImageResourceRow(R.drawable.ic_launcher));

Finally instantiate a RowAdapter with your list of rows:

mAdapter = new RowAdapter(this, rowBuilder.build());
mListView.setAdapter(mAdapter);

Notice how the library doesn't care about ViewTypeCount as it will figure out this information itself by comparing the classes' hash of each item in the list, i.e. A different class represents a different ViewType.

OnItemClickListener

Item Click Events can be handled in the traditional way by doing a combination of instanceof checks and casting to retrieve your selected data or by using the OnRowClickListener:

RowClickHandler clickHandler = new RowClickHandler()
.put(HeaderRow.class, new OnRowClickListener<HeaderRow>() {
 @Override
 public void onRowClick(HeaderRow typedRow, int position) {
  Toast.makeText(MainActivity.this, "header: " + typedRow.getItem(),   Toast.LENGTH_SHORT).show();
 }
})
.put(ImageResourceRow.class, new OnRowClickListener<ImageResourceRow>() {
 @Override
 public void onRowClick(ImageResourceRow typedRow, int position) {
  Toast.makeText(MainActivity.this, "image: " +   typedRow.getItem(), Toast.LENGTH_SHORT).show();
 }
})
.put(SimpleTextRow.class, new OnRowClickListener<SimpleTextRow>() {
 @Override
 public void onRowClick(SimpleTextRow typedRow, int position) {
  Toast.makeText(MainActivity.this, "simple: " + typedRow.getItem(),   Toast.LENGTH_SHORT).show();
 }
});
mListView.setOnItemClickListener(clickHandler);

RecyclerRowAdapter

The library also supports using the new RecyclerView Library. It works in a similar fashion to the above example but requires subtyping from ViewHolderRow with the second generic parameter extending RecyclerView.ViewHolder. A simple usage is shown in the next code snippet.

public class RecyclerRow extends ViewHolderRow<String, RecyclerRow.ViewHolder> {
 public RecyclerRow(String item) {
  super(item, R.layout.row_header);
 }
 @Override
 public ViewHolder createViewHolder(View view, int position) {
  return new ViewHolder(view);
 }
 @Override
 public void bindViewHolder(ViewHolder viewHolder, String item, int position) {
  viewHolder.mTextView.setText(item);
 }
 static class ViewHolder extends RecyclerView.ViewHolder {
  TextView mTextView;
  ViewHolder(View view) {
   super(view);
   mTextView = (TextView) view.findViewById(R.id.textview);
  }
 }
}

CursorRowAdapter

Compatible with any RowType implementation, however currently only supports a single ViewType.

CursorRowAdapter<HeaderRow, String> adapter = new CursorRowAdapter<HeaderRow, String>(this, new MockedCursor(20), new CursorMapper<HeaderRow, String>() {
 @Override
 public String map(Cursor c) {
  return String.valueOf(c.getString(1));
 }
 @Override
 public HeaderRow createRow(Context context, String item, int position) {
  return new HeaderRow(item);
 }
}); 
mListView.setAdapter(adapter);

Github Source

The library and sample source code are available here on GitHub.

Categories

Tutorials
comments powered by Disqus

We're Hiring - C#.NET Web Developer

By Sophie Hardbattle

We're looking for a new web developer to join the Eden Agency team.

Read more

We're Hiring - Unity Game Developer

By Sophie Hardbattle

Eden Agency are looking for another member of the development team.

Read more

Yorkshire Virtual Reality Meetup

By Adam Taglietti

We're hosting the Yorkshire VR event. Meet up with other enthusiasts and try the latest technology including the Microsoft HoloLens and the Oculus Rift with Touch controllers.

Read more

Top AR/VR Developers

By Adam Taglietti

Clutch has named us one of the top AR/VR developers.

Read more

Introducing PowerUp

By Sophie Hardbattle

Introducing PowerUp -- our new virtual reality solution for events.

Read more