【MAUI】CollectionView横屏竖屏布局内容切换
效果
正文
设置方向控制
因为我演示的是Android所以我这里以Android为例子。
找到 Platforms/Android/MainActivity.cs
文件,添加枚举ScreenOrientation = ScreenOrientation.Sensor,这个选项是应用程序的方向由传感器确认。
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true,ScreenOrientation = ScreenOrientation.Sensor ,ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
页面
<?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" x:Class="MauiCollectionViewChangeScreenExample.MainPage"> <StackLayout Spacing="10" x:Name="baseStack" Orientation="Horizontal" HorizontalOptions="Center"> <CollectionView ItemsSource="{Binding ListData}" x:Name="collectionView" HorizontalScrollBarVisibility="Never" VerticalScrollBarVisibility="Never" > <CollectionView.ItemTemplate> <DataTemplate> <StackLayout Orientation="Horizontal" Padding="0"> <Border Stroke="White" StrokeThickness="0.5" WidthRequest="275"> <Grid Margin="5"> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition Height="25"/> </Grid.RowDefinitions> <Image Source="{Binding ImagePath}" ></Image> <Label Grid.Row="1" TextColor="Black" FontSize="15" Text="{Binding Name}" FontAttributes="Bold" Margin="5,5,0,0"></Label> </Grid> </Border> </StackLayout> </DataTemplate> </CollectionView.ItemTemplate> </CollectionView> </StackLayout> </ContentPage>
逻辑代码
public partial class MainPage : ContentPage { public MainPage() { InitializeComponent(); var list = new List<ViewListData>(); list.Add(new ViewListData { Name = ".NET5", ImagePath = "dotnet_bot" }); list.Add(new ViewListData { Name = ".NET6", ImagePath = "dotnet_bot" }); list.Add(new ViewListData { Name = ".NET7", ImagePath = "dotnet_bot" }); list.Add(new ViewListData { Name = ".NET8", ImagePath = "dotnet_bot" }); list.Add(new ViewListData { Name = ".NET9", ImagePath = "dotnet_bot" }); this.ListData = new ObservableCollection<ViewListData>(list); BindingContext = this; } public ObservableCollection<ViewListData> ListData { get; set; } private double width = 0; private double height = 0; /// <summary> /// 监听变化 /// </summary> /// <param name="width"></param> /// <param name="height"></param> protected override void OnSizeAllocated(double width, double height) { base.OnSizeAllocated(width, height); if (this.width != width || this.height != height) { this.width = width; this.height = height; Console.WriteLine("screen width " + width); Console.WriteLine("screen height " + height); // Get Metrics var mainDisplayInfo = DeviceDisplay.MainDisplayInfo; //Portrait 竖屏 Landscape 横屏 var orientation = mainDisplayInfo.Orientation; if (orientation == DisplayOrientation.Portrait) { collectionView.ItemsLayout = null; } else if (orientation == DisplayOrientation.Landscape) { //横屏每行显示三个 collectionView.ItemsLayout = new GridItemsLayout(3, ItemsLayoutOrientation.Vertical); } } } }
请注意, OnSizeAllocated
当设备旋转时,可以多次调用该方法。 每次更改布局都会浪费资源,并可能导致闪烁,所以记录宽高,避免重复布局浪费资源。
public class ViewListData { public string Name { get; set; } public string ImagePath { get; set; } }
参考资料
https://learn.microsoft.com/zh-cn/xamarin/xamarin-forms/user-interface/layouts/device-orientation?tabs=windows
https://learn.microsoft.com/zh-cn/dotnet/maui/user-interface/controls/collectionview/layout?view=net-maui-7.0