Making Tip Calculator for Window Phone 7
Tip calculator is the one of the most useful tool/app for mobile devices.
The so-called business logic is very simple and is not very different among various versions of Tip Calcs out there. Yet, what I would like to show is my way of Metro UX which I do belive is still a part of family.
Entry animation – first user expirience.
<Storyboard x:Name="mainInAnimation"> <DoubleAnimation Storyboard.TargetName="ContentPanel" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Duration="0:0:1" To="-20" > <DoubleAnimation.EasingFunction> <ExponentialEase EasingMode="EaseOut" /> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation Storyboard.TargetName="TitlePanel" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)" Duration="0:0:1" To="-20" > <DoubleAnimation.EasingFunction> <ExponentialEase EasingMode="EaseOut" /> </DoubleAnimation.EasingFunction> </DoubleAnimation> <DoubleAnimation Storyboard.TargetName="ContentPanel" Storyboard.TargetProperty="Opacity" Duration="0:0:1.5" To="1"> <DoubleAnimation.EasingFunction> <QuadraticEase EasingMode="EaseOut" /> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard>
It gives a nice slide animation at start-up and opacity change. I used easing fuctions to give it more natural look.
Poping Textbox.
<Storyboard x:Name="translateAmountAnimation" > <DoubleAnimation Storyboard.TargetName="translateAmount" Storyboard.TargetProperty="Y" To="-3" AutoReverse="True" Duration="0:0:0.2"> <DoubleAnimation.EasingFunction> <ExponentialEase EasingMode="EaseOut" /> </DoubleAnimation.EasingFunction> </DoubleAnimation> </Storyboard>
When Textboxes are pressed, they move up and down.
Styling.
I have made a few changes to the default style.
- opacity of TexBox is 0.7
- different margins (careful with that and bear in mind the rule of thumb – 0.9mm)
- aligment
- theme aware styles (like PhoneTextLargeStyle)
That is all about XAML, now C#.
/// <summary> /// Constructor /// </summary> public MainPage() { InitializeComponent(); this.LayoutUpdated += new EventHandler(MainPage_LayoutUpdated); }
The ctor is kept light-weight for faster start of app and all the details are handled by MainPage_LayoutUpdated event handler.
private void MainPage_LayoutUpdated(object sender, EventArgs e) { if (m_onNavigatedToCalled) { m_onNavigatedToCalled = false; Dispatcher.BeginInvoke(() => { Random random = new Random(); var number = random.Next(1, 3); string fileName = String.Format(@"Images\background{0}.jpg", number); backgroundBrush.ImageSource = new BitmapImage(new Uri(fileName, UriKind.Relative)); radioButton3.IsChecked = true; mainInAnimation.Begin(); }); } }
Since we need to prepare things when everything is loaded MainPage_LayoutUpdated is a proper event but it is called everytime when layout has been updated, hence m_onNavigatedToCalled bool is init with true value and after first call of event it is set to false.
Dispatcher.BeginInvoke is a thread-safe asynchronous method for UI changes (mainly). In lambda expresion the random background is picked and animation begins (I prefer do it in code).
Orientation.
private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e) { if ((e.Orientation & PageOrientation.Portrait) == PageOrientation.Portrait) { Grid.SetRow(bottom, 1); Grid.SetColumn(bottom, 0); sumStackPanel.Margin = new Thickness(35, 30, 0, 0); } else { Grid.SetRow(bottom, 0); Grid.SetColumn(bottom, 1); sumStackPanel.Margin = new Thickness(-5, 30, 0, 0); } }
To keep UI concise I have divided main Grid into 2 kolumns and 2 rows. After OrientationChanged event occurs bottom grid is set to next column. For the orientation changes the Hybrid animaion do a nice job.
That is all interesting things about code. Here you can download the soultion link OR http://tipcalc.codeplex.com/
You can download Tip Calc for free form Zune marketplace! enjoy!
And here is a demo. (animations are a bit choppy because of emulator + recording software) 😉
All feedbacks and comments are welcome.