xamarin 9/10 san diego meetup
TRANSCRIPT
Cross-Platform Mobile Developmentthat Works.
Rob DeRosaEnterprise Customer Success Engineer,Key Accounts
xamarin.com/testcloud
✓ Automated UI testing✓ Thousands of real devices✓ Integration with CI systems✓ Test any mobile app✓ Find bugs before your
customers do
✓ Live, instructor lead courses✓ Developer Certification✓ Guest lectures✓ Office Hours✓ Lightning talks✓ Latest topics
xamarin.com/university
Shared C# codebase • 100% native API access • High performance
iOS C# UI Windows C# UIAndroid C# UI
Shared C# Mobile C# Server
Linux/MonoCoreCLRAzure
Shared C# Client/Server
MapKit UIKit iBeacon CoreGraphics CoreMotion
System.Data System.Windows System.Numerics System.Core System.ServiceModel
System.Net System System.IO System.Linq System.Xml
Text-to-speech ActionBar Printing Framework Renderscript NFC
System.Data System.Windows System.Numerics System.Core System.ServiceModel
System.Net System System.IO System.Linq System.Xml
Microsoft.Phone Microsoft.Networking Windows.Storage Windows.Foundation Microsoft.Devices
System.Data System.Windows System.Numerics System.Core System.ServiceModel
System.Net System System.IO System.Linq System.Xml
Traditional Xamarin Approach With Xamarin.Forms:Share UI code, all native
iOS C# UI Windows C# UIAndroid C# UI
Shared C# Business Logic
Shared UI Code
Shared C# Business Logic
✓ 40+ Pages, layouts, and controls(Build with C# or XAML)
✓ Two-way data binding✓ Navigation✓ Animation API✓ Dependency Service✓ Messaging Center✓ Styles, Converters, Behaviors
Shared C# Business Logic
Shared UI Code
<?xml version="1.0" encoding="UTF-‐8"?><TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"x:Class="MyApp.MainPage"><TabbedPage.Children><ContentPage Title="Profile" Icon="Profile.png">
<StackLayout Spacing="20" Padding="20” VerticalOptions="Center"><Entry Placeholder="Username“ Text="{Binding Username}"/><Entry Placeholder="Password” Text="{Binding Password}"
IsPassword="true"/><Button Text="Login" TextColor="White” BackgroundColor="#77D065"
Command="{Binding LoginCommand}"/></StackLayout>
</ContentPage><ContentPage Title="Settings" Icon="Settings.png">
<!-‐-‐ Settings -‐-‐></ContentPage></TabbedPage.Children></TabbedPage>
Layouts
Pages
Stack Absolute Relative Grid ContentView ScrollView Frame
Content MasterDetail Navigation Tabbed Carousel
ActivityIndicator BoxView Button DatePicker Editor
Entry Image Label ListView Map
OpenGLView Picker ProgressBar SearchBar Slider
Stepper TableView TimePicker WebView EntryCell
ImageCell SwitchCell TextCell ViewCell
Sport
Development goals:
• Provide a way for colleagues to challenge and rank up
• Gain a deeper understanding of Forms – capabilities/limitations
• Learn Azure Mobile Services (WebAPI, EF, push)
Application Design Goals
• Simplified registration/authentication
• Athlete’s can join multiple leagues
• View current rank within ladder
• Athlete stats & challenge history
• Facilitate challenge flow (accept, nudge, post results)
Topics we’ll cover
• Dead-simple authentication with SimpleAuth• Absolutely awesome AbsoluteLayout• Creating & consuming providers (Toast, HUD)• Creating & consuming custom controls• Tricks – ImageButton, styled DateTime picker• Animations and Parallax• Insights & UITest
Front end - Xamarin.Forms
• XAML• Bindings• Converters• Styles
• Reusable Controls• Custom Renderers• Messaging Center• Dependency Service
Back end – Azure Mobile
• WebAPI – REST/JSON• Entity Framework w/
SQL Database• Cross-templated push
notifications• Notification hubs• Tag-based
Absolute Layout
• Used to control size and position of child elements• LayoutBounds is based on LayoutFlags value
• SizeProportional, PositionProportional, All
• Element’s LayoutBounds are proportional to the AbsoluteLayout’s bounds
• The x and y anchor points are interpolated as the child elements position changes
SimpleAuth
• SimpleAuth – stupid simple• github.com/clancey/simpleauth
var scopes = new[] {"https://www.googleapis.com/auth/userinfo.email","https://www.googleapis.com/auth/userinfo.profile"
};var api = new GoogleApi("google", "clientid", "clientsecret") {
Scopes = scopes,};
var account = await api.Authenticate();
Providers• Use an interface to define intent
• Implement on each platform
• Use the Dependency Service to get a platform-specific
implementation at runtime
• Smaller utilities can use the same namespace/class without
the need for an interface
ToastNotifier Providerpublic interface IToastNotifier{
Task<bool> Notify(ToastNotificationType type, string title, string description,TimeSpan duration, object context = null);void HideAll();
}defin
e
[assembly: Dependency(typeof(Sport.Android.ToastNotifier))]...public class ToastNotifier : IToastNotifier{
public Task<bool> Notify(ToastNotificationType type, string title, string description,TimeSpan duration, object context = null)
{var taskCompletionSource = new TaskCompletionSource<bool>();Toast.MakeText(Forms.Context, description, ToastLength.Short).Show();return taskCompletionSource.Task;
}
public void HideAll(){}
}
impl
emen
t
var toaster = DependencyService.Get<IToastNotifier>();toaster.Notify(type, title ?? type.ToString().ToUpper(), message, TimeSpan.FromSeconds(2.5f));use
Custom, Reusable Controls
• Equivalent to a WPF/ASP.NET User Control
• Use Bindable Properties to allow consumers to bind values
• Templated controls can allow for inner content
• Subclass ContentView
Little Tricks• Use layers for precise layout - position and size
• Use opacity on controls to handle a user event• Examples
• ImageButton
• Styled Date and Time pickers• Use VectorImages instead of bitmaps
• Reduce application footprint by including a single .svg file
• Control tint color and size dynamically• Use an IsBusy flag to trigger progress
• Use a Busy : IDisposable to ensure flag always gets set to false
• Use static converters – less code, fewer objects• Run tasks safely using a proxy task-runner
Let’s check out some code!
Vector Image
• Control size and tint color dynamically• Reduce footprint by resourcing a single .svg file
Animations
• Super easy to use
• Basic animations are supported• Scale• Translate• Fade• Rotate
• Easing (Bounce, Cubic, Linear, Sin)
Animationsvar speed = (uint)App.AnimationSpeed;var ease = Easing.SinIn;
var pushRect = new Rectangle(Content.Width, btnPush.Bounds.Y, btnPush.Bounds.Width, btnPush.Height);btnPush.FadeTo(0, speed, ease);await btnPush.LayoutTo(pushRect, speed, ease);
var contRect = new Rectangle(Content.Width, btnCont.Bounds.Y, btnCont.Bounds.Width, btnCont.Height);btnCont.FadeTo(0, speed, ease);await btnCont.LayoutTo(contRect, speed, ease);
Parallax Effectvoid Parallax(){
if(_imageHeight <= 0)_imageHeight = photoImage.Height;
var y = scrollView.ScrollY * .4;if(y >= 0){
//Move the Image's Y coordinate a fraction//of the ScrollView's Y positionphotoImage.Scale = 1;photoImage.TranslationY = y;
}else{
//Calculate a scale that equalizes the height vs scrolldouble newHeight = _imageHeight + (scrollView.ScrollY * -1);photoImage.Scale = newHeight / _imageHeight;photoImage.TranslationY = scrollView.ScrollY / 2;
}}
Insights & UITest
• Add custom events or implement at a base level
• Use StyleID to store the element identifier• Share UITest code between iOS and Android