Android health app Design , building the ListView with Model View Controller Pattern

MVCIn a previous tutorial ,we created the Android Studio project for our app but we really didn’t do anything fun and interesting.This is where the fun begins as they say.We are going to add a list view to our app ,following the Model View Controller Design Pattern ,we are going to wire the list view to our internal model so our app is flexible from the developer’s perspective,in this regard Adapters and ViewHolders are introduced.Along the way we will discuss some design choices we make to make our app the best Calorie Counter app the earth has ever seen… 😉 ,lets get going.

Recap on the Design

We have already discussed a rough design of what we want the app to look like.The design figure is reproduced below for convenience.We directly notice that the listView(that displays the list of foods) is a major component of our user interface.

ryaNezaDesign

Android has created many different implementations of the listView along the course of its development.One of them is the RecyclerView which is defined as “A flexible view for providing a limited window into a large data set “.You have probably already seen a listView in some of your android apps ,a quick example is the list of contacts in your favorite instant messaging app like whatsapp.RecyclerView is a smart implementation of such lists google engineers have come up with so far.RecyclerView is smart in that it doesn’t load all the data in the listView at once ,instead it just loads what is needed to display the elements in the visible area of the screen , when you scroll ,the display part of your code is reused and only the data is reloaded within.This greatly reduces the RAM consumption of your app which is something you should care about.

You don’t need to understand the details of how RecyclerView does what it does,but to use it effectively ,you need to have a basic understanding of the Model View Controller design pattern.Don’t be scared by this pattern ,as it is explained shortly.

Android Model View Controller Pattern.

The Model View Controller pattern is a design good practice that aims at separating the manipulation of data from the management of the user interface in software engineering.The main components of the pattern are shown below.

android_model_view_controller

We see three components in the figure ,MODEL ,VIEW and CONTROLLER.Each of these components is an object in your app ,in other words ,an instance of some class you define.The view is the object the user interacts with.On our app ,it is the ListView(RecyclerView) object that we can scroll through to see the items.

The Model is the object that contains just data ,nothing else.The data displayed by the View object comes from the Model object.But the View doesn’t communicate with the Model directly ,it goes through the Controller object.

The operations flow with MVC is as follows :(1) The user modifies data in the food weight input field (a component of the View) and commits changes (2) The Controller which is constantly watching for changes in the View learns of the change and (3) Notifies the Model.The model updates its data with the change.(1,2,3) focus on changes being propagated to from the View to the Model through the controller.In our figure above this can be captured with : View(User Action) ->Controller(Property Update) ->The Model knows of the Change.

Sometimes change is propagated the other way round,lets assume that for some reason data in the Model has changed and the View needs to be updated.(4)Something causes the data,for example the food name in the model to change (5)Again the Controller is constantly watching for changes in the Model this time (not the View) (6) As soon as it learns of the change ,the Controller notifies the View of the change and the user can see the change in the user interface component.(4,5,6) focus on changes being propagated from the Model to the View through the Controller.In our figure above this can be captured with : Model(Property change)->Controller(Component update)->The View updates and the user can see the change.

This seems like complicating things at first but the benefits you get outweigh the effort you put in as you will see later.You should note that this MVC pattern is not something specific to Android .You will see it in most technologies that deal with user interfaces.With the basics of the MVC pattern out of the way I would like to zoom in and focus on how this model applies to android apps and specifically to the RecylerView we are interested in today.Lets start by the figure below.

android_specific_mvc

On the View side ,android implements the RecyclerView class as our View component.It allows us to build a scrollable list of components to be displayed on screen.The View class does not know the details of how each list item looks like by itself ,it doesn’t even know the number of list items it has to display .The RecyclerView class relies on its Controller class for all that information.

Speaking of the Controller ,Android implements the RecyclerView.Adapter class as our Controller class.This class knows of (1) our Model (2) The ViewHolder for the Adapter…,wait a minute,what is this ViewHolder class thing?It’s a class that defines the details of the looks for each list item.(3) How to fetch data in the model and stuck it in the View.

In our app ,FoodAdapter is our Controller class ,it is a subclass of RecyclerView.Adapter.Subclasses of RecyclerView.Adapter must implement three essential functions ,that our view uses to communicate with our Controller.(1) onCreateViewHolder() ,the View calls this function everytime it needs to display a list item ,(2) onBindViewHolder() , the View calls this function every time it needs to fill the ViewHolder with data from the Model and (3) getItemCount() ,the View calls this function to learn about how many list items it needs to display.You can see these functions depicted in the figure above.

The FoodModel class has nothing special ,it simply is a wrapper class around an array of Food Items.In our app we are going to create a Food class that encapsulates the details like food name ,calorie count and the like.All this will become clear as we build these classes in Android Studio which is what we are doing next.

Cooking up our Design in Android Studio

Open Imirire in Android Studio ,if you don’t have the code from the previous tutorial ,you can download it form the project github repository.In the MainActivity.java file change the MainActivity class so that it extends Activity and not AppCompatActivity as shown below.

android_extend_activity

We remove AppCompatActivity as it adds a top pane in our activity and we don’t want it in our design.Now we add the RecyclerView to our app.But the RecyclerView class resides in an android library that is not loaded by default.To load it hit File->Project Structure.The Project Structure dialog comes up as shown below.

android_project_structure_1Choose app in the left pane ,click on the green plus button ,in the dialog that pops up ,scoll down until you see a line containing recyclerview-v7 as shown below.

android_recyclerview_dependency

Hit the OK button twice and Android should load your library in a few seconds.We are going to add the RecylerView from the layout xml file for our MainActivity.Open up activity_main.xml and it may look as follows:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.blikoon.imirire.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"/>
</RelativeLayout>

We have mentioned in a previous tutorial that android uses xml layouts files to build user interfaces that your users will see.This is one of them.We won’t attempt to explain all the details as there are a good number of good reference material out there.Apply the changes so that the modified file looks as shown in the code snipped below.Note that the modified code section is highlighted in bold and red.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.blikoon.imirire.MainActivity">


    <TextView
        android:id="@+id/calorie_display"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
       />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/food_list_recycler_view"
        android:layout_below="@id/calorie_display"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</RelativeLayout>

We have a RelativeLayout tag wrapping all the code.The RelativeLayout arranges its child items relative to each other.The line android:layout_below=”@id/calorie_display”
instructs the android system to layout our RecyclerView right below our calorie_display TextView.

You should also notice that both the textView and the RecyclerView have IDs.We will use these in our Java code to reference them.Add a piece of text textView right before we preview so it looks like this:

<TextView
    android:id="@+id/calorie_display"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="777.5"
    />

Click on the design tab and our design looks as follows:

android_design_preview

 

Creating the Model for data.

The TextView is shown on top and the RecyclerView is shown as a list right below.With the Views in place now its time to add our Model.Add a new Java class as shown below and name it Food.

android_new_java_class

Now modify the class so it looks as show in the code snipped below:

Food.java

package com.blikoon.imirire;

import java.util.UUID;

/**
 * Created by gakwaya on 2/10/2016.
 */

public class Food {
    private String mFoodName;
    private double mGramCount;
    private double mCalCount;
    private boolean isChecked;
    private UUID mFoodId;

    public boolean isChecked() {
        return isChecked;
    }

    public void setIsChecked(boolean isChecked) {
        this.isChecked = isChecked;
    }

    public double getCalCount() {
        return mCalCount;
    }

    public void setCalCount(double calCount) {
        this.mCalCount = calCount;
    }

    public double getGramCount() {
        return mGramCount;
    }

    public void setGramCount(double gramCount) {
        mGramCount = gramCount;
    }

    public Food(String foodName ,double gramCount,String foodIcon,double calCount)
    {
        mFoodName = foodName;
        mGramCount = gramCount;
        mCalCount=calCount;
        isChecked=false;
        mFoodId = UUID.randomUUID();
    }

    public String getFoodName() {
        return mFoodName;
    }

    public void setFoodName(String foodName) {
        mFoodName = foodName;
    }

}

We have a bunch of instance variables to store information about each food item.Namely the name of the food , the calorie ratio per 100 gram,whether the food is checked and a unique ID for the food.mGramCount will store the number of grams that the user will input in our user interface.The other highlighted part of our class is the constructor that simply assigns initial values to our instance variables.Note that we took advantage of the UUID class provided by Java to uniquely identify our objects.

Add a new Java class called FoodModel that will store the list of foods.Modify it so it looks as follows:

FoodModel.java

package com.blikoon.imirire;

import android.content.Context;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by gakwaya on 2/10/2016.
 */

//This class is a singleton and supposed to only have
//one instance across the whole application.
public class FoodModel
{
    private static FoodModel sFoodModel;
    private List<Food> mFoods;

    public static FoodModel get(Context context)
    {
        if(sFoodModel == null)
        {
            sFoodModel = new FoodModel(context);
        }
        return  sFoodModel;
    }

    private FoodModel(Context context)
    {
        mFoods = new ArrayList<>();
        populateWithInitialFoods();
    }
    
    private void populateWithInitialFoods()
    {
        Food food1 = new Food("Rice",0,"RiceIcon",351.0);
        for(int i = 0 ; i < 50 ;i++) {
            mFoods.add(food1);
        }   
    }
    
    public List<Food> getFoods()
    {
        return mFoods;
    }

}

This class is a Singleton ,a singleton is an object (of a class) for which there is only one instance in the whole application.There is no need to have multiple food models in our app as one is enough.We create it once and simply use it for the rest of the lifetime of the application.

One way to create a singleton in Java ,is to make the constructor of the class private and provide a static function( accessible without the need of instantiating) that creates the instance if not there already and simply returns the instance if already there.The get function reproduced below for convenience illustrates that.

public static FoodModel get(Context context)
{
    if(sFoodModel == null)
    {
        sFoodModel = new FoodModel(context);
    }
    return  sFoodModel;
}

Besides the static sFoodModel instance variable ,our class also defines a list of Food objects.This is where our Foods will be stored.We populate the list with initial dummy food data just for test purposes.We will add real data later.

private FoodModel(Context context)
{
    mFoods = new ArrayList<>();
    populateWithInitialFoods();
}

Again notice that the FoodModel constructor is private .This makes sure it can only be called from within the FoodModel class and that only happens in the get function effectively making our class a singleton.We will discuss the Context argument later when we link our model to the View.

Creating the Controller : Connecting the Model to the View.

Coming back to our MVC design guide image ,as for now we have designed and finished the Model part :the FoodModel class ,and the View part : our RecyclerView in the activity_main.xml layout xml file.

android_specific_mvc

We need to implement the Controller to complete our design.FoodAdapter and FoodHolder classes will be implemented as inner classes to MainActivity class for now to keep things simple.But before we do that ,we add a new layout xml file that controls the looks of each single Food item.From our design we see that FoodHolder controls this and that it is three items laid our horizontally from left to right.

android_food_holder_look

Add a new layout xml file and name it list_item_food as shown in the figure below

android_add_new_resource_file

Hit the OK button and modify the resulting layout xml file as follows:

list_item_food.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <CheckBox
        android:id="@+id/list_item_food_checkbox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"/>

    <TextView
        android:id="@+id/list_item_food_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="foodName"
       />
    
    <EditText
        android:id="@+id/list_item_gram_input_field"
        android:layout_width="90dp"
        android:layout_height="wrap_content"
        android:hint="0.0"
        />
</LinearLayout>

The preview looks as shown below:

android_list_item_food_preview

There is still more we can do to make it look better but we leave it like this for now.We ll come back to this later.Now back to our Controller classes.

You are going to add the FoodHolder inner class to your already available MainActivity class.Modify the class as shown below.The new code is highlighted in red.

package com.blikoon.imirire;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

    
    //The FoodHolder class
    private class FoodHolder extends RecyclerView.ViewHolder
    {
        private CheckBox foodItemCheckBox;
        private TextView foodNameTextView;
        private EditText gramInputField;
        private Food mFood;

        public FoodHolder(View itemView)
        {
            super(itemView);
            foodItemCheckBox = (CheckBox) itemView.findViewById(R.id.list_item_food_checkbox);
            foodNameTextView = (TextView) itemView.findViewById(R.id.list_item_food_name);
            gramInputField = (EditText) itemView.findViewById(R.id.list_item_gram_input_field);
        }

        public void bindFood(Food food)
        {
            mFood = food;
            if(mFood == null)
            {
                Log.d("Imirire","Got a null food object");
            }else
            {
                foodItemCheckBox.setChecked(mFood.isChecked());
                foodNameTextView.setText(mFood.getFoodName().toString());

                if(mFood.getGramCount()!=0.0)
                {
                    gramInputField.setText(String.valueOf(mFood.getGramCount()));
                }

            }
        }
    }

    //FoodHolder class ends here.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

Note that FoodHolder is a sublclass of RecyclerView.ViewHolder.Also Remember that in our design ,FoodHolder is a class that helps FoodAdapter( not defined yet) to define the specifics looks for each single item.First it defines instance variables (in code) for what each list item will contain ,namely a checkbox ,a text view to contain the food name and a text input field where the user will type the number of grams for the food item of choice.We bind those instance variables to the items in our list_item_food.xml file in the constructor:

public FoodHolder(View itemView)
        {
            super(itemView);
            foodItemCheckBox = (CheckBox) itemView.findViewById(R.id.list_item_food_checkbox);
            foodNameTextView = (TextView) itemView.findViewById(R.id.list_item_food_name);
            gramInputField = (EditText) itemView.findViewById(R.id.list_item_gram_input_field);
        }

FoodHolder also helps in taking data from the model and stuff it in the layout view items.This is achieved in our bindFood function.

public void bindFood(Food food)
{
    mFood = food;
    if(mFood == null)
    {
        Log.d("Imirire","Got a null food object");
    }else
    {
        foodItemCheckBox.setChecked(mFood.isChecked());
        foodNameTextView.setText(mFood.getFoodName().toString());

        if(mFood.getGramCount()!=0.0)
        {
            gramInputField.setText(String.valueOf(mFood.getGramCount()));
        }

    }
}

The function simply takes the data it gets from the Food argument and populates the data in the view layout file child items.You will see how this function is called in the FoodAdapter class which is what we are implementing next.The MainActivity.java file is show below with the FoodAdapter class added.

MainActivity.java

package com.blikoon.imirire;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends Activity {


    //The FoodHolder class
    private class FoodHolder extends RecyclerView.ViewHolder
    {
        private CheckBox foodItemCheckBox;
        private TextView foodNameTextView;
        private EditText gramInputField;
        private Food mFood;

        public FoodHolder(View itemView)
        {
            super(itemView);
            foodItemCheckBox = (CheckBox) itemView.findViewById(R.id.list_item_food_checkbox);
            foodNameTextView = (TextView) itemView.findViewById(R.id.list_item_food_name);
            gramInputField = (EditText) itemView.findViewById(R.id.list_item_gram_input_field);
        }

        public void bindFood(Food food)
        {
            mFood = food;
            if(mFood == null)
            {
                Log.d("Imirire","Got a null food object");
            }else
            {
                foodItemCheckBox.setChecked(mFood.isChecked());
                foodNameTextView.setText(mFood.getFoodName().toString());

                if(mFood.getGramCount()!=0.0)
                {
                    gramInputField.setText(String.valueOf(mFood.getGramCount()));
                }
            }
        }
    }

    //FoodHolder class ends here.
    
    //FoodAdapter class Implementation

    private class FoodAdapter extends RecyclerView.Adapter<FoodHolder>
    {
        private List<Food> mFoods;

        public FoodAdapter (List<Food> foods)
        {
            mFoods = foods;
        }

        public FoodHolder onCreateViewHolder( ViewGroup parent,
                                              int viewType)
        {
            LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
            View view = layoutInflater
                    .inflate(R.layout.list_item_food, parent,
                            false);
            return new FoodHolder(view);
        }

        public void onBindViewHolder(FoodHolder holder ,int position)
        {
            Food food = mFoods.get(position);
            holder.bindFood(food);
        }
        
        @Override
        public int getItemCount()
        {
            return mFoods.size();
        }
        
    }
    
    //FoodAdapter class ends here

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

First notice that the class implements three functions : (1) onCreateViewHolder (2) onBindViewHolder and (3) getItemCount().You can recognize these functions from our MVC design image.

onCreateViewHoder is called when the RecyclerView needs to add an item in the listItem place holder.Remember that we have shown the listView of the RecyclerView as ListItem place holders .

android_abstract_place_holders

RecyclerView doen’t know what each list item looks like until it calls its Adpaters onCreateViewHolder method:

public FoodHolder onCreateViewHolder( ViewGroup parent,
                                      int viewType)
{
    LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
    View view = layoutInflater
            .inflate(R.layout.list_item_food, parent,
                    false);
    return new FoodHolder(view);
}

In this function , the list item view is created from the list_item_food view template we have created before.

After creating the View for the list item place holder ,now the View needs to fill in the data,this is where onBindViewHolder function comes in.

public void onBindViewHolder(FoodHolder holder ,int position)
{
    Food food = mFoods.get(position);
    holder.bindFood(food);
}

Basicaly the RecyclerView says ,I want to know the data I can stuff in the ViewHolder in my ListItems at this position.We fetch the food object at that position and bind its data to RecyclerView’s ViewHolder at the same position.Remember that bindFood simply takes data from the food and stuffs it in the ViewHolders child items( checkbox ,TextView and EditText).

The last function getItemCount simply lets the RecyclerView know of the number of list items it has to manage.

Connecting the dots and running the app.

The Model ,View and Controller for our app are all ready ,all that is left is connecting them and running the app to see how it looks.Apply the changes below to your MainActivity.java code.

MainActivity.java

package com.blikoon.imirire;

import android.app.Activity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends Activity {

    private RecyclerView mFoodListRecyclerView;
    private FoodAdapter mAdapter;
    private TextView caloryDisplayTextView;


    //The FoodHolder class
    private class FoodHolder extends RecyclerView.ViewHolder
    {
        private CheckBox foodItemCheckBox;
        private TextView foodNameTextView;
        private EditText gramInputField;
        private Food mFood;

        public FoodHolder(View itemView)
        {
            super(itemView);
            foodItemCheckBox = (CheckBox) itemView.findViewById(R.id.list_item_food_checkbox);
            foodNameTextView = (TextView) itemView.findViewById(R.id.list_item_food_name);
            gramInputField = (EditText) itemView.findViewById(R.id.list_item_gram_input_field);
        }

        public void bindFood(Food food)
        {
            mFood = food;
            if(mFood == null)
            {
                Log.d("Imirire","Got a null food object");
            }else
            {
                foodItemCheckBox.setChecked(mFood.isChecked());
                foodNameTextView.setText(mFood.getFoodName().toString());

                if(mFood.getGramCount()!=0.0)
                {
                    gramInputField.setText(String.valueOf(mFood.getGramCount()));
                }

            }
        }
    }

    //FoodHolder class ends here.


    //FoodAdapter class Implementation

    private class FoodAdapter extends RecyclerView.Adapter<FoodHolder>
    {
        private List<Food> mFoods;

        public FoodAdapter (List<Food> foods)
        {
            mFoods = foods;
        }

        public FoodHolder onCreateViewHolder( ViewGroup parent,
                                              int viewType)
        {
            LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
            View view = layoutInflater
                    .inflate(R.layout.list_item_food, parent,
                            false);
            return new FoodHolder(view);
        }

        public void onBindViewHolder(FoodHolder holder ,int position)
        {
            Food food = mFoods.get(position);
            holder.bindFood(food);
        }

        @Override
        public int getItemCount()
        {
            return mFoods.size();
        }

    }

    //FoodAdapter class ends here

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mFoodListRecyclerView = (RecyclerView)
                findViewById(R.id.food_list_recycler_view);
        mFoodListRecyclerView.setLayoutManager(new LinearLayoutManager(getBaseContext()));

        //Display textView
        caloryDisplayTextView = (TextView)findViewById(R.id.calorie_display);


        FoodModel model = FoodModel.get(getBaseContext());
        List<Food> foods = model.getFoods();

        mAdapter = new FoodAdapter(foods);
        mFoodListRecyclerView.setAdapter(mAdapter);
    }
}

First we get the instances to the RecyclerView , the Adapter and our calory display TextView.

private RecyclerView mFoodListRecyclerView;
private FoodAdapter mAdapter;
private TextView caloryDisplayTextView;

Then ,in the onCreate() function of the MainActivity class ,we initialize these variables:

mFoodListRecyclerView = (RecyclerView)
        findViewById(R.id.food_list_recycler_view);
mFoodListRecyclerView.setLayoutManager(new LinearLayoutManager(getBaseContext()));

//Display textView
caloryDisplayTextView = (TextView)findViewById(R.id.calorie_display);


FoodModel model = FoodModel.get(getBaseContext());
List<Food> foods = model.getFoods();

mAdapter = new FoodAdapter(foods);
mFoodListRecyclerView.setAdapter(mAdapter);

after initializing the mFoodListRecyclerView item ,we apply a LayoutManager to it.The layout mananager ,as its name implies ,controls how list items are organized in the RecyclerView.You can find out more on this in the android documentation.We also create our FoodModel passing in the base context of our app.The FoodAdapter is created passing in the list of foods from the FoodModel and we tell the RecyclerView to use that adapter.

Oooouuf! Finally .If you made it this far ,you really are dedicated about learning android development .Look up your code for errors and when you have solved them hit the run button to see your MVC RecyclerView powered best ever Calorie Counter app in action!Mine is shown below running on my Genymotion virtual device.

android_app_first_run

Our calorie dispay textview can be seen on top with the listView right below it.The list view is displaying dummy data we have stuffed in our model .The app is running but it still needs to be worked on.The textView needs to be made more beautiful to resemble a calculator display and the child items in list items need to be laid out better.This and many other improvements are subject of future tutorials.The complete source code for the project up to this tutorial is available at my github repository .If you come across any issue working with this tutorial or have any suggestions to do better ,please drop me a line.I hope this comes in helpful to somebody someday.

 

Posted in android, Tutorials and tagged , , .

Daniel Gakwaya loves computer Hardware/Software.He is a Software Engineer at BLIKOON and lead developer of bliboard-The whiteboard system currently marketed by the company.He is known to hack around on any piece of tech that happens to pick his interest. More on his tech endeavors here
Follow him on Twitter

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.