Wednesday, September 11, 2013

Ideal Body Weight Calculator

In this post, you learn to create the Ideal Body Weight Calculator (IBWC) app. The app allows the user to specify his/her sex and height. Then the recommended weight of the user is calculated. The Devine formula is used to calculate the IBW for men. This formula is shown below.
Ideal Body Weight =50kg+2.3* (height-60)

Another formula used in Ideal Body Weight Calculator app is Robinson formula. This formula is appropriate for women. So, we use this formula to calculate the IBW for women.
Ideal Body Weight=49kg+1.7*(height-60)

It is noted that these formulas are appropriate for people who are taller than 5 feet or 60 inches.

For the user interface, we need two TextView, one CheckBox, one EditText, one Spinner, and one Button. The first TextView displays the question text "Are you male?". Next to this TextView, it is a CheckBox view. The CheckBox displays "Yes" next to the tick mark. The user answers the question by selecting or unselecting the CheckBox. We use this CheckBox to determine the sex of the user.

The EditText view is used to allow height input. This value can be in inch or centimeter. The user can specify the measurement of the height value by choosing in or cm from the Spinner view next to this EditView. The file applies layout to the spinner is called spinner_style.xml. This file locates in res/layout directory. Here is the content of the spinner_style.xml file.

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee" />

The last TextView is used to display a note to the user regarding the limitation of the two formulas.
The Button view displays the text "Calculate". When the Calculate button is pushed, the calculateIBW method is called to perform the calculation. The android:onClick property links the Button view and the calculateIBW method. This method is defined in the MainActivity.java file. The background of the Button view is defined by a drawable resource that is written in the bt_style.xml file. The bt_style.xml file is stored in res/drawable directory. Here is the content of the bt_style.xml file:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<solid
android:color="#ff00ff" />
<stroke
android:width="1dp"
android:color="#171717" />
<corners
android:radius="3dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#ffffff"
android:endColor="#992211"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#171717" />
<corners
android:radius="4dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>

Ideal Body Weight Calculator Interface


The activity_main.xml file that is the source for IBWC app user interface can be written as shown below:
<LinearLayout 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=".MainActivity"
android:orientation="vertical"
android:background="@drawable/bgimage">

<LinearLayout
android:layout_marginTop="20dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<TextView
android:id="@+id/txt_qa"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/txt_q"
/>
<CheckBox
android:id="@+id/ch_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/ch_y"

/>

</LinearLayout>

<LinearLayout
android:layout_marginTop="20dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<EditText
android:id="@+id/txt_height"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/hint_h"
android:inputType="numberDecimal" />
<Spinner
android:id="@+id/unit_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

</LinearLayout>

<LinearLayout
android:layout_marginTop="20dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="@+id/bt_calc"
android:background="@drawable/bt_style"
android:text="@string/bt_text"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_marginRight="20sp"
android:onClick="calculateIBW"
/>
<TextView
android:id="@+id/txt_result"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#992211"
android:textSize="20sp"
/>
</LinearLayout>
<TextView
android:id="@+id/txt_note"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_marginTop="20sp"
android:text="@string/txt_note"
/>
</LinearLayout>

As you have seen in the picture above, the IBWC app has a background image. You can specify the background image of an Android app by using the android:background property of the top LinearLayout. In this app, the image that is used as the background when the activity is active is called bgimage that is stored in the res/drawable directory.
android:background="@drawable/bgimage"

Some string values used in the activity_main.xml are defined in the string.xmlf file. The content of the strings.xml file is shown below.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">IBWCalculator</string>
<string name="action_settings">Settings</string>
<string name="txt_q">Are you male?</string>
<string name="ch_y">Yes</string>
<string name="hint_h">Enter your height</string>
<string name="bt_text">Calculate</string>
<string name="txt_note">Note: This calculation is appropriate for people who are taller than 5 feet or 60 inches.</string>

</resources>

The last important file that you have to look and modify is MainActivity.java file. In this file, you need to add some methods such as setUpSpinnerData, getHeight, calculateIBW, and showAlert.

package com.example.ibwcalculator;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

public class MainActivity extends Activity {

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

    public boolean onCreateOptionsMenu(Menu menu) {
        //Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
 
    public void onStart(){
    super.onStart();
    setUpSpinnerData(); //populate data in spinner view
       
    }


    //This method will be invoked to setup data of the spinner view
    public void setUpSpinnerData(){
    Spinner sp=(Spinner)findViewById(R.id.unit_spinner);
    String[] items={"in","cm"};
    ArrayAdapter<String> aa=new ArrayAdapter<String>(this,R.layout.spinner_style,items);
    sp.setAdapter(aa);
   
    }
 
  //This method returns the height in inch
    public double getHeight(String strvalue){
    Spinner sp=(Spinner)findViewById(R.id.unit_spinner);    
   
    double value=Double.valueOf(strvalue);
    if(sp.getSelectedItem().toString().equals("cm")){
    return(value/2.54); //1inch=2.54cm
   
    }
    else {
    return(value);
    }
    }
   
 
 
    //This method calculates the IBW  
    public void calculateIBW(View view){
    double ibw=0.0f;
    CheckBox ch=(CheckBox)findViewById(R.id.ch_y);
    EditText txth=(EditText)findViewById(R.id.txt_height);
    String strvalue=txth.getText().toString();
    if(strvalue.length()>0){
    double height=getHeight(strvalue);    
    if(ch.isChecked()) //calculate ideal body weight for men
    ibw=50+2.3*(height-60);
    else //calculate ideal body weight for women
    ibw=49+1.7*(height-60);
    //create decimal formatter object to format the result
    NumberFormat nf=new DecimalFormat("###.00");    
    //display the result in txt_result
    TextView txtresult=(TextView)findViewById(R.id.txt_result);    
    txtresult.setText("IBW="+nf.format(ibw)+"kg");
   
    }
   
    else{
    showAlert();
    }
    }
 
 
     //This method will be invoked to display alert dialog
     public void showAlert(){
   
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
         builder.setMessage("Please enter your height!");
         builder.setCancelable(true);
         builder.setPositiveButton("OK", new OkOnClickListener());
         AlertDialog dialog = builder.create();
         dialog.show();
   
     }
     private final class OkOnClickListener implements
     DialogInterface.OnClickListener {
      public void onClick(DialogInterface dialog, int which) {
      dialog.dismiss();
      }
     }

 
}


The setupSpinnerData is invoked when the app starts to populate entries of the spinner. These entries are in and cm. You specify the entries of the spinner in the ArrayAdapter object then set this object to the Spinner view by using its setAdapter method. When you create ArrayAdapter object from the ArrayAdapter class, you need to provides three values to constructor of the ArrayAdapter class. The first value is the context. You can use this for this value to refer to the current activity. The second value is the layout of the Spinner view. This layout is defined in the spinner_style.xml file as mentioned above. The last value is the array that contains entries of the spinner.
The getHeight method returns the height input in inch. This value will be used in the calculateIBW method to calculate the ideal body weight for the user.
The calculateIBW is invoked when the user pushed the Calculate button. This method calculate the ideal body weight of the user based on his/her sex. If the user is male (CheckBox is selected), the Davine formula is used. Otherwise, the Robinson formula is used.
The showAlert method is invoked to display a dialog to ask the user to enter his/her height in the EditText, txt_height. This alert dialog is displayed only when the user leaves the EditText, txt_height blank and pushes the Calculate button. In Android, the alert dialog box can be created by using the Builder class. This class is a sub-class of the AlertDialog class.

Testing ideal weight calculator

Download apk file of the Ideal Body Weight Calculator app

2 comments: