After my recent posts I received a question asking for tips on porting a MonoTouch app to MonoDroid. I'm going to take a crack at that over a couple of days - with the warning that you probably shouldn't rush out and buy either tool but wait for Xamarin's future Mono-on-iOS and Mono-on-Android products.
The purpose of the original "M"osetta Stone post was to give cross-platform developers a 'head start' with some high-level concepts. This post will look a little closer at a screen from the Monospace11 app: the Speakers list.
This may be a massive oversimplification, but...
|if you have|
___ in iOS
|then you want|
___ in Android
|UIViewController||Activity||subclass to present a screen/form/page to the user|
|ViewDidLoad()||OnCreate()||setup the UI|
|Add() or AddSubview()||SetContentView()||use in ViewDidLoad/OnCreate to 'attach' UI to display|
|ViewWillAppear()||OnResume()||load/re-load data that might change and bind to UI|
|UITableView||ListView||visual control that presents a scrolling list|
|UITableViewSource||Adapter||subclass to broker the display of a data collection to the UI|
|GetCell()||GetView()||to build the layout(UI) for each cell/row, including re-using cells/views for performance|
|RowSelected()||ItemClick EventHandler||perform an action when a row is touched|
|RowsInSection||Count||tell the table/list how many rows to cater for|
Here's how it looks in a Visual Studio Class Diagram*
UITableViewSourcehas been implemented as an nested class to resemble the iOS pattern of implementing the equivalent Obj-C protocols on the ViewController - this pattern makes no sense in Android so the classes are separate.
- The MonoTouch example code builds the UI in C# (eg.
tableView=new UITableView();AddSubview (tableView);) whereas MonoDroid loads layout XML files
SetContentView(Resource.Layout.Speakers);. This can happen in both
GetCell/GetViewwhere UI controls must be created and presented to the user.
- The 'touch event handler' is in a different class: in MonoTouch the
TableViewSourcehandles a touch for a specific row (
NSIndexPath); MonoDroid implements the
ItemClick EventHandler<ItemEventArgs>on the
ListViewfor a given
- Both examples use the constructor (
TableViewSource/SpeakersAdapter) of the 'broker' class to pass the actual business object collection for display. This pattern lets the data be filtered/sorted/whatever before being passed in for display.
ViewDidLoad/OnResumeis kinda redundant in this example since the list never changes - but in other spots (eg the Favorites screen) you would want to refresh the list each time because it may have changed.
You can have a look at the MonoTouch code SpeakersViewController.cs and the MonoDroid SpeakersActivity.cs, SpeakersAdapter.cs to see the actual implementation. For MonoDroid you'll also need to check out the layout XML files Speakers.axml and SpeakersItem.axml.
One more thing...
One final piece which takes some getting used to... in MonoTouch this screen is part of a
UINavigationControllerstack and your
RowSelectedcreates a new ViewController object (passing whatever parameters you need) and calls
NavigationController.PushViewController(). The ViewController instances in the navigation stack are 'stateful' and it is really easy to pass business objects around as parameters.
In MonoDroid, the ever-present 'back-stack' does not require a specific 'navigation controller' BUT at it's simplest the mechanism is much more primative and involves passing simple type parameters (eg. strings) like this
var intent = new Intent();
There are more sophisticated approaches but it is probably best to keep your parameter-passing to a minimum - this way the Android hardware 'Back' button "just works".
HTH Slava ;-)