Listview getViewType() and getViewTypeCount() in Action

This  is an article on listview with different view’s.

We all know that listview is the most used and conventional way of displaying list  of data in android. Many-a-times we do encounter a scenario where we want to display list item depending on a specific condition for example have a look at the images below.

The common way of displaying such a data is to inflate one row and depending on the condition you may hide or make a view visible.

Toggling a view between VIEW.GONE and VIEW.VISIBLE can be a very expensive task inside the getview(..) which will sure affect the list scroll. This can be easily managed and tackled with listview’s pre-defined methods getViewTypeCount() and getItemViewType(..).

So to begin with you need to create separate layouts for each type of view that will be displayed. This way it will be more efficient and less clustered to manage the data.

To put all this into action i have created a demo project which can be downloaded here.

In this project i ‘ m showing 3 different types of row in a listview:

1. A simple text

2. Text with image view

3. Poll with three option

so first create 3 different xmls for different row type.

  • view_row_type_one.xml (for text layout)
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/textview"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_gravity="center"
 android:background="@android:color/darker_gray"
 android:textColor="@android:color/black"
 android:textSize="20sp"
 android:padding="10dp"/>

  • view_row_type_two.xml (layout with text and image )
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@android:color/darker_gray"
 android:padding="10dp" >

<ImageView
 android:id="@+id/imageView"
 android:layout_width="100dp"
 android:layout_height="100dp"
 android:layout_centerInParent="true"
 android:layout_marginBottom="10dp"
 android:contentDescription="@null" />

<TextView
 android:id="@+id/labelTextView"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_alignEnd="@id/imageView"
 android:layout_below="@id/imageView"
 android:layout_marginTop="15dp"
 android:textColor="@android:color/black"
 android:textSize="20sp" />

</RelativeLayout>

* view_row_type_three.xml (layout with radio buttons)

<?xml version="1.0" encoding="utf-8"?>
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@android:color/darker_gray"
 android:padding="10dp" >

<TextView
 android:id="@+id/questionTextView"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_marginLeft="5dp"
 android:textColor="@android:color/black"
 android:textSize="20sp" />

<RadioButton
 android:id="@+id/radioButtonOne"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="@string/yes"
 android:textColor="@android:color/black"
 android:textSize="20sp" />

<RadioButton
 android:id="@+id/radioButtonTwo"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="@string/no"
 android:textColor="@android:color/black"
 android:textSize="20sp" />

<RadioButton
 android:id="@+id/radioButtonThree"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="@string/cant_say"
 android:textColor="@android:color/black"
 android:textSize="20sp" />

</RadioGroup>

What does getViewTypeCount() and getItemViewType(…) do ?

These methods are called before getView(…).

1] getViewTypeCount()

Returns the count of different type of views. Here we are having three different type of views so this method will return count as 3.

2] getItemViewType(…) 

Here we will write the logic to determine the type of view.

@Override

public int getItemViewType(int position) {

if(mList.get(position) instanceof DataModel){

return VIEW_TYPE_TEXT;

}else if(mList.get(position) instanceof ImageModel){

return VIEW_TYPE_IMAGE;

}else{

return VIEW_TYPE_QUESTION;
}

Inside getView(…) method first we determine the type of view by calling getItemViewType(..) method, this will return the type to be inflated as shown below.

@Override

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

ViewHolder.DataViewHolder dataViewHolder = null;

ViewHolder.ImageViewHolder imageViewHolder = null;

ViewHolder.QuestionViewHolder questionViewHolder = null;

int type = getItemViewType(position); // to determine type of view.

if(type == VIEW_TYPE_TEXT){

if(convertView == null){

convertView = mInflater.inflate(R.layout.view_row_type_one, parent, false);

convertView.setTag(dataViewHolder);

.................

}else{

dataViewHolder = (DataViewHolder)convertView.getTag();

........

}

}else if(type == VIEW_TYPE_IMAGE){

if(convertView == null){

convertView = mInflater.inflate(R.layout.view_row_type_two, parent, false);

convertView.setTag(imageViewHolder);

..........

}else{

imageViewHolder = (ImageViewHolder)convertView.getTag();

...............

}

}else{

if(convertView == null){

convertView = mInflater.inflate(R.layout.view_row_type_three, parent, false);

convertView.setTag(questionViewHolder);

.................

}else{

questionViewHolder = (ViewHolder.QuestionViewHolder)convertView.getTag();

.......

}

}

return convertView;

}

This is all it. You can follow this mechanism of displaying data and you will notice significant improvements in the list scroll and the number of objects created. Hope this is useful to someone.

Download sample project from here.

Happy coding, happy learning. 🙂

Advertisements