Wednesday, October 2, 2013

Currency Converter

In this post, you learn to create a currency converter app. This currency converter can be used to convert twelve currency types. The currency types that the converter supports are shown below.

-AUD (Australian Dollar)
-CAD (Canadian Dollar)
-CHF (Swiss Franc)
-EUR (Euro)
-GBP (British Pound)
-JPY (Japnese Yen)
-NZD (New Zealand Dollar)
-KHR (Khmer Riel)
-USD (American Dollar)
-CNY (Chinese Yuan Renminbi)
-THB (Thai Baht)
-INR (Indian Rupee)

To follow this tutorial, you will need to create a new Android project in Eclipse. The project will be named CurrencyConverter.

In the CurrencyConverter app, the user is allowed to select a pair of currency for the conversion. One is the currency that will be converted from and another is the currency that will be converted to. We also allow the user to input the exchanged rate and the amount to be converted. One button is provided to show the table of conversion. The table displays the currency types and amounts. The currency types that are not the target of the conversion, their amounts are calculated based on their default average exchange rates. For target currency type, its amount is calculated based on the exchange rate provided by the user. The target currency is highlighted.

currency converter main interface


In this CurrencyConverter app, there are two activities. On activity is the main activity that starts when the app initially runs. The components or view that are used to construct the user interface of the main activity are two TextViews, two Spinner, two EditTexts, and one Button. The two TextViews to display the labels of the Spinners. The two Spinners allow the user to select a currency type to convert from and another currency type to converted to. The spinner_style.xml file defines the item style of the Spinners. One EditText is for the user to input the exchange rate and another one allows the user to input the amount for converting. The Show button will be pushed to display the conversion table. This button has background style that defined by the bt_style.xml file. The activity_main.xml file that is the resource of main activity is written as shown below.

activity_main.xml

<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"
    android:orientation="vertical"
    android:background="#ff8899"
    tools:context=".MainActivity" >
<LinearLayout
   android:layout_marginTop="10dp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
    <TextView
        android:id="@+id/from_currency"
        android:layout_width="150dp"
    android:layout_height="wrap_content"
    android:textColor="#ffffff"
    android:textSize="18sp"
        android:text="@string/from_currency" />
    <Spinner
android:id="@+id/fromcurrency_spin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

/>
</LinearLayout>
<LinearLayout
   android:layout_marginTop="10dp"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"      
        android:orientation="horizontal" >
<TextView
        android:id="@+id/to_currency"
        android:layout_width="150dp"
    android:layout_height="wrap_content"
    android:textColor="#ffffff"
    android:textSize="18sp"
        android:text="@string/to_currency" />
    <Spinner
android:id="@+id/tocurrency_spin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"

/>
</LinearLayout>

<EditText
        android:id="@+id/txt_rate"
        android:layout_width="match_parent"
    android:layout_height="wrap_content"
        android:hint="@string/txt_rate"
        android:inputType="numberDecimal" />

<EditText
        android:id="@+id/txt_fromamount"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="@string/txt_fromamount"      
        android:inputType="numberDecimal" />

<Button
   android:id="@+id/bt_show"
   android:background="@drawable/bt_style"
   android:text="@string/bt_label"
   android:layout_width="match_parent"
   android:layout_height="40dp"
   android:gravity="center"
   android:onClick="showResult"
   />


</LinearLayout>


spinner_style.xml

<?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"
 
     />

bt_style.xml

<?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>

The main activity is defined by the MainActivity class. Besides loading the components from the activity_main.xml file, the MainActivity has code to set up the item data of the Spinners. This task is done by calling the setupSpinnerData method. To capture the From currency and To currency, the two Spinners has to register to the items selected event. When the user selected a currency from the first Spinner, the selected currency is stored in the fromCurrency variable. Similarly, the selected currency from the second Spinner is stored in the toCurrency variable.

The showResult result method is invoked when the user pushes the Show button. Before showing the conversion table, the app checks to make sure that the exchange rate text box and the amount text are not blank. The alert dialog box is displayed when he/she tries to click the Show button with the blank exchange rate or amount. The intent object is created to put some data such as From currency, To currency, exchange rate, and amount. The intent object that contains the data is sent to the second activity after the startActivity method is invoked. Below is the content of the MainActivity.java file that has the MainActivity class.

MainActivity.java

package com.example.currencyconverter;

import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

public class MainActivity extends Activity {

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


    @Override
    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;
    }
 
 
 
    protected void onResume(){
    super.onResume();
    setUpSpinnerData();
       
    }
    //This method will be invoked to setup data of the spinner views
    //to show lists of currency types for selection
    public void setUpSpinnerData(){
    Spinner spFrom=(Spinner)findViewById(R.id.fromcurrency_spin);
    Spinner spTo=(Spinner)findViewById(R.id.tocurrency_spin);
    String[] currencyList={"AUD","CAD","CHF","EUR","GBP","JPY","NZD","KHR","USD","CNY","THB","INR"};
    ArrayAdapter<String> afrom=new ArrayAdapter<String>(this,R.layout.spinner_style,currencyList);
    spFrom.setAdapter(afrom);
    spFrom.setOnItemSelectedListener(new ItemSelectedFrom());
    ArrayAdapter<String> ato=new ArrayAdapter<String>(this,R.layout.spinner_style,currencyList);
    spTo.setAdapter(ato);
    spTo.setOnItemSelectedListener(new ItemSelectedTo());
   
    }
 
    private class ItemSelectedFrom implements OnItemSelectedListener{
    public void onNothingSelected(AdapterView<?> av){
   
    }
    public void onItemSelected(AdapterView<?> av, View view, int position, long id){
    TextView sel=(TextView)view;
    String from=sel.getText().toString();
    fromCurrency=from; //capture the currency of the From side
        EditText txtfrom=(EditText)findViewById(R.id.txt_fromamount);
    txtfrom.setHint("Enter "+fromCurrency+" amount");
   
    }
    }
 
    private class ItemSelectedTo implements OnItemSelectedListener{
    public void onNothingSelected(AdapterView<?> av){
   
    }
    public void onItemSelected(AdapterView<?> av, View view, int position, long id){
    TextView sel=(TextView)view;
    String to=sel.getText().toString();
    toCurrency=to; //capture the currency of the To side
       
   
    }
    }
 

    public void showResult(View view){
    EditText txtRate=(EditText)findViewById(R.id.txt_rate);
    EditText txtAmount=(EditText)findViewById(R.id.txt_fromamount);
    if(txtRate.getText().toString().length()<=0 || txtAmount.getText().toString().length()<=0){
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("Please input value in text box.");
            builder.setCancelable(true);
            builder.setPositiveButton("OK", new OnClickListener(){
            public void onClick(DialogInterface di,int which){
            di.cancel();
            }
            });
            AlertDialog dialog = builder.create();      
            dialog.show();

    }
    else{
    //create intent, place data in it and start the ConversionTable activity
    Intent intent=new Intent(this, ConversionTable.class);
    intent.putExtra("fromCurrency", fromCurrency);
    intent.putExtra("toCurrency", toCurrency);
    intent.putExtra("Rate", Double.valueOf(txtRate.getText().toString()));
    intent.putExtra("fromAmount", Double.valueOf(txtAmount.getText().toString()));
    startActivity(intent);
    }
    }
 
}


Another activity is called ConversionTable. It shows when the user pushes the Show button. This activity displays the conversion table as i mentioned above. This activity has a resource xml file called activity_conversion_tabl.xml. This file defines one ListView component to show the conversion table.

activity_conversion_tabl.xml

<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"
    android:orientation="vertical"
    tools:context=".ConversionTable" >

   <ListView
        android:id="@+id/conversion_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
   
       />
     

</LinearLayout>


When constructing the conversion table, you will need the icon images of the countries that their currency types are used in the CurrencyConverter app. You can download the icon images from here.
In default, ListView in Android displays on text. However, this CurrencyConverter app, the conversion table has to display icon images, currency types, and amount text. We have to customize the ListView to do this task. To customize the ListView, you start from defining the components for its item. The ListView has its own layout file called listlayout.xml that defines the layout of its item or row. The content of the listlayout.xml file is show below.

listlayout.xml

<?xml version="1.0" encoding="utf-8"?>
<!--  Single List Item Design -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:background="#000000"
    android:padding="5dip" >

<ImageView
    android:id="@+id/icon"
    android:layout_width="30dp"
    android:layout_height="30dp"
    android:padding="5sp"
    android:contentDescription="countryicon"
   />

 <TextView
    android:id="@+id/currency"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#ffffff"
        android:textStyle="bold" >
</TextView>
<TextView
    android:id="@+id/label_amount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10sp"
        android:textSize="20sp"
        android:textColor="#ffffff"
        android:textStyle="bold" >
</TextView>
</LinearLayout>

In this listlayout file, we define three components-- one ImageView, and two TextViews. The ImageView will display the icon image. One TextView displays the currency type, and another TextView displays the amount.

Next, you need to extends the ArrayAdapter class that acts as the data source of the ListView. This class is called ListAdapterModel. Its getView method is overridden to allow the ListView to display icon image, currency type, and amount.

ListAdapterModel.java

package com.example.currencyconverter;
import java.text.DecimalFormat;
import android.content.Context;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class ListAdapterModel extends ArrayAdapter<String>{
int groupid;
String[] clist;
Context context;
String to;
Double[] alist;

public ListAdapterModel(Context context, int vg,String[] clist, Double[] alist, String to){
super(context,vg, clist);
this.context=context;
groupid=vg;
this.clist=clist;
this.to=to;
this.alist=alist;
}
public View getView(int position, View convertView, ViewGroup parent) {

        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View itemView = inflater.inflate(groupid, parent, false);
        ImageView imageView = (ImageView) itemView.findViewById(R.id.icon);
        imageView.setImageDrawable(context.getResources().getDrawable(getImage(position)));
        TextView textCurrency = (TextView) itemView.findViewById(R.id.currency);
        TextView textAmount= (TextView) itemView.findViewById(R.id.label_amount);
        textCurrency.setText(clist[position]);
        DecimalFormat df=new DecimalFormat("#,###.0000");
        String value=df.format(Double.valueOf(alist[position]));
        textAmount.setText(value);
        if(clist[position].equals(to)) //highlight the target conversion row
        itemView.setBackgroundColor(Color.MAGENTA);
        return itemView;
     
}

public Integer getImage(int pos){
Integer[] imageIds=new Integer[12];
imageIds[0]=R.drawable.aud;
imageIds[1]=R.drawable.cad;
imageIds[2]=R.drawable.chf;
imageIds[3]=R.drawable.eur;
imageIds[4]=R.drawable.gbp;
imageIds[5]=R.drawable.jpy;
imageIds[6]=R.drawable.nzd;
imageIds[7]=R.drawable.khr;
imageIds[8]=R.drawable.usd;
imageIds[9]=R.drawable.cny;
imageIds[10]=R.drawable.thb;
imageIds[11]=R.drawable.inr;

return(imageIds[pos]);

}

}


Inside the ConversionTable class, Java code is written to construct the conversion table. The constructTable method is called to prepare the data for the ListView and display the currency conversion table. The data to be defined here are the array of amounts (amounts) and the currency list (clist). Each amount that is the item of the amounts array is calculated based on this formula:

amounts[i]=rate*amount;

The default average exchange rates are used for the currency types that are not the target. For the target conversion currency, the rate input by the user will be used. The clist array contains all currency types that are supported by the CurrencyConverter app.

The amounts array is used by the ListAdapterModel class to display the amounts and the clist array contains the currency types to show with the amount on the conversion table. The icon image list is not defined here. It is in the ListAdapterModel class.

currency converter conversion table sub interface


The AndroidManifest.xml file is modified to allow the second activity to be the child of the main activity. When you are on the second activity and press the back button, you will come back to the main activity. The content of the AndroidManifest.xml file is shown below.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.currencyconverter"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/currencyconverter"
        android:label="@string/app_name"
     
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.currencyconverter.MainActivity"
            android:label="@string/app_name"
            android:configChanges="orientation"
             >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.currencyconverter.ConversionTable"
            android:label="@string/title_activity_conversion_table"
             android:configChanges="orientation"
            android:parentActivityName="com.example.currencyconverter.MainActivity"          
             >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.currencyconverter.MainActivity" />
         
            >
        </activity>
     
    </application>

</manifest>


Now you are ready to run the program. If you have any questions, please write them at the comment section. I will reply as soon as possible. Thank you for reading this post.

Download the apk file of the CurrencyConverter app.

6 comments:

  1. como transforma isso tudo em arquivos apk, para fazer a instalação no andoid?

    ReplyDelete
  2. there is no ConversionTable .java code

    ReplyDelete
  3. Trading courses has become a very popular asset class to trade. Trading course you’ll be in a position to make great trades.

    Online Forex Brokers

    ReplyDelete
  4. Hi this one is great and is really a good post. I think it will help me a lot in the related stuff
    Great article ...Thanks for your lovely post, the contents are quiet interesting. I will be waiting for your next post.
    Image Icon Converter

    ReplyDelete
  5. project run but cannot display second screen
    or output

    ReplyDelete
  6. con not display conversion table
    send me solution

    ReplyDelete