Tuesday 25 March 2014

Calculator demo

 You can download demo from : "http://www.codeproject.com/Articles/104931/Introduction-to-Android-development-TouchCalculato"

OR
==
1)Create java file KeypadAdapter.java
==========================
package com.pragmatouch.calculator;

import android.widget.*;
import android.content.*;
import android.view.*;
import android.view.View.OnClickListener;

public class KeypadAdapter extends BaseAdapter {
private Context mContext;

// Declare button click listener variable
private OnClickListener mOnButtonClick;

public KeypadAdapter(Context c) {
mContext = c;
}

// Method to set button click listener variable
public void setOnButtonClickListener(OnClickListener listener) {
mOnButtonClick = listener;
}

public int getCount() {
return mButtons.length;
}

public Object getItem(int position) {
return mButtons[position];
}

public long getItemId(int position) {
return 0;
}

// create a new ButtonView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
Button btn;
if (convertView == null) { // if it's not recycled, initialize some
// attributes

btn = new Button(mContext);
KeypadButton keypadButton = mButtons[position];

switch(keypadButton.mCategory)
{
case MEMORYBUFFER:
btn.setBackgroundResource(R.drawable.keypadmembuffer1);
break;
case CLEAR:
btn.setBackgroundResource(R.drawable.keypadclear1);
break;
case NUMBER:
btn.setBackgroundResource(R.drawable.keypad1);
break;
case OPERATOR:

btn.setBackgroundResource(R.drawable.keypadop1);
break;
case OTHER:
btn.setBackgroundResource(R.drawable.keypadother1);
break;
case RESULT:
btn.setBackgroundResource(R.drawable.keypadresult1);
break;
case DUMMY:
btn.setBackgroundResource(R.drawable.appvertical1);
break;
default:
btn.setBackgroundResource(R.drawable.keypad1);
break;
}
// Set OnClickListener of the button to mOnButtonClick
if(keypadButton != KeypadButton.DUMMY)
btn.setOnClickListener(mOnButtonClick);
else
btn.setClickable(false);
// Set CalculatorButton enumeration as tag of the button so that we
// will use this information from our main view to identify what to do
btn.setTag(keypadButton);
} else {
btn = (Button) convertView;
}

btn.setText(mButtons[position].getText());
return btn;
}

// Create and populate keypad buttons array with CalculatorButton enum
// values
private KeypadButton[] mButtons = { KeypadButton.MC, KeypadButton.MR,KeypadButton.MS, KeypadButton.M_ADD, KeypadButton.M_REMOVE,
KeypadButton.BACKSPACE, KeypadButton.CE, KeypadButton.C,KeypadButton.SIGN, KeypadButton.SQRT,
KeypadButton.SEVEN,KeypadButton.EIGHT, KeypadButton.NINE, KeypadButton.DIV,KeypadButton.PERCENT,
KeypadButton.FOUR, KeypadButton.FIVE,KeypadButton.SIX, KeypadButton.MULTIPLY, KeypadButton.RECIPROC,
KeypadButton.ONE, KeypadButton.TWO, KeypadButton.THREE,KeypadButton.MINUS, KeypadButton.DECIMAL_SEP,
KeypadButton.DUMMY, KeypadButton.ZERO,KeypadButton.DUMMY,KeypadButton.PLUS, KeypadButton.CALCULATE };

}
2)KeypadButton.java
===============
package com.pragmatouch.calculator;

public enum KeypadButton {
MC("MC",KeypadButtonCategory.MEMORYBUFFER)
, MR("MR",KeypadButtonCategory.MEMORYBUFFER)
, MS("MS",KeypadButtonCategory.MEMORYBUFFER)
, M_ADD("M+",KeypadButtonCategory.MEMORYBUFFER)
, M_REMOVE("M-",KeypadButtonCategory.MEMORYBUFFER)
, BACKSPACE("<-",KeypadButtonCategory.CLEAR)
, CE("CE",KeypadButtonCategory.CLEAR)
, C("C",KeypadButtonCategory.CLEAR)
, ZERO("0",KeypadButtonCategory.NUMBER)
, ONE("1",KeypadButtonCategory.NUMBER)
, TWO("2",KeypadButtonCategory.NUMBER)
, THREE("3",KeypadButtonCategory.NUMBER)
, FOUR("4",KeypadButtonCategory.NUMBER)
, FIVE("5",KeypadButtonCategory.NUMBER)
, SIX("6",KeypadButtonCategory.NUMBER)
, SEVEN("7",KeypadButtonCategory.NUMBER)
, EIGHT("8",KeypadButtonCategory.NUMBER)
, NINE("9",KeypadButtonCategory.NUMBER)
, PLUS(" + ",KeypadButtonCategory.OPERATOR)
, MINUS(" - ",KeypadButtonCategory.OPERATOR)
, MULTIPLY(" * ",KeypadButtonCategory.OPERATOR)
, DIV(" / ",KeypadButtonCategory.OPERATOR)
, RECIPROC("1/x",KeypadButtonCategory.OTHER)
, DECIMAL_SEP(",",KeypadButtonCategory.OTHER)
, SIGN("±",KeypadButtonCategory.OTHER)
, SQRT("SQRT",KeypadButtonCategory.OTHER)
, PERCENT("%",KeypadButtonCategory.OTHER)
, CALCULATE("=",KeypadButtonCategory.RESULT)
, DUMMY("",KeypadButtonCategory.DUMMY);

CharSequence mText; // Display Text
KeypadButtonCategory mCategory;
KeypadButton(CharSequence text,KeypadButtonCategory category) {
mText = text;
mCategory = category;
}

public CharSequence getText() {
return mText;
}
}
3)Create java file KeypadButtonCategory.java
================================
package com.pragmatouch.calculator;

public enum KeypadButtonCategory {
MEMORYBUFFER
, NUMBER
, OPERATOR
, DUMMY
, CLEAR
, RESULT
, OTHER
}
4) create java file main.java
==================
package com.pragmatouch.calculator;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Iterator;
import java.util.Stack;

import android.app.Activity;
import android.os.Bundle;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.view.View;
import android.view.View.OnClickListener;

public class main extends Activity {
GridView mKeypadGrid;
TextView userInputText;
TextView memoryStatText;

Stack<String> mInputStack;
Stack<String> mOperationStack;

KeypadAdapter mKeypadAdapter;
TextView mStackText;
boolean resetInput = false;
boolean hasFinalResult = false;

String mDecimalSeperator;
double memoryValue = Double.NaN;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

DecimalFormat currencyFormatter = (DecimalFormat) NumberFormat
.getInstance();
char decimalSeperator = currencyFormatter.getDecimalFormatSymbols()
.getDecimalSeparator();
mDecimalSeperator = Character.toString(decimalSeperator);
setContentView(R.layout.main);

// Create the stack
mInputStack = new Stack<String>();
mOperationStack = new Stack<String>();
// Get reference to the keypad button GridView
mKeypadGrid = (GridView) findViewById(R.id.grdButtons);
// Get reference to the user input TextView
userInputText = (TextView) findViewById(R.id.txtInput);
userInputText.setText("0");
memoryStatText = (TextView) findViewById(R.id.txtMemory);
memoryStatText.setText("");
mStackText = (TextView) findViewById(R.id.txtStack);
// Create Keypad Adapter
mKeypadAdapter = new KeypadAdapter(this);
// Set adapter of the keypad grid
mKeypadGrid.setAdapter(mKeypadAdapter);
// Set button click listener of the keypad adapter
mKeypadAdapter.setOnButtonClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Button btn = (Button) v;
// Get the KeypadButton value which is used to identify the
// keypad button from the Button's tag
KeypadButton keypadButton = (KeypadButton) btn.getTag();

// Process keypad button
ProcessKeypadInput(keypadButton);
}
});

mKeypadGrid.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {

}
});

}

private void ProcessKeypadInput(KeypadButton keypadButton) {
//Toast.makeText(this, keypadButton.getText(), Toast.LENGTH_SHORT).show();
String text = keypadButton.getText().toString();
String currentInput = userInputText.getText().toString();

int currentInputLen = currentInput.length();
String evalResult = null;
double userInputValue = Double.NaN;

switch (keypadButton) {
case BACKSPACE: // Handle backspace
// If has operand skip backspace
if (resetInput)
return;

int endIndex = currentInputLen - 1;

// There is one character at input so reset input to 0
if (endIndex < 1) {
userInputText.setText("0");
}
// Trim last character of the input text
else {
userInputText.setText(currentInput.subSequence(0, endIndex));
}
break;
case SIGN: // Handle -/+ sign
// input has text and is different than initial value 0
if (currentInputLen > 0 && currentInput != "0") {
// Already has (-) sign. Remove that sign
if (currentInput.charAt(0) == '-') {
userInputText.setText(currentInput.subSequence(1,
currentInputLen));
}
// Prepend (-) sign
else {
userInputText.setText("-" + currentInput.toString());
}
}
break;
case CE: // Handle clear input
userInputText.setText("0");
break;
case C: // Handle clear input and stack
userInputText.setText("0");
clearStacks();
break;
case DECIMAL_SEP: // Handle decimal seperator
if (hasFinalResult || resetInput) {
userInputText.setText("0" + mDecimalSeperator);
hasFinalResult = false;
resetInput = false;
} else if (currentInput.contains("."))
return;
else
userInputText.append(mDecimalSeperator);
break;
case DIV:
case PLUS:
case MINUS:
case MULTIPLY:
if (resetInput) {
mInputStack.pop();
mOperationStack.pop();
} else {
if (currentInput.charAt(0) == '-') {
mInputStack.add("(" + currentInput + ")");
} else {
mInputStack.add(currentInput);
}
mOperationStack.add(currentInput);
}

mInputStack.add(text);
mOperationStack.add(text);

dumpInputStack();
evalResult = evaluateResult(false);
if (evalResult != null)
userInputText.setText(evalResult);

resetInput = true;
break;
case CALCULATE:
if (mOperationStack.size() == 0)
break;

mOperationStack.add(currentInput);
evalResult = evaluateResult(true);
if (evalResult != null) {
clearStacks();
userInputText.setText(evalResult);
resetInput = false;
hasFinalResult = true;
}
break;
case M_ADD: // Add user input value to memory buffer
userInputValue = tryParseUserInput();
if (Double.isNaN(userInputValue))
return;
if (Double.isNaN(memoryValue))
memoryValue = 0;
memoryValue += userInputValue;
displayMemoryStat();

hasFinalResult = true;

break;
case M_REMOVE: // Subtract user input value to memory buffer
userInputValue = tryParseUserInput();
if (Double.isNaN(userInputValue))
return;
if (Double.isNaN(memoryValue))
memoryValue = 0;
memoryValue -= userInputValue;
displayMemoryStat();
hasFinalResult = true;
break;
case MC: // Reset memory buffer to 0
memoryValue = Double.NaN;
displayMemoryStat();
break;
case MR: // Read memoryBuffer value
if (Double.isNaN(memoryValue))
return;
userInputText.setText(doubleToString(memoryValue));
displayMemoryStat();
break;
case MS: // Set memoryBuffer value to user input
userInputValue = tryParseUserInput();
if (Double.isNaN(userInputValue))
return;
memoryValue = userInputValue;
displayMemoryStat();
hasFinalResult = true;
break;
default:
if (Character.isDigit(text.charAt(0))) {
if (currentInput.equals("0") || resetInput || hasFinalResult) {
userInputText.setText(text);
resetInput = false;
hasFinalResult = false;
} else {
userInputText.append(text);
resetInput = false;
}
}
break;
}
}

private void clearStacks() {
mInputStack.clear();
mOperationStack.clear();
mStackText.setText("");
}

private void dumpInputStack() {
Iterator<String> it = mInputStack.iterator();
StringBuilder sb = new StringBuilder();
while (it.hasNext()) {
CharSequence iValue = it.next();
sb.append(iValue);
}
mStackText.setText(sb.toString());
}

private String evaluateResult(boolean requestedByUser) {
if ((!requestedByUser && mOperationStack.size() != 4)
|| (requestedByUser && mOperationStack.size() != 3))
return null;

String left = mOperationStack.get(0);
String operator = mOperationStack.get(1);
String right = mOperationStack.get(2);
String tmp = null;
if (!requestedByUser)
tmp = mOperationStack.get(3);

double leftVal = Double.parseDouble(left.toString());
double rightVal = Double.parseDouble(right.toString());
double result = Double.NaN;

if (operator.equals(KeypadButton.DIV.getText())) {
result = leftVal / rightVal;
} else if (operator.equals(KeypadButton.MULTIPLY.getText())) {
result = leftVal * rightVal;
} else if (operator.equals(KeypadButton.PLUS.getText())) {
result = leftVal + rightVal;
} else if (operator.equals(KeypadButton.MINUS.getText())) {
result = leftVal - rightVal;
}

String resultStr = doubleToString(result);
if (resultStr == null)
return null;

mOperationStack.clear();
if (!requestedByUser) {
mOperationStack.add(resultStr);
mOperationStack.add(tmp);
}

return resultStr;
}

private String doubleToString(double value) {
if (Double.isNaN(value))
return null;

long longVal = (long) value;
if (longVal == value)
return Long.toString(longVal);
else
return Double.toString(value);
}

private double tryParseUserInput() {
String inputStr = userInputText.getText().toString();
double result = Double.NaN;
try {
result = Double.parseDouble(inputStr);

} catch (NumberFormatException nfe) {
}
return result;
}

private void displayMemoryStat() {
if (Double.isNaN(memoryValue)) {
memoryStatText.setText("");
} else {
memoryStatText.setText("M = " + doubleToString(memoryValue));
}
}
}

5)main.xml
========
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@drawable/appvertical1" >

<TextView  
   android:id="@+id/txtStack"
   android:layout_width="fill_parent" 
   android:layout_height="wrap_content" 
  android:textSize="15sp"
   android:gravity="right"
   android:background="@drawable/stackview1"
   android:layout_marginTop = "3sp"
   android:layout_marginLeft = "5sp"
   android:layout_marginRight = "5sp"
    android:textColor="@color/darkgrey"/>
    <TextView  
    android:id="@+id/txtInput"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textSize="25sp"
    android:gravity="right"
    android:background="@drawable/inputview1"
    android:textColor="@color/darkgreen"
    android:layout_marginLeft = "5sp"
    android:layout_marginRight = "5sp"/>


    <TextView  
    android:id="@+id/txtMemory"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:textSize="15sp"
    android:textColor="@color/lightyellow"
    android:gravity="left"
        android:layout_marginLeft = "5sp"
    android:layout_marginRight = "5sp"/>
<GridView 
    android:id="@+id/grdButtons"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent"
    android:columnWidth="90dp"
    android:numColumns="5"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"/>

</LinearLayout>
6)manifest.xml
==========
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.pragmatouch.calculator"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".main"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="8" />
</manifest> 

No comments:

Post a Comment