Introduction

The last time I spoke you about communication between fragment and activity. In this case, any android developer will necessarily be confronted one day or another to study the issue. For the next topic, this is not always the case unless you’ve met in all your projects, the need to create an horizontal listview.

The Theory

To create a horizontal listview you need:

Implement an horizontal listview

The Practice

Prerequisites: Add this line in the dependencies corresponding part of the app.build.gradle file.

compile 'com.android.support:recyclerview-v7:24.1.1'

Without this dependency, you will be unable to continue.

The layout

In first, we have to create an xml layout that we will name recycler_layout.xml and in which we will create a RecyclerView like this:

<LinearLayout android:id="@+id/linear_recycler_view"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:background="@null"
  android:orientation="horizontal">
  <android.support.v7.widget.RecyclerView android:id="@+id/my_recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>
</LinearLayout>

Then we have to create a LinearLayout with an horizontal orientation to specify that all contained elements have to be displayed horizontally. Finally, create a RecyclerView by specifying its tree.

The model part

To continue, create a model to collect datas to display in the corresponding views that we will create later. Let’s assume that an item (row) of our listview will consist of a text and an image. Therefore, our model should be structured like this:

public class Item {
  private int imageResource;
  private String text;
  /**
   * here my model description
   * @param imageResource
   * @param text
   */
  public Item(int imageResource, String text) {
    this.imageResource = imageResource;
    this.text = text;
  }
  public int getImageResource() {
    return imageResource;
  }
  public void setImageResource(int imageResource) {
    this.imageResource = imageResource;
  }
  public String getText() {
    return text;
  }
  public void setText(String text) {
    this.text = text;
  }
}

The view layout : item_view.xml

Each row of the listview will be graphically represented within xml view. Later, we will bind each of its elements with the corresponding components that we will have created in Java code.

<xml version="1.0" encoding="utf-8"/>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/relative_layout_view"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">
  <LinearLayout android:id="@+id/linear_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <TextView android:id="@+id/textview_title_item"
      android:layout_width="wrap_content"
      android:layout_height="15dp"
      android:layout_gravity="center_horizontal"
      android:layout_marginTop="8dp"
      android:textSize="15sp" />
    <ImageView android:id="@+id/_imageview_item"
      android:layout_width="40dp"
      android:layout_height="45dp"
      android:layout_below="@+id/ textview_title_item "
      android:layout_gravity="center_horizontal"/>
  </LinearLayout>
</RelativeLayout>

The Adapter

Let’s create a class that we will simply name ItemAdapter. We will add an initialisation constructor that take a context parameters of the calling activity and the list of data to be filled in (here an ItemModel ArrayList)

public ItemAdapter(ArrayList<Item> horizontalList, Context context) {
  this.horizontalList = horizontalList; this.context = context;
}

We will now create a sub class in the adapter that will represent an N view of our Adapter. In others words, it will represent the current item of our adapter and will be binded with the item_view.xml_ layout.

public class MyItemView extends RecyclerView.ViewHolder {
  public TextView textViewTitle; public ImageView imageView;
  public MyItemView(View view) {
    super(view);
    textViewTitle = (TextView) view.findViewById(R.id.textview_titley);
    imageView = (ImageView) view.findViewById(R.id.imageview_item);
  }
}

The abstracts methods

Until then we have created a model and a graphic view that only expects one thing: to be binded! For this, we must create the adapter that will set the recyclerview. We have to create a class that we will simply call ItemAdapter that inherits from RecyclerView.Adapter of ItemAdapter.ItemView. Implements its abstract methods :

@Override public MyItemView onCreateViewHolder(ViewGroup parent, int viewType) {}
@Override public void onBindViewHolder(final MyItemView holder, final int position) {}
@Override public int getItemCount() {}

The implementation

Here is how to implement the methods described above:

...
@Override public MyItemView onCreateViewHolder(ViewGroup parent, int viewType) {
  View itemView = LayoutInflater.from(parent.getContext())
  .inflate(R.layout.item_view, parent, false);
  return new MyItemView(itemView);
}
@Override public void onBindViewHolder(final MyItemView holder, final int position) {
  Item mItem = horizontalList.get(position);
  holder.textView.setText(mItem.getText());
  holder.imageView.setImageResource(mItem.getImageResource());
}
@Override public int getItemCount() {
  return horizontalList.size();
}

The onCreateViewHolder method allows the creation of the current item to set a layout, here item_view.xml. The onBindviewHolder method is used to bind the xml in the programmatically created view. Here, a TextView and an ImageView. Finally the getItemCount method allows to return the counted elements.

The RecyclerView as a ListView

Here, we performed 90% of the realisation work. All we have to do is create a RecyclerView object, which will act as a horizontal listview by specifying it a LayoutManager with the horizontal orientation value. This operation could not be performed on an android.widget.ListView object. So here are the last steps to achieve in an Activity :

RecyclerView recyclerView = (RecyclerView) v.findViewById(R.id.my_recycler_view);
LinearLayoutManager layoutManager = new LinearLayoutManager(getContext());
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
ArrayList<Item> listItem = getListItem();
itemAdapter = new ItemAdapter(listItem getContext());
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(historyAdapter);

I bind my RecyclerView object with R.id.my_recycler_view view from the recycler_layout.xml file. Next, I create a LayoutManager in which I assign the HORIZONTAL value, then I set on the recyclerView object. Finally I retrieve a list of items that I assign to the adapter that I set to my recycleView. The result at compilation time might look like this: !

Implement an horizontal listview

Conclusion

In this article we reviewed the different components required for an horizontal listview implementation . Don’t forget to load the dependency that allows you to implement your recyclerview which is not a listview but an item that will allow you to display items as a listview would allow you to do it with the difference that you can display it as an horizontally listview thanks to the LayoutManager.