[英]In .NET MAUI is there a way to choose a different XAML view based upon whether the device is in Landscape or Portrait
我正在使用 .NET MAUI,我有一個相當復雜的特定視圖,如果設備方向是縱向,我寧願有不同的布局,如果設備方向是橫向。
很久以前,我修改了 Android 編程,對於 Android Studio,有一種方法可以在設備橫向時選擇 XAML 文件,而在設備縱向時選擇不同的 XAML 文件。
這對 MAUI 來說可能嗎? 如果不是,這方面的最佳做法是什么?
這是我的布局,在橫向模式下,我可以在一行中放置 3 個主要部分,但這在縱向模式下不起作用,而在縱向模式下,我希望中間的主要元素位於下一行。
以下是我在 Photoshop 上創建的肖像與風景模型的示例:
更新解決方案*************** 我正在嘗試 FreakyAli 發布的解決方案並且有一個主要工作的原型,所以任何想要根據屏幕方向使用不同的 XAML 布局的人可以使用這種方法。
我在我的解決方案中創建了一個名為“ContentViews”的新文件夾。 我添加了 3 個新的 ContentViews(帶有后面代碼的 XAML):
HomePageOrientationViewLoader 稍后將直接加載到 HomePage.xaml 文件中。 這是將在縱向模式下加載 HomePagePortrait ContentView 或在橫向模式下加載 HomePageLandscape ContentView 的控件。
namespace ScoreKeepersBoard.ContentViews;
public partial class HomePageOrientationViewLoader : ContentView
{
public ContentView homePagePortraitContentView;
public ContentView homePageLandscapeContentView;
public HomePageOrientationViewLoader()
{
InitializeComponent();
homePagePortraitContentView = new HomePagePortrait();
homePageLandscapeContentView = new HomePageLandscape();
this.Content = homePageLandscapeContentView;
DeviceDisplay.Current.MainDisplayInfoChanged += Current_MainDisplayInfoChanged;
this.Content = DeviceDisplay.Current.MainDisplayInfo.Orientation == DisplayOrientation.Portrait ? homePagePortraitContentView : homePageLandscapeContentView;
}
private void Current_MainDisplayInfoChanged(object sender, DisplayInfoChangedEventArgs e)
{
if (e.DisplayInfo.Orientation == DisplayOrientation.Landscape)
{
// if (this.Content.GetType() is not typeof(HomePageLandscape))
// {
this.Content = homePageLandscapeContentView;
// }
}
else if (e.DisplayInfo.Orientation == DisplayOrientation.Portrait)
{
// if (this.Content.GetType() is not typeof(HomePagePortrait))
// {
this.Content = homePagePortraitContentView;
// }
}
else
{
//Whatever you would like to do if the orientation is unknown.
}
}
}
HomePageOrientationViewLoader.xaml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScoreKeepersBoard.ContentViews.HomePageOrientationViewLoader">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI!"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
這是 HomePagePortrait.xaml.cs 文件:
namespace ScoreKeepersBoard.ContentViews;
public partial class HomePagePortrait : ContentView
{
public HomePagePortrait()
{
InitializeComponent();
}
}
這是 HomePagePortrait.xaml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScoreKeepersBoard.ContentViews.HomePagePortrait">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI portrait"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
這是 HomePageLandscape.xaml.cs 文件:
namespace ScoreKeepersBoard.ContentViews;
public partial class HomePageLandscape : ContentView
{
public HomePageLandscape()
{
InitializeComponent();
}
}
這是 HomePageLandscape.xaml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ScoreKeepersBoard.ContentViews.HomePageLandscape">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI landscape"
VerticalOptions="Center"
HorizontalOptions="Center" />
</VerticalStackLayout>
</ContentView>
我的項目有一個名為 HomePage 的初始主頁內容頁面。 我們正在將 HomePageOrientationViewLoader ContentView 作為自定義控件加載到 HomePage Content Page 的 xaml 中。 請注意,我必須定義 ContentView 所在的命名空間,並在 xaml 文件中定義控件時使用它:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:ScoreKeepersBoard.ContentViews"
x:Class="ScoreKeepersBoard.Views.HomePage"
Title="HomePage">
<VerticalStackLayout>
<Label
Text="Welcome to .NET MAUI Home Page Content Page"
VerticalOptions="Center"
HorizontalOptions="Center" />
<controls:HomePageOrientationViewLoader></controls:HomePageOrientationViewLoader>
</VerticalStackLayout>
</ContentPage>
這是主頁背后的代碼
namespace ScoreKeepersBoard.Views;
public partial class HomePage : ContentPage
{
public HomePage(HomeViewModel homeViewModel)
{
InitializeComponent();
}
}
當項目以縱向模式在我的 iphone 模擬器上運行時:
您將看到顯示的第二個 label 顯示“歡迎使用 .NET MAUI 肖像”,這是肖像內容視圖的視圖,當我切換到風景時:
您將看到顯示的第二個 label 顯示“歡迎使用 .NET MAUI 橫向”,這是橫向內容視圖中的視圖。
問題
這適用於我的 iPhone 模擬器,但是當我切換到我的 Android 像素 5 模擬器並切換我的切換手機方向時,它不起作用並且插入換行符,不會觸發 HomePageOrientationViewLoader 中定義的代碼。 新注意事項:我在 Android 實體手機上試過這個,它正在工作,所以它一定是模擬器。
我需要將它用於一個非平凡的示例,該示例的視圖 model 將保存體育比賽得分、計時等數據。我想我只需要將視圖 model 的 singleton 注入每個視圖,它們將只是分享,如果方向切換,其他內容視圖將加載,視圖 model 將綁定到適當的控件?
FreakyAli 最初建議的代碼有這個檢查:
if (e.DisplayInfo.Orientation == DisplayOrientation.Landscape) { if (this.Content.GetType() is not typeof(HomePageLandscape)) { this.Content = homePageLandscapeContentView; } }
但是“typeof(HomePageLandscape)”部分給我一個錯誤,並說需要一個常數。
除此之外,不同方向的不同視圖正在工作,我非常感謝 FreakyAli,我相信我會弄清楚為什么 Android 模擬器沒有觸發方向切換代碼。 但建議會很棒。
理想情況下,這就是我處理這種情況的方式:
在我的構造函數中,我會得到 DisplayInfoChanged 事件,如果此信息發生變化,它會通知我,我還會根據當前方向分配我當前的 ContentView:
DeviceDisplay.Current.MainDisplayInfoChanged += Current_MainDisplayInfoChanged;
this.Content = DeviceDisplay.Current.MainDisplayInfo.Orientation == DisplayOrientation.Portrait ? potraitView : landscapeView;
這里的 PortraitView 是一個 ContentView,它是當我的設備處於縱向和反之亦然時我將顯示的視圖。
然后按如下方式處理方向的運行時變化:
private void Current_MainDisplayInfoChanged(object sender, DisplayInfoChangedEventArgs e)
{
if(e.DisplayInfo.Orientation==DisplayOrientation.Landscape)
{
if(this.Content.GetType() is not typeof(LandscapeView))
{
this.Content = landscapeView;
}
}
else if (e.DisplayInfo.Orientation == DisplayOrientation.Portrait)
{
if (this.Content.GetType() is not typeof(PortraitView))
{
this.Content = portraitView;
}
}
else
{
//Whatever you would like to do if the orientation is unknown.
}
}
希望這對你有幫助!
執行此操作的正確方法是通過 ContentViews,其中您有 2 個 ContentView,一個用於縱向,一個用於橫向。 您有另一個 ContentView,用於根據方向選擇橫向或縱向加載。 我創建了一個教程,將所有部分放在一起: https://codeshadowhand.com.net-maui-different-layouts-for-portrait-vs-landscape/ 非常感謝 FreakyAli 為我指明了正確的方向!! !
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.