Xamarin.FormsのGridについて
下図の画面をGridで作成するための前準備のお話し。
Gridの仕様(?)が結構特殊な感じだったためφ(..)
Xamarin.FormsのAngerの内容を流用しているため、Xamlの話ではありません。
AngerのCardsの画面の作り方、結構好きなんですが
これ、Xamlで作るにはどうしたらいいんですかね?さっぱり想像つきません…
Grid
Grid grid = new Grid { RowSpacing = 1, ColumnSpacing = 1, BackgroundColor = UserPageStyleKit.CardBorderColor, VerticalOptions = LayoutOptions.FillAndExpand, RowDefinitions = { new RowDefinition { Height = new GridLength(80, GridUnitType.Absolute)}, new RowDefinition { Height = new GridLength(50, GridUnitType.Absolute)} }, ColumnDefinitions = { new ColumnDefinition { Width = new GridLength(100, GridUnitType.Absolute)}, new ColumnDefinition { Width = new GridLength ( 1,GridUnitType.Star)}, new ColumnDefinition { Width = new GridLength ( 10,GridUnitType.Absolute)}, new ColumnDefinition { Width = new GridLength ( 140,GridUnitType.Absolute)} } };
上記で2行4列のGridとなります。
下図の様なGridの配置となります。
それぞれGridLengthが指定されていますが、紫色背景の列は
GridUnitType.starが指定されているため、表示領域により動的に幅が変わるようです。
例えば、下記のようにソースを変更すると、1:2で描画されるようです。
ColumnDefinitions = { new ColumnDefinition { Width = new GridLength(100, GridUnitType.Absolute)}, new ColumnDefinition { Width = new GridLength ( 1,GridUnitType.Star)}, new ColumnDefinition { Width = new GridLength ( 2,GridUnitType.Star)}, new ColumnDefinition { Width = new GridLength ( 140,GridUnitType.Absolute)} }
Grid要素の配置
Gridに対する要素の配置は、下記のようなソースで行っています。
grid.Children.Add(new Label { Text = "(0,1,0,1)", BackgroundColor = Color.Black }, 0, 1, 0, 1); grid.Children.Add(new Label { Text = "(1,2,0,1)", BackgroundColor = Color.White }, 1, 2, 0, 1); grid.Children.Add(new Label { Text = "(2,3,0,1)", BackgroundColor = Color.Blue }, 2, 3, 0, 1); grid.Children.Add(new Label { Text = "(3,4,0,1)", BackgroundColor = Color.Pink }, 3, 4, 0, 1); grid.Children.Add(new Label { Text = "(0,1,1,2)", BackgroundColor = Color.Silver }, 0, 1, 1, 2); grid.Children.Add(new Label { Text = "(1,2,1,2)", BackgroundColor = Color.Purple }, 1, 2, 1, 2);
Text要素が、上図の(x,x,x,x)で表記されている内容です。
下図のような感じの考えたでしょうか?(手書き汚くてすみません)
なので、(0,1,0,2)と指定してやることで
下図のようにRowをまたがった描画も可能となります。
ただし、下記のように描画箇所がバッティングを起こすと
後に宣言されたものが優先して描画されます。
grid.Children.Add(new Label { Text = "(0,1,0,2)", BackgroundColor = Color.Black }, 0, 1, 0, 2); grid.Children.Add(new Label { Text = "(0,1,1,2)", BackgroundColor = Color.Silver }, 0, 1, 1, 2);
Column数以上の数値を指定したとき
ここ、少し戸惑いました。
基本形を下図とします。
grid.Children.Add(new Label { Text = "(3,5,0,2)", BackgroundColor = Color.Blue }, 3, 5, 0, 2);
上記コードを突っ込んだときエラーになるかというとなりませんでした。
下図のようになります。
見にくいですが、2/3列目が縮小されています。
2/3列目をAbsolute属性に変更し、同様のソースで実行したところ
下図のようになりました。
領域をフルに活用して描画するようになっているのでしょうか?
Column数が拡張されているように見受けられます。
ちなみに、下のようなソースで実行した場合
grid.Children.Add(new Label { Text = "(4,100,0,1)", BackgroundColor = Color.Maroon }, 4, 100, 0, 1); grid.Children.Add(new Label { Text = "(4,20,1,2)", BackgroundColor = Color.Maroon }, 4, 20, 1, 2);
下図のような描画となります。
残領域で100カラム作っているんですかね?
Gridのここらへんの動作分かってないと
ほぼエラーが発生しないんでドツボにはまることになるかもしれません。
まとめ
気を付けなければいけない部分はありますが
Gridを活用すれば、イケている画面を作成する余地は十分にありそうです。
Congnitive Serviceを使ってみる - App実行編(Adult検証) -
続きです。
完全に釣りタイトルかもしれませんが
VisionがXamarinでも使用できるのであれば
顔認識系のアプリもさくっとできるかもしれない。
というかそれがしたいがために、このサービスの検証をしています。
「Adult」はAPIの中にあったんで、気になって検証しました。
だって男の子ですし
コンソールアプリケーションで試す(Code)
以下のサイトを参考にコンソールからCongnitive Serviceを使用してみます。
Microsoft Cognitive Services - Documentation
NuGetでVisionを取得
ソース
VisionServiceClient VisionServiceClient = new VisionServiceClient({SUBSCRIPTION_KEY}); AnalysisResult analysisResult; using (Stream imageFileStream = File.OpenRead({FILE_PATH})) { VisualFeature[] visualFeatures = new VisualFeature[] { VisualFeature.Adult, VisualFeature.Categories, VisualFeature.Color, VisualFeature.Description, VisualFeature.Faces, VisualFeature.ImageType, VisualFeature.Tags }; analysisResult = await VisionServiceClient.AnalyzeImageAsync(imageFileStream, visualFeatures); }
これだけです。
これだけでComputerVisionの恩恵をあずかれるのは素晴らしいですね。
動かしてみる
自分の写真を使ってみました(実際に目線はないしサイズももうちょっとでかいです)
・こんなん
実行結果
きちんと返ってきました。中身も色々と興味深いです。
現在年齢は27、1歳など誤差の範囲なので、いい感じの認識能力です。
GenderはFemale??
MSでは、Female=男なの?と訝しみ、Bingで翻訳してみましたが「女性」と出ましたので
やはり、自分はMS的には女性として認識されているようです。
(日本人の顔認識は苦手なのかな?)
「Adult」が気になる
IsAdultContent = False?
もしかして、これ画像が成人コンテンツか判断しているのか?
気になるので検証してみました。
いざAdult検証
というわけで、検証のため、検証のため
肌色多めのあだるてぃな画像を用意して検証してみました。
(さすがに画像は載せれません)
結果
Adult認証!
やはり画像が成人コンテンツかどうか判定するものなんですね。
ちなみに、↓みたいな肌色一色の画像はFalseになりました。結構有能っぽいです。
ちょっと真面目にAdult考察
まぁ画像1・2個試しただけなので、その精度はいかがなものか?というのもありますが
お子さん向けのアプリケーションで、フィルタをかけるのにいいかもしれません。
また、MobileApp系の審査って、成人コンテンツに敏感なイメージがあります
Upload&閲覧系のアプリケーションの成人コンテンツのブロックにもいいかもしれませんね。
しかし、2次元とか水着とか肌の色がアバターとか着衣とかどうなるんだろう…?
明日にでも試そうと思います。んでXamarinの人柱erに戻ります。
今日はもう限界なのでここまで。
Congnitive Serviceを使ってみる - 導入編 -
JXUGとても楽しかったです。
色々と昂ってきたので、冷めやらないうちに色々やろうと思います。
とりあえずCongnitiveServieを!(ぇ
準備
CongnitiveServieのトライアル版を下記サイトで試すことができます。
「GetStartedFree」からトライアル版の申し込みが可能です。
Microsoftアカウントが必要となりますので、ない人は事前に取得が必要です。
登録が完了すると「MyAccount」から登録したプロダクトの確認が行えます。
プロダクトの確認画面
Preview版は下記の通りの制限があるようです。
Face:30,000トランザクション/月 20回/分
ComputerVision:5,000トランザクション/月 20回/分
APIの動作の確認
使用の仕方はAPIのリファレンスがあるので↓を参考に。
Microsoft Cognitive Services
上記ページの「OPEN API TESTING CONSOLE」から
コード記述なしで実際の動きを確認することができます。
TESTING CONSOLE画面
- VisualFeatures:顔認識の「Face」を選択。
- Subscription-Key:上図の「MyAccount」画面で表示されるKey。
- RequestBody:顔認識を行いたい画像のURLを指定。
画面下部の「Send」押下で処理が実行されます。
実行結果
結果は、上記に様に返却されます。
今回は1万円の諭吉さんの画像を使用したので
年齢・性別ともに、いい感じに認識できていると思います。
あとはJson.Netを使用して
ほしい情報を引っこ抜けばいいわけですね。
長くなるので「App実行編」に続きます。
EmployeeDirectoryを弄ってみた
以前に書いた通り、EmployeeDirectoryのマージをしました。
ただ、思った以上にサンプルとしては内容が盛りだくさんな感じなので
ポイント部分と動作イメージだけさらっと
結果として、EmployeeDirectoryは入門編にはちょうどいい感じがしました。
構成
サンプルのソリューションの構成が今までのと違います。
UIとビジネスロジックをソリューションから分離している感じですね。
というかこのサンプル、ログイン画面込みの構成なんで
最初からこれを使えばよかった…と思ったのは別の話。
一応自分が作ったマージするほうも同様に、下図の様にUIとロジックで分離しました
これ関係ぜんぶ書き出すとめちゃくちゃ長くなりそうなので
一部だけ
ログイン画面の遷移
App.cs内の初期ページの指定として、ログイン画面ではなくMain画面を指定します
App.cs
public App() { var task = Task.Run(async () => { //CSVをメモリに格納 Service = await MemoryDirectoryService.FromCsv("XamarinDirectoryTemp.csv"); }); task.Wait(); //ログインページではなくMainPageを指定 MainPage = new NavigationPage(new MainPage()); }
また、上記で指定したMainPage.csのOnAppearingイベント内で
LoginPageをPush表示します。
これで、App起動時にLogin画面が開かれることになります。
MainPage.cs
protected async override void OnAppearing() { base.OnAppearing(); if (LoginViewModel.ShouldShowLogin(App.LastUseTime)) { if (!LoginPageAdd) { LoginPageAdd = true; //ログインページを表示 await Navigation.PushModalAsync(new LoginPage()); } } favoritesRepository = await XmlFavoritesRepository.OpenIsolatedStorage("XamarinFavorites.xml"); if (favoritesRepository.GetAll().Count() == 0) { favoritesRepository = await XmlFavoritesRepository.OpenFile("XamarinFavorites.xml"); } viewModel = new FavoritesViewModel(favoritesRepository, true); }
ログイン成功時はPopModaiAsyncでMain画面に戻ります。
※単純にこの実装だけだと、Androidの「戻る」ボタン押下で
Main画面を見れてしまうのですが(^^;)
まぁその制御はおいおい。
PCLStorage
このサンプルでは、端末のローカルストレージにCSVファイルを落とし
CSVの内容からLINQでUserViewModelの配列を生成しています。
端末のローカルストレージに落とす場合
PCLStorageの機能を使用して
同一のロジックでファイル操作を行っているようです。
MemoryDirectoryService.cs
public async static Task<MemoryDirectoryService> FromCsv(string path) { //PCLStorage機能を使用しファイル操作 IFolder store = FileSystem.Current.LocalStorage; var file = await store.GetFileAsync(path); using (var reader = new StreamReader(await file.OpenAsync(FileAccess.Read))) { return FromCsv(reader); } }
これは↓に格納されるようです。
動作させた
ログイン後はMasterDetailページとなります。
MasterDetailのサンプル画面から
EmployeeListの画面に遷移します。
(サンプルから中身弄ってないんで頭だけ出しときます)
まとめ
ページ遷移からファイル操作、ViewModelを使用したMVVMな作り等
EmployeeDirectoryのサンプルは盛りだくさんといった感じです。
なので、とっかかりとしてやる分には非常にいいのではないかな?
と思います。
備忘録:Xamarin系
Link貼り間違えてました…ので修正。
とりあえず、Xamarin.Formsで色々やりたいこと調べたので備忘録的にφ(..)
Xamarin.FormsでPopUpViewを出したいときに使えそう
SearchBarの使い方
Xamarin.Formsのイケてるデザイン指南?
Xamarin.Formsコントロールのチートシート
Xamarin.Formsのサンプルで遊んでみたよ!
Evoleve2016始まりましたね!
どんな発表があるかドキドキですね!
サンプルで遊ぶ
Hello, iOSですとかHello Androidもいいですけど
実際にゴリゴリ動いているのを見るとソースをいじるのが楽しくなりますよね。
今回、Xamarin.FormsのGitHubで提供されている、2つのSampleを組み合わせて遊んでみました。
今回組み合わせたサンプル2つ
xamarin-forms-samples/Navigation/LoginFlow/
xamarin-forms-samples/Navigation/MasterDetailPage/
使用しているサンプル名称を見ていただければわかる通りですが
ログイン画面でログイン→MasterDetailページに遷移
といった単純な構成です。とっかりりとしてはこれぐらいがちょうどいいですね。
※MasterDetailPageの構成なんかは、上記のGitHub内にScreenShotがありますのでご覧くださいませ。
まずはサンプルソースをざっと眺めてみる
LoginFlow
開いて早速エラーが出まくったり、MVVMチックな構成ではなかったりと
気になるところは多々ありますが、サンプルを下敷きに新しく作り直せば問題ありません。
LoginPageCS.cs
LoginPage.xaml
まず上の2つのファイルがその名の通りLoginPageのView部分ですね
C#のコードのみでも構成できますし、XAMLを使用することも可能です。
Sampleを組み合わせるうえでLogInPage側の肝のLogicは下記部分ですね。
(実際には色々基本的な部分で重要な部分はいっぱいありますよ!)
LoginPage.xaml,cs
async void OnLoginButtonClicked (object sender, EventArgs e) { var user = new User { Username = usernameEntry.Text, Password = passwordEntry.Text }; var isValid = AreCredentialsCorrect (user); if (isValid) { App.IsUserLoggedIn = true; Navigation.InsertPageBefore (new MainPage (), this); await Navigation.PopAsync (); } else { messageLabel.Text = "Login failed"; passwordEntry.Text = string.Empty; } }
入力されたユーザー名称とパスワードが一致しますかー?というものを確認。
Navigation.InsertPageBeforeで遷移先のページを生成し、Navigation.PopAsyncでページ遷移を行っています。
今回やりたいのは、このMainPageをMasterPageDetailのSampleで使用されているMain画面にするだけです。
MasterDetailPage
こちらはLogic部分で変更する箇所はありません。
ただ、押さえておきたいのは、下記の内容です。
MainPage.xaml
<?xml version="1.0" encoding="UTF-8"?> <MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:MasterDetailPageNavigation;assembly=MasterDetailPageNavigation" x:Class="MasterDetailPageNavigation.MainPage"> <MasterDetailPage.Master> <local:MasterPage x:Name="masterPage" /> </MasterDetailPage.Master> <MasterDetailPage.Detail> <NavigationPage> <x:Arguments> <local:ContactsPage /> </x:Arguments> </NavigationPage> </MasterDetailPage.Detail> </MasterDetailPage>
CSのコードハイライトはちと役不足感があるけどまぁいいか
MainPage.xaml.cs
public MainPage () { InitializeComponent (); masterPage.ListView.ItemSelected += OnItemSelected; if (Device.OS == TargetPlatform.Windows) { Master.Icon = "swap.png"; } } void OnItemSelected (object sender, SelectedItemChangedEventArgs e) { var item = e.SelectedItem as MasterPageItem; if (item != null) { Detail = new NavigationPage ((Page)Activator.CreateInstance (item.TargetType)); masterPage.ListView.SelectedItem = null; IsPresented = false; } }
MainPageがMasterとDetailに分かれており、それぞれページが指定されています。
Maseterがわが「MasterPage」Detail側が「ContactsPage」です。
リストアイテムの選択処理はMasterPage(子)のCSではなく、MainPage(親)で行われています。
XAML側7行目で配置された、MasterPageに配置されたListViewのEventをキャッチし、選択処理が行われています。
NavigationPageでページ遷移を行っています。
item.TargetTypeはMainPageやContentPage等のXAMLで作成したページ名称ですね。
では組み合わせてみよう
前述の通り、Sampleをそのままですとエラーが多すぎるため
新しいソリューションを立ち上げて、ソースを組み合わせていきます。
途中過程はすっとばしまして、ソリューションの構成は下記の通りです。
MVVMっぽい構成になりました。
Mock内にはSampleUserをつっこんでます。
ViewModel内には、UserViewModelとMenuのViewModelですね。
Xamarin.Droid,/iOsにはResourceとして、アイコン情報を登録しただけです。
Droidは \Resources\drawableに
iOSは \Resourcesに格納しました。
デバイス側にはコードを1行も記述していないです。スバラシイ
実行
ログインページでた!
が、ログイン処理時にエラー!!
やはりすんなりはいかないか…
エラーの内容を確認すると
「Navigationページは1ページ1個しか認めませんよ!」という内容のようです。
そりゃそうだ。
では、ここでXAMLを見ていきます。
たしかに、MasterDetailを使用しているMainPage.xamlは
しかし、LoginPageには
では、どこにあるのでしょうか。
App.cs
public App() { if (!IsUserLoggedIn) { MainPage = new NavigationPage(new LoginPage()); } else { MainPage = new NavigationPage(new MainPage()); ; } }
App.csでアプリケーション立ち上げ時のページを指定していますが
ここの部分で、LoginPageがNavigationPageとしてNewされています。
だから、ログインアクション時の、「Navigation.InsertPageBefore (new MainPage (), this)」が使用できるわけですね。
対処療法的に対処してみる
変更後のMainPage.xaml
<?xml version="1.0" encoding="UTF-8"?> <MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:XamarinSample.Views;assembly=XamarinSample" x:Class="XamarinSample.Views.MainPage"> <MasterDetailPage.Master> <local:MasterPage x:Name="MasterPage" /> </MasterDetailPage.Master> <MasterDetailPage.Detail> <!--<NavigationPage>--> <!--<x:Arguments>--> <local:ContactsPage /> <!--</x:Arguments>--> <!--</NavigationPage>--> </MasterDetailPage.Detail> </MasterDetailPage>
完全に対処療法ですが
すでにLoginPageからNavigationを使用したページ遷移が行われているわけですし
改めてNavigationPageタグの宣言する必要ないよね?ってことでNavigationタグを消してみました。
まとめ
- Sampleソースは見るのもいじるのも勉強になります。
- いきなり作りたいものを作るより、Sampleを組み合わせるほうがイメージしやすいかも?
次
EmployeeDirectoryのSampleを流用して、ユーザー管理画面を作ってみようかなと考えています。
あぁ、でもBotFrameworkも気になってるんですよね
まぁ、明日から月曜なんで、遊ぶのはしばらくお預けです…。
ものすごい長くなったんで次回は抑えれるよう頑張ります。
Xamarinを初めて見た
Xamarinが無償化されて幾週間。
自分が嵌った所やら、勉強に使用したものをまとめてみます。
環境設定
正直、Xamarinで一番何が嵌ったかといわれると環境設定のような気がします。
ベース部分は、エクセルソフトの田淵さんが書かれた、下記のサイトが非常に参考になりました。
テンプレートについても非常に有り難かったです。
「読んでほしい」とありますが「必読」です。
Windows10 + VisualStudio Emuratorが鉄板?
鬼門だったのはXamarin Android Player。
元々Win7でやろうとしていたので、導入しようとしていたのですが
VirtualBoxの最新Ver.から、VBox Commnad Failedでまともに動作せず
(うぶんつちゃんすら動かなかった…)
VirtualBoxの5.0.0.0を導入する羽目に。
ただ、旧Ver.を入れ続けることにも抵抗はあったし
Win10+VSEmuratorで動作は確認済みだったため
(早く弄りたいこともあり)Win10側をメインに転向しました。
Win7機2台ほどで試したのですが
両方同様にXAPの環境設定で嵌ったため
PCの環境依存によるものとしても
Win10を使用するのが一番安定するのかなぁ。と感じました。
VSEmuratorについては、標準Emuratorから比べると圧倒的によい動作なので
特に気にせず使用できる感じです。
次回はGitHubで公開されている
Xamarin.Formsのサンプルで遊んだ内容について記述しようと思います。