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:
- Number inputs (from 0-9)
- Dot (decimal point)
- Basic Operators input (+, -, *, /, =)
- 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="<" 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>
..
Hi Andy,
Great MVVM and Adroid! I am also a C# (Silverlight, WP7) Developer. But I have to develop my WP7 city guide now forAndroit. The Adapter idea looks not really nice for me. 😉
I love MVVM. Please do not stop do develop your project. I need it.
Many Thanks and regards
From Switzerland
Peter
How can I bind a image?
Image is not visible.
public class CityTourEntry {
public String CityTourEntryName;
public String Id;
public String CityId;
public String Location;
public int ImageNumber;
public int ImageSource;
public CityTourEntry (String cityTourEntry)
{
CityTourEntryName = cityTourEntry;
}
public CityTourEntry (String cityTourEntry, String id, Context context)
{
CityTourEntryName = cityTourEntry;
Id = id;
ImageSource = 0x7f020000;
}
}
****************************************************
OK this looks a bit better.
public CityTourEntry (String cityTourEntry, String id, Context context)
{
CityTourEntryName = cityTourEntry;
Id = id;
ImageSource = context.getResources().getDrawable(R.drawable.c_l_1010162000);
}
Bun again notvisible ???
What’s the data type of ImageSource?
JPG File
I mean, it seems that you declare ImageSource as a Drawable, right?
A drawable cannot directly bind to the view (unless you use the POJO extension), better I recommend you to use the Observable pattern, simply define your ImageSource as:
public final Observable ImageSource = new Observable(Drawable.class);
// and later in setting the source:
ImageSource.set(context.getResources().....);
In order to get the View notified, it is required that all data provided to view to be Observables.
Thanks for all your responses. It is working now.
Regards
Peter
Welcome 🙂
Did you join the discussion group in Google Group: http://groups.google.com/group/androidbinding
Discussion would best be done on that platform, and comments from users would help a lot in pushing the development and improvements.
How can I implement other math functions such as sin, cos, tan, and so on?
Also, I found your calculator demo didn’t go with android,binding.0.3.jar as well as android.building.0.4.jar. It works only with 0.15 and 0.22.
Thanks a lot.
Oh. Sorry haven’t updated the calculator for quite a while. Latest version on market, and tutorial and source code is coming soon. Stay tuned for later series 😛
The 0.4a is not compatible is because of two major changes made after v0.2:
1. Change of the namespace – the namespace is changed to gueei.binding instead of com.gueei.android.binding, the later one is too verbose;
2. Command is not an interface anymore, it’s now a Abstract class.