Search This Blog

Saturday, November 28, 2009

First Application_Part3 (Activities)

We have got our View and Model so far, it means that we've got one more thing left to do, our controller which is called Activity in Android world. we will need 3 activities since we have 3 different functionality in our application, our calculator , Save result page and View Page. you might say , well it's actually one main application with three functions and that's what i though initially, but apparently we need a different activity for each of them , i'm not sure though... but i kinda like this idea...real modularity.
Any way you can see our main activity below, it's a bit messy but what i was gonna do was to find out how many ways there are for handling events...you can see that i have used 3 different ways to handling onClick event for our calculator's buttons. if you cannot figure out what oneClicked , twoClicked and... are. you would be better to take a look at our calculator layout file which you can find at First Application_Part1 .



package com.amir.calculator;

import com.amir.calculator.Calculator.Operation;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener{
/** Called when the activity is first created. */

private TextView textView;
private double currentValue = 0;
private Button addBtn;
private Button subBtn;
private Button divBtn;
private Button mulBtn;
private Button SRBtn;
private Button clearBtn;
private Button showBtn;
private Button equal;
private Calculator calc = new Calculator();

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

this.textView = (TextView)findViewById(R.id.note);
this.textView.setText(Double.toString(this.currentValue));
this.addBtn = (Button)findViewById(R.id.addition);
this.subBtn = (Button)findViewById(R.id.subtract);
this.divBtn = (Button)findViewById(R.id.devide);
this.mulBtn = (Button)findViewById(R.id.multiply);
this.equal = (Button)findViewById(R.id.equalSign);
this.SRBtn = (Button)findViewById(R.id.save);
this.clearBtn = (Button)findViewById(R.id.clear);
this.showBtn = (Button)findViewById(R.id.show);

this.addBtn.setOnClickListener(this);
this.subBtn.setOnClickListener(this);
this.divBtn.setOnClickListener(this);
this.mulBtn.setOnClickListener(this);
this.equal.setOnClickListener(this);

this.SRBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

Intent intent = new Intent();
intent.setAction("com.amir.calculator.SAVE");
intent.putExtra("com.amir.calculator.result", MainActivity.this.currentValue);
startActivity(intent);

}
});

this.clearBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

MainActivity.this.textView.setText("");
calc.resetCalculator();
MainActivity.this.currentValue = 0;

}
});


this.showBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {

Intent intent = new Intent();
intent.setAction("com.amir.calculator.SHOW");
startActivity(intent);

}
});

}

@Override
public void onClick(View source) {

if(this.currentValue == 0)
return;

if(!this.calc.isStarted()){
this.calc.initiateProcess(this.currentValue);
}
else if (source.getId() != R.id.equalSign){ //to support cascading operations...
this.currentValue = doCalculation();
this.calc.initiateProcess(this.currentValue);
}

if(source.getId() == R.id.addition){
this.textView.setText("+");
this.calc.nextOperation(Calculator.Operation.ADD);
this.currentValue = 0;
}
else if(source.getId() == R.id.subtract){
this.textView.setText("-");
this.calc.nextOperation(Calculator.Operation.SUBTRACT);
this.currentValue = 0;
}
else if(source.getId() == R.id.devide){
this.textView.setText("/");
this.calc.nextOperation(Calculator.Operation.DIVIDE);
this.currentValue = 0;
}
else if(source.getId() == R.id.multiply){
this.textView.setText("*");
this.calc.nextOperation(Calculator.Operation.MULTIPLY);
this.currentValue = 0;
}
else if(source.getId() == R.id.equalSign){
this.textView.setText(Double.toString(doCalculation()));
this.calc.resetCalculator();
}
else
this.textView.setText("ERROR!!!");

}

private double doCalculation(){
double result = this.calc.doOperation(this.currentValue);
this.currentValue = result;

return result;
}

public void oneClicked(View btn){
this.recalculateValue(1);
}

public void twoClicked(View btn){
this.recalculateValue(2);
}

public void threeClicked(View btn){
this.recalculateValue(3);
}

public void fourClicked(View btn){
this.recalculateValue(4);
}

public void fiveClicked(View btn){
this.recalculateValue(5);
}

public void sixClicked(View btn){
this.recalculateValue(6);
}

public void sevenClicked(View btn){
this.recalculateValue(7);
}

public void eightClicked(View btn){
this.recalculateValue(8);
}

public void nineClicked(View btn){
this.recalculateValue(9);
}

public void zeroClicked(View btn){
this.recalculateValue(0);
}

private void recalculateValue(int value){
this.currentValue = (this.currentValue*10)+value;
this.textView.setText(Double.toString(this.currentValue));

}

}




it might not be the best algorithm for implementing a calculator , but i'm not worried about that...at least at this stage ;)
you can also see how we interact with other activities in android, when user presses SR button we need to run other activity to Save the result so what we need to do is to send a message for that activity with all required information and ask it to do what it's supposed to do... startActivity() function is responsible to deliver our messages to other activities and Intent class represents our messages(receiver address and required information).

and here is our Save Result Activity :



package com.amir.calculator;

import java.util.Calendar;

import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class SaveActivity extends Activity implements OnClickListener{

private double value;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.save);

this.value = getIntent().getDoubleExtra("com.amir.calculator.result", 0);
TextView view = (TextView)findViewById(R.id.ResultBox);
view.setText(Double.toString(this.value));

Button btn = (Button)findViewById(R.id.SaveBtn);
btn.setOnClickListener(this);

}

@Override
public void onClick(View v) {

ContentValues values = new ContentValues();
EditText text = (EditText)findViewById(R.id.content);
String content = text.getText().toString();

if( content == null || content.length() == 0){
text.setText("DefaultName - "+Calendar.getInstance().getTime().toString());
return;
}

values.put(CalcContent.Content.NOTE, content);
values.put(CalcContent.Content.VALUE, this.value);
getContentResolver().insert(CalcContent.Content.CONTENT_URI, values);

finish();

}


}


the most interesting thing here would probably be how we saved our data, we have already implemented our ContentProvider and also defined it in our Android Manifest file, so all we need to do is to use getContentResolver() function, it will then go and start searching Android manifest file to find a ContentProvider which is able to handle requested data type , in this case
CalcContent Data type.

Our last activity is 'Show Saved Results' :




package com.amir.calculator;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class ShowActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.show);
TextView view = (TextView)findViewById(R.id.viewBox);


Cursor cursor = getContentResolver().query(CalcContent.Content.CONTENT_URI, null, null, null, null);
int number = 0;

if(cursor.moveToFirst()){
int noteIndex = cursor.getColumnIndex(CalcContent.Content.NOTE);
int valueIndex = cursor.getColumnIndex(CalcContent.Content.VALUE);

String str = " ";
do{
str += cursor.getString(noteIndex)+" -> "+cursor.getDouble(valueIndex)+"\n";
}while(cursor.moveToNext());

view.setText(str);
}
else{
view.setText("Data Base is empty mate!!");
}


}



}



There are heaps of thing to learn about Activities and their life cycle which I'm gonna get into them soon in my next application...but before that i will be going over Activity class Documentation again and again ;)

The last thing that we'll need to complete our application is Android Manifest file :


<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.amir.calculator">

<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="false" />


<application android:icon="@drawable/icon" android:label="@string/app_name">



<provider android:name="CalcProvider"
android:authorities="com.amir.calculator.CalcContent"
/>


<activity android:name="MainActivity"
android:label="@string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity android:name="SaveActivity"
android:label="@string/save"
android:theme="@android:style/Theme.Dialog">
<intent-filter>
<action android:name="com.amir.calculator.SAVE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>


<activity android:name="ShowActivity"
android:label="@string/show"
android:theme="@android:style/Theme.Dialog">
<intent-filter>
<action android:name="com.amir.calculator.SHOW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>


</application>
<uses-sdk android:minSdkVersion="5" />

</manifest>

No comments: