dot net conf 2020 xamarin メモ
サンプルコード github.com
Keynote : Xamarin All The Things
AndroidのProfiled AOT
Profiled AOTはStartup Speedが速く(AOTについで)でAPK SizeがAOTよりも小さい(Normalよりは大きい).
バランスがいい.
Type | Startup Speed | APK Size |
---|---|---|
Normal | 2s914ms | 16.1 MB |
AOT | 1s18ms | 34.6 MB |
Startup Tracing | 1s518ms | 20.1 MB |
Visual StudioでAndroidプロジェクトのProfileを開く.
左ペインからAndroid Options
タブを選択し,Enable Startup Tracing
という項目にチェックをつける.
試してみた.
- チェックなし.8.3MB.
- チェックあり.8.4MB.
Xamarin.Formsデモ
FlyMeアプリケーション.
All Things Xamarin.Forms Shell
Shellは
- アプリケーションの構造を宣言的に記述できる
- ナビゲーションをシンプルにする
- カスタマイズ性に優れる
- 作りたいアプリを素早く開発できる
Shellの見た目を設定する
細かく変更できる.
ドロワーメニューの見た目を設定する
DataTemplateをResourceDictionary内に定義して,それを使う.
StyleClass (Xamarin.Forms 4.6以降)
Shellに限らない.すべての要素に有効な機能.
HTML,CSSのclassのようにスタイルを適用できる. 複数適用できるのが特徴.
追記
ShellのFlyoutItemに関するスタイルの指定については以下のShell Fly-out Styling
の項目を参照する.
Tabの見た目を設定する
Shellのナビゲーション(遷移)
- 遷移先に名前をつける.
<Tab Title="Details" Route="Details"....
- どこからでも遷移できる
await Shell.Current.GoToAsync("//Details");
- ページとRoutingを登録しておける
Routing.RegisterRoute("ModalPage", typeof(ModalPage));
- Deep link ナビゲーション
await GoToAsync("//Details/ModalPage");
文字列でナビゲーションできる.
アプリから離脱しても,その時のURLを記録してさえ於けば,復帰も簡単.
モーダルページ
Shell.PresentationMode="Modal"
await Shell.Current.GoToAsync("ModalPage");
Search Handler
これ使いたいな.
BackButtonBehavior
TextOverrideで戻るボタンのテキストを変更できる IconOverrideで戻るボタンのアイコンを変更できる
Shellの特徴
ContentPage,MasterDetailPage,NavigationPage,TabbedPageをまとめてShellで置き換えることができる.
Shell.TitleViewでTitleBarのUIを作成できる.
Shellの今後
- 3rdパーティ製のMVVMサポート(Prism,FreshMVVM,RxUIなど)
- TitleViewの修正
- すべてをテンプレート化
- デュアルスクリーンをサポート
- パフォーマンスの向上
QA
GoToはAsyncだけれど,OnNavigatedなどはAsyncではない.
Spectacular Components for Xamarin Apps
MacOSもXamarin.Formsで?
- Expressive
- MVVM Atom
- HttpTracer
- AnyBind
- TinyInsights
- Shiny
Shinyの紹介
- Background Task
- Notification
Resizetizer
通常,様々なディスプレーサイズに合わせて,各画像ごとに複数のサイズを用意しなければならない.
このライブラリは画像を一つ用意しておけば,それらを自動的に生成してくれるもの?
Control Vender製のコントロールについて紹介
Communityによって提供されるコントロール
- Magic Gradients
- Color Picker Control
- XamAnimation
- Sheet Control
- Xamlly
- PancakeView
DebugRainbowsの紹介
開発のための機能がある - 各コントロールに色をつけて領域をわかりやすくする - 格子を表示して,コントロールの位置をわかりやすくできる <- Xamarin.Forms.DebugRainbowsだ.これ
PancakeViewの紹介
FrameやImage的なものの枠を三角形にしたり1つの角だけ丸めたり,色々できる.
SkiaSharp
SkiaSharpを使ったライブラリの紹介
- Balloony
- Magic Gradients
- Microchart
- Mapsui
- Aurora Highlights
- eliteKit
- Draw2D
Sharpnado
- CollectionViewのアイテムの入れ替えなどができる
Task Loaderとは?
Building Beautiful Apps with Xamarin.Forms
おしゃれなアプリとは?
- とても主観的なもの
- トレンドに左右される
- 無意識に
- 重要なものの不足を補えない
- すごい開発者がすごいデザイナとはいえない
なんで評判がよくない?
- シンプルなデータ入力アプリに向いているというマーケティングを行った
- 過去の経験
- 「Forms」という言葉の印象
おしゃれUIの要素
- グラデーション
- SkiaSharp
- MagicGradients
- PancakeView
- Built-in Xamarin Forms Gradients(そのうち)
- 影
- iOSでは好きなようにできる
- Androidでは制限がある
- フォント,アイコン
- Google Fonts
- FontAwesome などなど
- 色
- 色(の組み合わせなど)を生成するツールを使う
- 形
- 動き,アニメーション
- Micro Animation
- Lottie
- Xamarin.Forms built-in animation
- Xamanimation
- Page Transitions
- Xamarin.Plugin.SharedTransition
おしゃれさのためだけではない
Styleを使おう!
UIの再利用性を高めるためにStyleを使う.
Button,色,フォントなどなどを個別のファイルに分けてStyleを定義しておく.
練習の仕方
- オンラインで色々探してインスピレーションを得る
- 実際に試してみる
- 後はやるだけ
具体的には
- デザインをまとまりごとに分ける
- どのように構成したらいいかを考える
サンプル
github.com/sthewissen/FocusOnXamarin
GridでRowDefinition
作れなければ,それっぽく見せればいい
If you can't make it, fake it
おすすめのサイト,パッケージやフォントなどのリソース
Xamarin Productivity to the Max
Code Build Deploy Iterate この繰り返しを迅速に行うには.
- IntelliCode
Xamarin.Forms.Visual.Materialとは. iOSとAndroidで同じMaterialDesignな見た目に統一することができる.
完全ではない.
Testing Your Xamarin Apps
テストの階層は上から順に以下のとおり.
UI Test エンドユーザーの視点でのテスト.Viewに対して行う.
Automated Service Test Serviceが期待どおりに動作して,正しいデータを返すかをテストする.
Automated Unit Test 機能の動作を確認するためのテスト.ViewModelに対して行う.
FIRSTの原則
Fast テストは遅いものだけれども,遅くならないように書かなければならない.
Independent 他のテストを呼び出してはいけない.
Repeatable アクセストークンのような定数を使ってはいけない.MockサーバーやMockサービスを使う
Self-validating Assertsを使う
Timely 複雑にならないようにする.そのためにはアクションを複数のテストに分ける必要があるかもしれない.
Unitテストの基本的な構成
AAAパターン
で書く.
- Arrange
- Act
- Assert
テスト対象
public int MySum(int a, int b) { return a + b; }
テストコード
[Test] public void TestMySum() { //Arrange int a = 5; int b = 7; //Act int result = MySum(a, b); //Assert Assert.AreEqual(12,result); }
テスト条件を設定(Arrange)して,実行(Act)して,判定(Assert)する.
なぜテストをしなければならないのか
テストしよう
Mock(Moq)サービスを使ってインターフェースのインスタンスを作成する.
ViewModelを使っている場合,テストするときにBinding,JSON parsers,PluginsやXamarin.Formsの機能などXamarin開発チームによってテストされているものについては考える必要はない.
自分のコマンドやロジックをViewModel越しにテストする.
選択したテスティングフレームワークに従ってテストを書くこと.
IntelliTestが役に立つよ!
すべてにInterfaceを
アプリに様々なプラグインやパッケージをインストールするよね.Xamarin.Essentialsとか.
例えばXamarin.Essentialsを使うなら,IXamarinEssentialsを作ってプロパティとメソッドだけを公開すると,柔軟性が高くなる.
Unit Test Demo
UI Test
BDDアプローチ
Behavior Driven Development
技術的な言葉を使わずに誰もがわかる言葉でテストを記述する.(例えば,Gherkinのようなドメイン記述言語など)
例示を用いて議論を行うことを通じて,どのようなソフトウェアを作るのかについて共通の理解を構築するためのアプローチ.
例えば:
As a [Role] I want [Feature] So that [Benefit] Roleとして Benefitを得るために Featureがほしい
つまり,「誰が何のためにどんな機能がほしい」のかを明確にするということか.
これに従うと:
As a [Registered User] I want [to be able to login] so that [I can see the Application] Scenario 1: User is able to log in Given that I am a registered user, when I enter the username 'Codrina' and password 'ladybug', then I should see the first screen of the app.
UI Test Demo
UIテストをどうするか.
Going Reactive with Reactive Extensions & UI
ReactiveUIについて.
よく見るこのイベントハンドラ.
SearchBar.TextChanged += (sender, args) => { };
textChangedEvents .Throttle(TimeSpan.FromMilliseconds(750),RxApp.TaskpoolScheduler) .Select(x => x.NewTextValue.Trim()) .DistinctUntilChanged() .Where(x => !string.IsNullOrWhiteSpace(x)) .ObserveOn(RxApp.MainThreadScheduler) .InvokeCommand(this, x => x.ViewModel.Search) .DisposeWith(ViewBindings);
ロジックのすべてをコンストラクタにまとめることができる.
テキスト
github.com/kentcb
イベントを普通に使うのであれば役に立つよ.
All Things Xamarin.Forms Shell
Developing Performant Xamarin Apps
Improve Xamrin.Forms App Performance という動画があるのでチェックするように.
Performance Optimizations
- 起動時にすべてのServiceを開始/登録しないこと.可能な限りLazyロードする.
- montemagnoさんのTurnip TrackerでLazy使ってる.
- 起動時にすべてのデータをダウンロードしない.
- User Experienceについて考える
- Lottieつかったり
- iOS: Launch Storyboard
- Android: Splash Screen Activity
Androidの起動時について
- AOT with startup tracingを使う
- Custom Profiles with Startup Tracingを使う.
Async/Awaitのベストプラクティスを使う
- 同時に実行できるところで,処理を順次行わないようにする.
- すべてのTaskが完了することを不必要に待たないようにする
- ループの中で
Task.Run
を使わない - Cancellation tokensを使うこと
順次処理と並行処理
- 例1:
Okay Codeではループの中でawaitを使って処理を一つずつ完了している.
Better CodeではWhenAll
を使ってすべての処理を同時に処理している.
- 例2:
Okay CodeではWhenAllを使ってすべてのリクエストの結果が得られるまでawaitして,結果のリストからオブジェクトを取得している.
Better CodeではWhenAnyを使って,結果が得られたものから直ちにオブジェクトを取得.
こちらの方が効率が良いとのこと.
Cancellation tokens
Taskのキャンセルに使用する.
tokenを作って,それをTaskの実行時に渡す.そして,Cancel()メソッドを実行すると,Taskの実行を終了させることができる.
var cts = new CancellationTokenSource();
var token = cts.Token;
Task.Run(async() => await someLongRunningAction(),tokens);
cts.Cancel();
しかし,Cancelのハンドリングは以下のように並行処理の中にtokenを介してThrowIfCancellationRequested()
を記述しておく必要がある.
Cancelされた後に,この記述の位置に来たときにTaskがキャンセルされる.
var cts = new CancellationTokenSource(); var token = cts.Token; Task.Run(async() => await { for (int i = 0; i<3; i++){ token.ThrowIfCancellationRequested(); } },tokens); cts.Cancel();
参考:
Event Handlers
public class Subscriber :IDisposable { readonly Publisher publisher; EventHandler handler; public Subscriber(Publisher publish) { publisher = publish; handler=(sender,e)=>{ Debug.Writeline("The publisher notified the subscriber of an event."); }; publisher.MyEvent+= } public void Dispose() { publisher.MyEvent -=handler; } }
public class Publisher { public event EventHandler MyEvent; public void OnMyEventFires() { if(MyEvent != null){ MyEvent(this,EventArgs.Empty); } } } public class Subscriber: IDisposable { readonly Publisher; public Subscriber(Publisher publish) { publisher=publish; publisher.MyEvent+=OnMyEventFires; } void OnMyEventFires (object sender,EventArgs e) { Debug.Writeline("..."); } public void Dispose () { publisher.MyEvent -= OnMyEventFires; } }
データのロード
- ローカルデータをまず読み込む
- Webとのデータのやり取りを最小限に抑える.
- ただのラベルやタイトルといった静的なデータをバインドしないこと.
Profilerを活用しろ
- 確認する点
- メモリーリーク,
- 大きな画像
- 大きなオブジェクトグラフ
- 広いスコープ
相互参照
計測する点
- 起動時間
- 実行時間
- メモリ消費
- CPU利用状況
- ネットワーク状況
- I/O状況
Icon, Image, Asset
ディスプレイの解像度ごとに画像の解像度も最適化するのが良い.
でも,それを手動で行うのは手間なので,ResizetizerNTというNugetパッケージがある.
レイアウトについて
フォントについて
- フォントを
- 画像を使わずに,アイコンフォントを使うこと
- 非表示のタブページの扱いに気をつけること
参考: