This is the second tutorial about implementing MVVM pattern with Android Binding. Here we are going to build a simple calculator app.

This is part one of the series, and here is Part 2 of the series

Calculator app is simple to implement, but since it involves quite lots of buttons, the interaction (and user interface binding) could be quite complicated. By applying MVVM pattern, your code can be more focused and reduce spaghetti codes with binding to UI.

Source code available to download at: http://code.google.com/p/android-binding

You can also download the app from market to try out:
http://market.android.com/details?id=com.gueei.tutorials.calculator&feature=search_result

Design

We start by the screen shot of the end-product. It’s a very simple calculator, with all basic operations. So, in terms of functions, it would consists of:

  1. Number inputs (from 0-9)
  2. Dot (decimal point)
  3. Basic Operators input (+, -, *, /, =)
  4. Clear (AC), Backspace

The above describes the interface that User will interact with the system, with one output showing the calculated results.

The View Model Class

According to the previous described requirements, our View Model needs the following ‘Interface’:

public class CalculatorViewModel{
    // Display
    Observable display;

    // Commands: Serve as input from outside the model
    NumberCommand Number9;
    NumberCommand Number8;
    // other numbers from 0-7
    Command Dot;
    OperatorCommand Plus;
    OperatorCommand Minus;
    OperatorCommand Multiply;
    OperatorCommand Divide;
    OperatorCommand Equal;
...
}

for Number0 … Number9, they share almost the same logic, and also Operators, so additional two inner-classes are defined:

        private class NumberCommand implements Command{
		private int mNumber;
		public NumberCommand(int number){
			mNumber = number;
		}
		public void Invoke(View arg0, Object... arg1) {
			addNumber(mNumber);
		}
	}

	private class OperatorCommand implements Command{
		private final Operator mOperator;
		public OperatorCommand(Operator operator){
			mOperator = operator;
		}
		public void Invoke(View arg0, Object... arg1) {
			operate(mOperator);
		}
	}

The actual calculation logic is pretty simple and if you are interested, you may look at the source code to know about it.

The View

The view is an XML layout file, with custom ‘binding’ namespace attached to it.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:binding="http://www.gueei.com/android-binding/"
	android:orientation="vertical" android:layout_width="fill_parent"
	android:layout_height="fill_parent">
	<TextView android:layout_width="fill_parent"
		android:layout_height="fill_parent" android:textSize="45dip"
		android:gravity="right|bottom" binding:text="formattedDisplay"
		android:layout_weight="1"/>
	<TableLayout android:layout_width="fill_parent"
		android:layout_height="wrap_content" android:stretchColumns="0,1,2,3"
		>
		<TableRow>
			<Button android:text="/" binding:onClick="Divide" />
			<Button android:text="x" binding:onClick="Multiply" />
			<Button android:text="-" binding:onClick="Minus" />
			<Button android:text="+" binding:onClick="Plus" />
		</TableRow>
		<TableRow>
			<Button android:text="7" binding:onClick="Number7" />
			<Button android:text="8" binding:onClick="Number8" />
			<Button android:text="9" binding:onClick="Number9" />
			<Button android:text="&lt;" binding:onClick="Back" />
		</TableRow>
		<TableRow>
			<Button android:text="4" binding:onClick="Number4" />
			<Button android:text="5" binding:onClick="Number5" />
			<Button android:text="6" binding:onClick="Number6" />
			<Button android:text="AC" binding:onClick="AllClear" />
		</TableRow>
		<TableRow>
			<Button android:text="1" binding:onClick="Number1" />
			<Button android:text="2" binding:onClick="Number2" />
			<Button android:text="3" binding:onClick="Number3" />

		</TableRow>
		<TableRow>
			<Button android:text="0" binding:onClick="Number0"
				android:layout_span="2" />
			<Button android:text="." binding:onClick="Dot" />
			<Button android:text="=" binding:onClick="Equal" />
		</TableRow>
	</TableLayout>
</LinearLayout>

..