公式でも、Xamarin から .NET へのアップグレードが案内されるようになりました。いよいよ Xamarin が終焉が近くなってきました。
learn.microsoft.com
Xamarin.Forms から MAUI への移行は .NET Upgrade Assistant が利用できます。
learn.microsoft.com
Xamarin.Android、Xamarin.iOS、Xamarin.Mac といった Xamarin プロジェクトは現状、「手動」でのアップグレードになってしまいます。
learn.microsoft.com
.NET MAUI の主なプロジェクトテンプレート(Xamarin との比較)
Xamarin でサポートされていたプロジェクトは .NET MAUI でサポートされているのでしょうか。
というわけで.NET MAUI の主なプロジェクトテンプレートを Xamarin と比較してみました。
下記の表の「短い名前」は、 .NET CLI で
dotnet new maui
のように「短い名前」をテンプレート名として使うことでプロジェクトを作成できます。
learn.microsoft.com
Xamarin | .NET | ||
---|---|---|---|
テンプレート名 | テンプレート名 | 短い名前 (dotnet new <TEMPLATE>) |
|
iOSアプリ | iOSアプリ(Xamarin) | iOS アプリケーション(プレビュー) | ios |
MacCatalyst アプリケーション(プレビュー) | maccatalyst | ||
watchOSアプリ | watchOSアプリ(Xamarin) | .NET 6 未サポート。.NET 7 での追加サポート予定もなし https://twitter.com/davidortinau/status/1519303524726849536 |
|
Androidアプリ | Androidアプリ(Xamarin) | Android Application | android |
Android Wear アプリ | Android Wear アプリ(Xamarin) | Android Wear Application | androidwear |
クロスプラットフォームモバイルアプリ | モバイルアプリ(Xamarin.Forms) | .NET MAUI アプリ | maui |
macOSアプリ | cocoaアプリ(Xamarin) | macOS アプリケーション(プレビュー) | macOS |
MacCatalyst アプリケーション(プレビュー) | maccatalyst |
.NET では watchOS アプリは未サポートです。今のところ .NET 7 での追加サポート予定もありません。
(たいして使われていない割に、サポートするには手間がかかるため、予定がないとのことです。)
以下、.NET MAUI のプロダクトマネージャーのツイートです。
we don’t have watchOS support in .NET 6 and no plans to add it in .NET 7. The original .NET 6 issue tracking Apple SDK plans stated this and since then it’s not on any roadmap. We will consider it in the future. High cost, low usage.
— David Ortinau (@davidortinau) 2022年4月27日
Apple M1 Mac 上の Visual Studio for Mac で Xamarinはどれくらい使えるか調べました。(2020/12/13時点)
はじめに
こんにちは、@hiro128_777です。
この記事は「Xamarin Advent Calendar 2020」の13日目になります。
Apple M1 Mac が発売されて1ヶ月になりますね。というわけで、macOS Big Sur (Apple M1) 上の、Visual Studio for Mac で Xamarin がどれくらい使えるか再度確認してみました。
ちなみに、11/23 時点での状況こちらとなっております。
hiro128.hatenablog.jp
バージョン
- macOS Big Sur 11.0.1
- Visual Studio for Mac Version 8.8.3 (build 16)
- Xcode 12.2
Xcode は Universal App です。
Visual Studio はまだ Intel App で Rosetta2 を介しての動作となります。
Visual Studio for Mac のインストールと起動
インストールと起動は全く問題ありません。当該の Mac 上で、 なお、Rosetta 2 を利用するアプリの起動が初めての場合は、Rosetta 2 のインストールが走ります。
アプリごとの動作のまとめ
SDK 認識・コード編集 | エミュレーター デバッグ実行 |
実機 デバッグ実行 |
Xamarin Profiler エミュレーター |
Xamarin Profiler 実機 |
備考 | |
---|---|---|---|---|---|---|
iOS | ○ OK | ○ OK | ○ OK | ○ OK | ○ OK | |
Android | ○ OK | △ 一応動作 | ○ OK | ○ OK | ○ OK | エミュレーターはプレビュー版で動作 |
macOS | ○ OK | --------------- | ○ OK | --------------- | ○ OK | Intel App としてビルドされ、 Universal App としてビルドできない |
結論から言うと、発売直後の状況より改善があります。
以下詳細となります。
iOS アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行(シミュレータ)
問題ありません。
ビルド・デバッグ実行(実機)
問題ありません。
11/23 時点では iOS で実機にデプロイ時にプロビジョニングプロファイルの設定が不完全な時、1度だけ Visual Studio for Mac がクラッシュする現象が発生しましたが、それが起こらなくなりました。ですが、たまたま起こらなかったのか改善されたのかは不明です。
Xamarin Profiler(シミュレータ)
問題ありません。
Xamarin Profiler(実機)
問題ありません。
Android アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行(エミュレータ)
11/23 時点では、エミュレータが起動できず実行できませんでしたが、プレビューですが、Google からApple M1 で動作するエミュレーターがリリースされており、そちらででエミュレーター上のデバッグが可能となりました。
エミュレータは以下からダウンロードしてインストールできます。
github.com
起動すると、Visual Studio for Mac で認識します。
なお、プロジェクトオプションで「迅速なアセンブリの配置」を外さないと、デプロイでエラーが出ました。
プレビュー版で試したら発生しませんでしたので、以下の issue のようです。
github.com
ビルド・デバッグ実行(実機)
問題ありません。
Xamarin Profiler(シミュレータ)
問題ありません。
Xamarin Profiler(実機)
問題ありません。
mac アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行(実機)
こちらは状況が変わらず、ビルド、デバッグ実行できますが、Universal App としてビルドさせる設定が見つからず、結果として、Intel App としてビルドされ、Universal App としてはビルドできません。
Xamarin Profiler(実機)
問題ありません。
まとめ
というわけで、再度の検証では、Apple M1 Mac 発売直後より状況が改善され、動くには動くという状況にはなりました。少なくとも実機での動作は問題なくなっていますので、実機デバッグのみで開発するのであれば問題ない感じです。エミュレーターも使う場合には、もう少し待てば、Android でも問題なく使えるようになりそうです。
なお、速度的には全く遅いとは感じませんでした。あとは、Visual Studio for Mac が M1 ネイティブで動くようになると嬉しいのですが、情報が全く無くどこまで開発が進んでいるのかもわかりません。Xamarin 後継の .NET MAUI は Visual Studio Code をサポートするとアナウンスされていますので、MAUI リリースまで Rosetta 2 で引っ張って、Visual Studio for Mac は廃止で Visual Studio Code に移行というような事態にならないかがとても心配です。
早く Visual Studio for Mac を M1 ネイティブ対応にしていただけると助かります。
今回は以上です。
macOS Big Sur (Apple M1) 上で、Visual Studio for Mac を軽く試してみました。(2020/11/23速報版)
はじめに
こんにちは、@hiro128_777です。
ようやく、Apple M1 Mac が自宅に届きました。というわけで、早速 Apple M1 Mac で Visual Studio for Mac を一通り軽く試してみました。なお、まだ詳しい検証はできておりませんので、引き続き調査したいと思います。
Intel Mac の Big Sur 上の動作状況は以下をご覧ください。
hiro128.hatenablog.jp
バージョン
- macOS Big Sur 11.0.1
- Visual Studio for Mac Version 8.8.1 (build 37)
- Xcode 12.2
Xcode は Universal App です。
Visual Studio は Intel App で Rosetta2 を介しての動作となります。
Visual Studio for Mac のインストールと起動
インストールと起動は全く問題ありません。当該の Mac 上で、 なお、Rosetta 2 を利用するアプリの起動が初めての場合は、Rosetta 2 のインストールが走ります。
なお、Visual Studio for Mac Version 8.8 のリリースノートは以下をご参照ください。
docs.microsoft.com
アプリごとの動作のまとめ
SDK 認識・コード編集 | エミュレータ デバッグ実行 |
実機 デバッグ実行 |
備考 | |
---|---|---|---|---|
ASP.NET(.NET 5) | ○ OK | --------------- | × NG | Safari (Universal) 、 Chrome (Universal) ともに同じエラー |
iOS | ○ OK | ○ OK | ○ OK(若干不安定) | 実機でプロビジョニングプロファイルの設定が不完全な時、 1度 VS がクラッシュ |
Android | ○ OK | × NG | × NG | エミュレータが起動せず、実機も認識しない |
macOS | ○ OK | --------------- | ○ OK | Intel App としてビルドされ、Universal App としてビルドできない |
ASP.NET(.NET 5)
自分の環境では、Intel Mac 同様、ASP.NET で初回のみ開発証明書に関するダイアログが出ましたが、以下のように、画面表示の通り許可すれば、次回以降は聞かれなくなります。
上記は、微妙に発生条件が違いますが、以下の issue が相当しそうです。
docs.microsoft.com
ただし、対処後もデバッグ実行に失敗します。
下記のようなエラーメッセージが出ます。
------------------------------------------------------------------- You may only use the Microsoft .NET Core Debugger (vsdbg) with Visual Studio Code, Visual Studio or Visual Studio for Mac software to help you develop and test your applications. ------------------------------------------------------------------- Loaded '/usr/local/share/dotnet/shared/Microsoft.NETCore.App/5.0.0/System.Private.CoreLib.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. Stack overflow. at System.Collections.HashHelpers.GetPrime(Int32) at System.Collections.Generic.Dictionary`2[[System.__Canon, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Initialize(Int32) at System.Collections.Generic.Dictionary`2[[System.__Canon, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]..ctor(Int32, System.Collections.Generic.IEqualityComparer`1<System.__Canon>) at System.AppContext.Setup(Char**, Char**, Int32)
iOS アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行(シミュレータ)
問題ありません。
ビルド・デバッグ実行(実機)
問題ありません。
プロビジョニングプロファイルの設定が不完全な時、1度だけ Visual Studio がクラッシュしました。その後は、プロビジョニングプロファイルの設定が不完全であることを示すエラーが表示されました。
Android アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行(エミュレータ)
エミュレータが起動できず、実行できません。
ビルド・デバッグ実行(実機)
実機を認識しませんでした。ただし、Intel Mac では、実機をきちんと認識しますので、Visual Studio for Mac 起因の問題ではない可能性もあります。
mac アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行(実機)
ビルド、デバッグ実行できますが、Universal App としてビルドさせる設定が見つからず、結果として、Intel App としてビルドされ、Universal App としてはビルドできません。
まとめ
というわけで、軽く触った感じでは、Apple M1 Mac ではまだ問題が結構ありそうです。エラーの原因も詳しく調べられていないので、もう少し色々試してみたいと思います。
なお、速度的には特に遅いとは感じませんでした。Visual Studio for Mac が M1 ネイティブで動くようになるのが楽しみです。
また、M1 Mac 発売から1ヶ月後の 2020/12/13 時点での、調査結果は以下をご覧ください。
hiro128.hatenablog.jp
今回は以上です。
macOS Big Sur (Intel) 上で、Visual Studio for Mac を軽く試してみました。
はじめに
こんにちは、@hiro128_777です。
待ちに待った macOS Big Sur がリリースされました。というわけで、早速アップデートし Intel Mac 上で Visual Studio for Mac を一通り軽く試してみました。
なお、Apple M1 チップ Mac 上の検証結果は以下をご覧ください。
hiro128.hatenablog.jp
バージョン
- macOS Big Sur 11.0.1
- Visual Studio for Mac Version 8.8 (build 2913)
- Xcode 12.2
Visual Studio for Mac 起動
問題ありません。
なお、Visual Studio for Mac Version 8.8 のリリースノートは以下をご参照ください。
docs.microsoft.com
iOS アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行(シミュレータ)
問題ありません。
Android アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行(シミュレータ)
問題ありません。
.NET 5 ASP.NET アプリ
SDK 認識・コード編集
問題ありません。
ビルド・デバッグ実行
自分の環境では、ASP.NET デバッグ実行時、開発証明書に関するダイアログが出ましたが、以下のように、画面表示の通り許可すれば、問題ありませんでした。
上記は、微妙に発生条件が違いますが、以下の issue が相当しそうです。
docs.microsoft.com
なお、対処後は無事デバッグ実行もできました。
まとめ
というわけで、軽く触った感じでは、Intel Mac では問題なさそうです。
Apple M1 Mac での挙動は、実機が届き次第確認してみます。
今回は以上です。
DualScreen 対応の Xamarin.Forms アプリを作ってみる (3)
はじめに
こんにちは、@hiro128_777です。
とうとう iPhone 12 が発売されましたね。でも、Surface Duo も忘れないでください。Surface Duo 日本での発売はまだですが、すでに、エミュレーターで疑似体験することは可能です。
というわけで、10月27日(火)に、エミュレーターで Surface Duo 対応アプリを体験するオンラインハンズオンを開催いたします!
こちらは、簡単な Surface Duo のエミュレーターで動作するマルチスクリーン対応アプリを作って体験していただけるコンテンツになっていますので、ご興味がある方はぜひご参加下さい!
この記事は(3)ですので、最初から手順をお試しになる場合は下記の(1)からお願いします。
hiro128.hatenablog.jp
(2)は下記からお願いします。
hiro128.hatenablog.jp
今回やること
ViewModel と Service を紐づけてアプリを完成させます。
ViewModel と Service を紐づける
ViewModel と Service を紐づけるコードを追記していきます。
なお、このサンプルはコードをシンプルにし、Dual Screen の動作をわかりやすくするために、 DI などコードの量が増える手法はあえて省いています。
MasterDetailPage.xaml.cs を修正
// 追記
の部分を追記してください。
bool IsSpanned => DualScreenInfo.Current.SpanMode != TwoPaneViewMode.SinglePane; DetailsPage detailsPagePushed; MasterViewModel masterViewModel; // 追記 DetailsViewModel detailsViewModel; // 追記 public MasterDetailPage() { InitializeComponent(); NavigationPage.SetHasNavigationBar(this, IsSpanned); detailsPagePushed = new DetailsPage(); masterViewModel = masterPage.BindingContext as MasterViewModel; // 追記 masterViewModel.SetupViewsAction = () => SetupViews(); // 追記 detailsViewModel = masterViewModel.DetailsViewModel; // 追記 detailsPagePushed.BindingContext = detailsViewModel; // 追記 detailsPage.BindingContext = detailsViewModel; // 追記 }
Master.xaml.cs を修正
// 追記
の部分を追記してください。
public Master() { InitializeComponent(); BindingContext = new MasterViewModel(new DetailsViewModel()); // 追記 }
View から確認用の マークアップ を消去
<!-- 確認用(後ほど消去する)ここから -->
から<!-- 確認用(後ほど消去する)ここまで -->
の部分を消去してください。
<Picker Title="路線を選択して下さい" Margin="10" HeightRequest="60" FontSize="Large" HorizontalOptions="Fill" VerticalOptions="Fill" ItemsSource="{Binding LineItems}" SelectedItem="{Binding SelectedLineItem, Mode=TwoWay}" > </Picker> <!-- 確認用(後ほど消去する)ここから --> <Label FontSize="Title" TextColor="Coral" Text="Master" HorizontalOptions="CenterAndExpand"> </Label> <!-- 確認用(後ほど消去する)ここまで --> <CollectionView x:Name="Stations" ItemsSource="{Binding StationItems}" SelectionMode="Single" SelectedItem="{Binding SelectedStationItem, Mode=TwoWay}" SelectionChangedCommand="{Binding SelectStationCommand}" >
Details.xaml から確認用の マークアップ を消去
<!-- 確認用(後ほど消去する)ここから -->
から<!-- 確認用(後ほど消去する)ここまで -->
の部分を消去してください。
<Label BackgroundColor="White" FontSize="Title" Grid.Column="1" Grid.Row="1" Text="{Binding Name}" VerticalTextAlignment="Center" > </Label> </Grid> <!-- 確認用(後ほど消去する)ここから --> <Label FontSize="Title" TextColor="Coral" Text="Detail" HorizontalOptions="CenterAndExpand"> </Label> <!-- 確認用(後ほど消去する)ここまで --> <StackLayout BackgroundColor="White" Padding="5">
以上でコードは完成です。
デバッグ実行し、Dual Screen でアプリが動作するか確認する
Dual Screen で表示させるためには以下の動画の手順でアプリをスパンしてください。
Surface Duo Span 操作
youtu.be
上記の動画のように、路線と駅が選択でき、時刻が表示されればサンプルアプリは完成です。
今回は以上です。
DualScreen 対応の Xamarin.Forms アプリを作ってみる (2)
はじめに
こんにちは、@hiro128_777です。
とうとう iPhone 12 が発表されましたね。でも、Surface Duo も忘れないでください。Surface Duo 日本での発売はまだですが、すでに、エミュレーターで疑似体験することは可能です。
というわけで、10月27日(火)に、エミュレーターで Surface Duo 対応アプリを体験するオンラインハンズオンを開催いたします!
こちらは、簡単な Surface Duo のエミュレーターで動作するマルチスクリーン対応アプリを作って体験していただけるコンテンツになっていますので、ご興味がある方はぜひご参加下さい!
なお、この記事は(2)ですので、最初から手順をお試しになる場合は下記の(1)からお願いします。
hiro128.hatenablog.jp
今回やること
TwoPaneView
を作成し、Surface Duo エミュレータ―上で、Master - Detail 構成のページを Dual Screen 表示できるようにします。
TwoPaneView
はGrid
を継承しており、左右または上下に 2 つのビューを配置できるコンテナーです。
TwoPaneView
の詳細については下記公式ドキュメントをご参照ください。
Dual Screen に対応するには、以下の対応を行うだけであり、非常に簡単です。
- Single Screen 用と、Dual Screen 用の "ガワ" の ContentPage を別々に用意し、それぞれのコンテンツの配置情報のみ記述する。
- 具体的なコンテンツ(配置する UI)の XAML を用意する。
TwoPaneView
が 画面の表示領域のサイズによって、Single Screen 用または、Dual Screen 用 の画面を表示できるように、MinWideModeWidth
をMinTallModeHeight
を設定します。
TwoPaneView
の Single Screen、Dual Screen の制御の詳細については下記公式ドキュメントをご参照ください。
これから作成するサンプルアプリの Single Screen、Dual Screen のときの構成を図に表すと以下のようになります。
Single Screen 時の構成
Dual Screen 時の構成
では、次にコードを書いていきましょう。
TwoPaneView
用のコンテンツページとコンテンツビューのファイル追加する
- View フォルダを追加します。
- 以下の4つのコンテンツページを追加します。
MasterDetailPage.xaml
コンテンツページDetailsPage.xaml
コンテンツページMaster.xaml
コンテンツビューDetails.xaml
コンテンツビュー
以下のようになればOKです。
デフォルトの MainPage に設定されているMainPage.xaml
を削除します。
MasterDetailPage を MainPage として設定します。
App.xaml.cs
public App() { InitializeComponent(); MainPage = new NavigationPage(new MasterDetailPage()); }
MasterDetailPage.xaml のマークアップとコードを記述する
Single Screen 時は Master Page のコンテンツのみ表示し、Dual Screen 時は 左に Master Page のコンテンツ、右に Detail Page のコンテンツを表示します。
MasterDetailPage.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:dualScreen="clr-namespace:Xamarin.Forms.DualScreen;assembly=Xamarin.Forms.DualScreen" xmlns:local="clr-namespace:XFSurfaceDuoSample2020" mc:Ignorable="d" x:Class="XFSurfaceDuoSample2020.MasterDetailPage"> <dualScreen:TwoPaneView MinWideModeWidth="4000" MinTallModeHeight="4000"> <dualScreen:TwoPaneView.Pane1> <local:Master x:Name="masterPage"></local:Master> </dualScreen:TwoPaneView.Pane1> <dualScreen:TwoPaneView.Pane2> <local:Details x:Name="detailsPage"></local:Details> </dualScreen:TwoPaneView.Pane2> </dualScreen:TwoPaneView> </ContentPage>
MasterDetailPage.xaml.cs
using System.ComponentModel; using System.Linq; using Xamarin.Forms; using Xamarin.Forms.DualScreen; using Xamarin.Forms.Xaml; using XFSurfaceDuoSample2020.Models; using XFSurfaceDuoSample2020.ViewModels; namespace XFSurfaceDuoSample2020 { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class MasterDetailPage { bool IsSpanned => DualScreenInfo.Current.SpanMode != TwoPaneViewMode.SinglePane; DetailsPage detailsPagePushed; public MasterDetailPage() { InitializeComponent(); NavigationPage.SetHasNavigationBar(this, IsSpanned); detailsPagePushed = new DetailsPage(); } async void SetupViews() { NavigationPage.SetHasNavigationBar(this, !IsSpanned); NavigationPage.SetHasNavigationBar(detailsPagePushed, !IsSpanned); NavigationPage.SetHasNavigationBar(detailsPage, !IsSpanned); if (!IsSpanned) { if (!Navigation.NavigationStack.Contains(detailsPagePushed)) await Navigation.PushAsync(detailsPagePushed); } } protected override void OnAppearing() { base.OnAppearing(); DualScreenInfo.Current.PropertyChanged += OnFormsWindowPropertyChanged; } protected override void OnDisappearing() { base.OnDisappearing(); DualScreenInfo.Current.PropertyChanged -= OnFormsWindowPropertyChanged; } void OnFormsWindowPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(DualScreenInfo.Current.SpanMode) || e.PropertyName == nameof(DualScreenInfo.Current.IsLandscape)) { SetupViews(); } } } }
DetailsPage.xaml のマークアップとコードを記述する
Single Screen 時は Detail Page を表示します。Dual Screen 時は使用されません。
DetailsPage.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:XFSurfaceDuoSample2020" mc:Ignorable="d" x:Class="XFSurfaceDuoSample2020.DetailsPage" Title="Master Details" Padding="10,0,0,0" > <local:Details></local:Details> </ContentPage>
DetailsPage.xaml.cs
using Xamarin.Forms.DualScreen; using Xamarin.Forms.Xaml; namespace XFSurfaceDuoSample2020 { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class DetailsPage { bool IsSpanned => DualScreenInfo.Current.SpanMode != TwoPaneViewMode.SinglePane; public DetailsPage() { InitializeComponent(); } protected override void OnAppearing() { base.OnAppearing(); DualScreenInfo.Current.PropertyChanged += OnFormsWindowPropertyChanged; } protected override void OnDisappearing() { base.OnDisappearing(); DualScreenInfo.Current.PropertyChanged -= OnFormsWindowPropertyChanged; } async void OnFormsWindowPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { if(e.PropertyName == nameof(DualScreenInfo.Current.SpanMode) || e.PropertyName == nameof(DualScreenInfo.Current.IsLandscape)) { if (IsSpanned) await Navigation.PopAsync(); } } } }
Master.xaml のマークアップとコードを記述する
Master Page のコンテンツです。
Master.xaml
<?xml version="1.0" encoding="utf-8" ?> <StackLayout xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="XFSurfaceDuoSample2020.Master" > <StackLayout.Resources> <ResourceDictionary> <Style TargetType="Grid"> <Setter Property="VisualStateManager.VisualStateGroups"> <VisualStateGroupList> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal" /> <VisualState x:Name="Selected"> <VisualState.Setters> <Setter Property="BackgroundColor" Value="LightSkyBlue" /> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateGroupList> </Setter> </Style> </ResourceDictionary> </StackLayout.Resources> <Picker Title="路線を選択して下さい" Margin="10" HeightRequest="60" FontSize="Large" HorizontalOptions="Fill" VerticalOptions="Fill" ItemsSource="{Binding LineItems}" SelectedItem="{Binding SelectedLineItem, Mode=TwoWay}" > </Picker> <!-- 確認用(後ほど消去する)ここから --> <Label FontSize="Large" TextColor="Coral" Text="Master Page のコンテンツ" HorizontalOptions="CenterAndExpand"> </Label> <!-- 確認用(後ほど消去する)ここまで --> <CollectionView x:Name="Stations" ItemsSource="{Binding StationItems}" SelectionMode="Single" SelectedItem="{Binding SelectedStationItem, Mode=TwoWay}" SelectionChangedCommand="{Binding SelectStationCommand}" > <CollectionView.ItemTemplate> <DataTemplate> <Grid Padding="5" > <Frame Visual="Material" BorderColor="LightGray"> <StackLayout Padding="0" > <Label FontSize="Title" Text="{Binding Name}"> </Label> </StackLayout> </Frame> </Grid> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </StackLayout>
Master.xaml.cs
using Xamarin.Forms; using Xamarin.Forms.Xaml; using XFSurfaceDuoSample2020.ViewModels; namespace XFSurfaceDuoSample2020 { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class Master : StackLayout { public Master() { InitializeComponent(); } } }
Details.xaml のマークアップとコードを記述する
Detail Page のコンテンツです。
Details.xaml
<?xml version="1.0" encoding="UTF-8"?> <StackLayout xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:d="http://xamarin.com/schemas/2014/forms/design" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="XFSurfaceDuoSample2020.Details" BackgroundColor="LightGray" Spacing="0" > <Grid BackgroundColor="White" RowSpacing="2" ColumnSpacing="2" Padding="8,8,8,0" VerticalOptions="Center" > <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="*"></ColumnDefinition> </Grid.ColumnDefinitions> <Label BackgroundColor="White" HorizontalTextAlignment="End" VerticalTextAlignment="Center" FontSize="Title" Text="ナンバリング :" > </Label> <Label BackgroundColor="White" Grid.Row="1" HorizontalTextAlignment="End" VerticalTextAlignment="Center" FontSize="Title" Text="駅名 :" > </Label> <Label BackgroundColor="White" FontSize="Title" Grid.Column="1" Text="{Binding SelectedStationItem.ID}" VerticalTextAlignment="Center" > </Label> <Label BackgroundColor="White" FontSize="Title" Grid.Column="1" Grid.Row="1" Text="{Binding Name}" VerticalTextAlignment="Center" > </Label> </Grid> <StackLayout BackgroundColor="White" Padding="5"> <!-- 確認用(後ほど消去する)ここから --> <Label FontSize="Large" TextColor="Coral" Text="Detail Page のコンテンツ" HorizontalOptions="CenterAndExpand"> </Label> <!-- 確認用(後ほど消去する)ここまで --> <CollectionView Margin="3" BackgroundColor="LightGray" x:Name="Stations" ItemsSource="{Binding TimeTableRowItems}" SelectionMode="None" > <CollectionView.ItemTemplate> <DataTemplate> <StackLayout BackgroundColor="LightGray" Padding="1"> <Grid BackgroundColor="LightGray" HorizontalOptions="Fill" VerticalOptions="Center" ColumnSpacing="2" Padding="2,1,2,1" > <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"></ColumnDefinition> <ColumnDefinition Width="10*"></ColumnDefinition> </Grid.ColumnDefinitions> <Label BackgroundColor="LightSkyBlue" Padding="8" Grid.Column="0" Grid.Row="0" Text="{Binding Hour}" FontSize="Large" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" > </Label> <Label BackgroundColor="Beige" Padding="8" Grid.Column="1" Grid.Row="0" Text="{Binding RowText}" FontSize="Large" HorizontalTextAlignment="Start" VerticalTextAlignment="Center" > </Label> </Grid> </StackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </StackLayout> </StackLayout>
Details.xaml.cs
using Xamarin.Forms; using Xamarin.Forms.Xaml; namespace XFSurfaceDuoSample2020 { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class Details : StackLayout { public Details() { InitializeComponent(); } } }
デバッグ実行し、Single Screen、Dual Screen で表示されるか確認する。
Surface Duo エミュレータ―にデプロイすると、以下のように、Single Screen、Dual Screen で表示が変化します。
Single Screen での表示
Dual Screen での表示
Dual Screen で表示させるためには以下の動画の手順でアプリをスパンしてください。
なお、アプリのロジックはまだ実装していないので、画面が表示されるだけで、UI は反応しません。
Surface Duo Span 操作
youtu.be
続きは以下をご覧ください。
hiro128.hatenablog.jp