Tutorial - Android Mobile Development: List View and Memory Resources
Android provides us a powerful way to create lists views. Just like Facebook or the popular Vine mobile app, Android allows us to show the posts/feeds in list view. I’ll give you a few tips that can be really useful when it comes to the memory consumption management subject for android mobile apps.
We are going to make some assumptions. First, we already have a layout with a list view in it:
Secondly, we also have a reference to our list view in our list view activity:
ListView myListView = (ListView) findViewById(R.id.myListView);
Ok, let's create a custom layout for each row of our list view. Let's say that we want to create a list view with two text views and one check box in each row. So in a new xml file (row.xml), I’ll add the three objects like this:
Now, we can start creating our list adapter which will help us manage the resources in a really optimized way to create our list view.
First of all, let's explain what the main parts of an adapter are. For this example, I will talk about the Base Adapter, which contains the followings methods:
Return how many items are in the data set represented by this adapter.
Get the data item associated with the specified position in the data set.
Get the row id associated with the specified position in the list.
Get a View that displays the data at the specified position in the data set
We need to create a new java file which extends from base adapter and will override the previous methods.
From our main activity, we will create a list adapter which receives an array in its constructor and that array contains the information we want to see in our list view:
As we can see in the previous image, I created a class which will manage two strings (the stadium and the football team). In this example, I just added one stadium but you can add as many as you want. After having the array ready, I created the list adapter and set it to list view.
We can start painting the list view and here is where the optimized list view starts.
As soon as we set the adapter to the list view, the getCount method from our list adapter will be called to return the number of elements the list view has. In my example, this is how the getCount method will look:
By doing this, we can ensure that the list view will have n-rows depending on the array size and the getView method will be called the integer getCount method returns.
Let’s see what getView method is for and how we can adapt it to be optimized. There are two things for Android which are lengthy and time consuming that we must avoid doing this too many times:
*Making references to layout objects
The getView method gives us the following objects:
public View getView(int position, View convertView, ViewGroup parent)
For this example, we will use the position and convertView objects. As the name says, the position value tells us which row is going to be painted in the list view and the convertView object gives us a recycled object that has already been painted and we can reuse or just use a null object if we didn’t already paint a row.
Here is our first hint to optimize our code. If we get a convertView which has a recycled object, we do not need to inflate any layouts anymore. This is an action that we must avoid doing several times. To accomplish this action, our code should look like this:
How will the previous code help us optimize our application? In a scenario where we can have 100+ list items to show, Android will only load the items that can fit on the screen. Let's say 6 for example, so the getView method will only be called 6 times. Each time with a convertView value as null.
When we start scrolling to see the 7th item, the getView method will be called again with a convertView value as null. This is because we are still able to see some part of the first element of the list view and we don't have any recycled items.
The optimization starts when the 8th item is going to be painted. By this time the first element won’t be visible anymore, we are going to have a recycled layout. We have to use this because the layout is out of bounds on the screen. The convertView for this element won't be null, so we can managed to reuse it and save time and resources by avoiding inflating a new layout.
How to make a reference to each object in my row.xml file? This is the second part we have to be careful about how we manage these references. So let's review the following code:
First, I created a ListAdapterHolder class which will contain the objects I have in my row.xml file and by using the previous convertView logic, I will make a reference to my layout objects only if convertView is null. Otherwise it will mean that I already did it. To reuse the recycle references, I will have to store them in the convertView tag property by doing a setTag call and to have them back by doing a getTag call.
Finally, we have to manage our array to extract the string we need and set the text to our holder objects to get the following result:
NOTE: This note can save you hours of desperation when creating this kind of views. Remember how we added the List View in our xml? Both width and height are configured as fill patent. Never use wrap_content because it will cause multiple calls to getView method when painting your List View. Android will repaint the List View every time getView is called (It will need to repaint it because its content has change and as wrap_content is set, it dynamically adapts its width and height).
About the Author
Abraham Vargas is a Software Developer with more than 2 years of experience in mobile development. He is an Appcelerator Titanium Certified Developer (TCD) and currently works at iTexico as an Android Developer.