Windows Phone From Scratch #43
This is the first in a series of mini-tutorials and related content on moving applications from Android to Windows Phone.
To get us started, let’s take a look at a simple Android application that takes an amount and computes the total with an 18% tip. We’ll then rebuild it in Windows Phone.
I began the Android application by opening Eclipse, which is set up with the Android SDK and AVD Manager. To create the layout I opened the res (resources) /layout/main.xml file and had the choice of either using the Graphical Layout view or the xml view. In this case I chose the xml view and started with a LinearLayout into which I put a TextView an EditView, a Button and a final TextView:
<?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" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Android Tip Calculator" /> <EditText android:id="@+id/mealprice" android:layout_width="fill_parent" android:layout_height="wrap_content" android:autoText="true" /> <Button android:id="@+id/calculate" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Calculate Tip" /> <TextView android:id="@+id/message" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" /> </LinearLayout>
Each control that I want to refer to from code has an @+id identifier. The code itself is in the src/tipcalculator.jesseliberty.com/TipCalculator.java file. As is usual, the source file begins with the package name, and a series of import statements,
package tipcalculator.jesseliberty.com; import java.text.NumberFormat; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView;
The Activity that does all the computational work is called TipCalculator. In that class I override the OnCreate method, and set the content view to main. I then create local variables to represent the three named fields from main.xml,
public class TipCalculator extends Activity { public static final String tag = "Tip Calculator"; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); final EditText mealpricefield = (EditText) findViewById(R.id.mealprice); final TextView messagefield = (TextView) findViewById(R.id.message); final Button calculateButton = (Button) findViewById(R.id.calculate);
I’m now ready to set up the listener for the click event on the button. The first step is to extract the text from the mealpricefield text box and to turn that value into a float:
public void onClick(View v) { try { String mealprice = mealpricefield.getText().toString(); String message = ""; if (mealprice.indexOf("$") == -1) { mealprice = "$" + mealprice; } float mealPriceAsFloat = 0.0F; NumberFormat nf = java.text.NumberFormat.getCurrencyInstance(); mealPriceAsFloat = nf.parse(mealprice).floatValue();
We can now add 18% to the cost of the meal and display the final result in the messagefield,
mealPriceAsFloat = nf.parse(mealprice).floatValue(); mealPriceAsFloat *= 1.18; message = "Pay: " + nf.format(mealPriceAsFloat); messagefield.setText(message); } catch (java.text.ParseException pe) { messagefield.setText("Unable to understand amount"); } catch (Exception e) { e.printStackTrace(); messagefield.setText(e.getMessage()); } } });
Creating the Application in Windows Phone
Assuming you have downloaded and installed the Windows Phone development tools and are set up and ready to go, open a new application named TipCalculator. As with Android, you can create the UI using drag and drop from the toolbox or by writing the Xaml code directly. You can also create the UI in Expression Blend, which gives you an even more powerful UI drag and drop environment, but for now, we’ll mimic what we did above and write the Xaml.
To keep the look and feel consistent with what I have in the Android application, I’ll use TextBlocks, TextBoxes and Buttons to correspond to the TextView, EditText and Button controls respectively.
The layout is placed in MainPage.xaml.
Visual Studio sets up my page to fit the Metro look and feel, providing a bit of theming and a TitlePanel, so I’ll add a StackPanel to hold the content. A StackPanel lets me stack one object atop another, much as the LinearLayout was doing for me in the Android application.
<StackPanel Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <TextBlock HorizontalAlignment="Stretch" Text="Tip Calculator" /> <TextBox Name="mealprice" HorizontalAlignment="Stretch" /> <Button Name="Calculate" HorizontalAlignment="Center" Content="Calculate Tip" /> <TextBlock Name="Message" /> </StackPanel>
You’ll note that Intelllisense makes filling in these values very easy as shown in the figure.
Associated with MainPage.xaml is MainPage.xaml.cs, the so-called “code-behind” file that can be used to hold the logic associated with the controls in MainPage.
Any control declared in the Xaml in MainPage.xaml is automatically visible and in scope in the code-behind, and so there is no equivalent to the Android statements linking a local variable to the various controls (TextBlock, TextBox, etc.). That is, you can access properties on these controls directly in the code without needing to associate them with local variables.
The two steps to implementing this code are to associate a method with the Click Event, which we’ll do in the constructor, and then to implement that click event.
public MainPage( ) { InitializeComponent( ); Calculate.Click += new RoutedEventHandler( Calculate_Click ); }
The implementation can reach directly into the Text property of the TextBox and retrieve the value. We parse that as a float and then multiply, and finally we display the result in the Text property of the Message TextBlock,
private void Calculate_Click( object sender, RoutedEventArgs e ) { var mealPriceAsFloat = float.Parse( mealprice.Text ); mealPriceAsFloat *= 1.2F; Message.Text = "Pay $" + mealPriceAsFloat.ToString( ); }
I would be very interested in putting the two blocks of code in front of a random Java or C++ programmer and asking which was found simpler, more straight forward, easier to understand. There is no contest between the tools (Visual Studio is by far and indisputably the better environment) but I’m not 100% certain I’m in a position to objectively assess the ease of coding, maintenance, etc.
Wait, would the C# one deal with a dollar sign in the input box? If it does, I was not aware of this capability in float.Parse(). Other than that, and the already pointed out error handling that should be in both, this example is really nice.
Instead of removing error handling from the java example, how about adding it to the c# example — it is still valid to make sure your input can be parsed and float.Parse() will generate an exception if the string cannot be parsed as a float.
@Dave
You are right, I should strip that out of the Android example to compare apples to apples. The problem is that the java code insists on having the try block because the call to format expects it.
Unless i’m missing something – you’ve not included the exception handling in your C# example.
Do you really need to find yourself a random developer to compare the two? I think we can all see which is the cleaner code 😉
Nice tutorial, though some day I will teach you about margins in design! 🙂