首页 > 其他分享 >MAUI新生5.3-Layout布局类控件难点

MAUI新生5.3-Layout布局类控件难点

时间:2022-12-24 21:46:51浏览次数:61  
标签:控件 5.3 Layout 布局 FlexLayout 对齐 方向 元素

一、布局控件目录 

  • Grid,网格布局。子元素按行列布局,类似于在Word里画表格
  • FlexLayout,弹性布局。和前端的Flex弹性布局基本一样
  • StackLayout,堆叠布局。子元素按指定方向逐行(列)堆叠。如果能确定堆叠方向,建议使用横向或纵向堆叠布局
  • HorizontalStackLayout,横向堆叠布局。子元素在水平方向上逐列堆叠,性能比StackLayout好。
  • VerticalStackLayout,纵向堆叠布局。子元素在垂直方向上逐行堆叠,性能比StackLayout好。
  • AbsouteLayout,绝对布局。可以定义子元素的绝对位置
  • DockLayout,停靠式布局。子元素可以固定停靠在上下左右位置。DockPanel是WPF的内置控件,但MAUI给取消了,【Community.Toolkit.Maui】补充了这个控件
  • UniformItemsLayout,大小一致的网格布局。子元素按行列布局,且单元格大小一致。和DockPanel,UniformGrid本也是WPF的内置控件,但MAUI给取消了,【Community.Toolkit.Maui】中补充了这个控件
  • BindableLayout,绑定布局。作为附加属性应用于其它布局,功能上类似于集合类控件,适用于条目数较少、无滚动、无选择的情况
  • StateContainer,状态容器。作为附加属性应用于其它布局,根据用户定义的状态数值,显示不同的元素块,由【Community.Toolkit.Maui】提供

 

 

 

二、布局实操经验

  • 根据实际情况和个人偏好,选用Grid或FlexLayout进行整体布局。推荐使用Grid,但习惯前段Flex布局的,可能更喜欢FlexLayout。
  • 局部布局,根据需要首选HorizontalStackLayout、VerticalStackLayout或AbsouteLayout,复杂一些的可以用FlexLayout。只有在运行时需要改变排列方向时,才选用StackLayout。
  • MAUI取消了DockLayout和UniformItemsLayout,总有其原因,Grid和FlexLayout吃透了,应该很少会用到。
  • BindableLayout和StateContainer,是附加属性,Grid、StackLayout、FlexLayout等布局控件都可以使用,提供的功能还是很实用,建议掌握。
  • 重点讲三个控件:FlexLayout、BindableLayout、StateContainer。其它可查看文档。

 

 

 

三、FlexLayout弹性布局

1、FlexLayout弹性布局,和前端的Flex弹性布局,几乎一样。FlexLayout是容器,可以定义Direction/主轴方向、Wrap/子元素在主轴方向上是否换行/列、JustityContent/AlignItems/AlignContent子元素整体对齐方式。同时,在子元素上可以通过附加属性,定义子元素的个体行为,如Order,定义子元素排列顺序;Basis/Grow/Shrink,定义子元素主轴方向的尺寸形为;AlighSeft,定义子元素在交叉轴方向的对齐行为。

 

 2、使用FlexLayout布局时的经验

  • 确定子元素排列的主轴方向Direction,Row-由左至右水平排列(默认值),Column-由上至下垂直排列,或者RowReverse-由右至左水平排列、ColumnReverse-由下至上垂直排列
  • 确定子元素在主轴方向上是否换行Wrap,NoWrap-不换行(默认值)、Wrap-换行、Reverse-反方向换行
  • 确定子元素整体在主轴和交叉轴上的对齐方式,JustifyContent-主轴方向上的对齐方式、AlignItems-NoWap时交叉轴方向上的对齐方式、AlignContent-Wap时交叉轴方向上的对齐方式
  • 确定子元素个体在主轴和交叉轴上的排列顺序、缩放和对齐行为,Order-排列顺序、Basis/Grow/Shrink-NoWap时主轴方向上的尺寸和缩放、AlignSeft-NoWap时交叉轴方向上的对齐
  • 如下图所示:

 

3、使用FlexLayout完成圣杯布局 

<ContentPage
    x:Class="MauiApp12.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    BackgroundColor="{DynamicResource PageBackgroundColor}">

    <!--  外层FlexLayout,主轴为Column,自上而下垂直排列,分为三行,不换行  -->
    <!--  JustifyContent主轴-垂直方向的对齐方式为Start,AlignItems交叉轴-水平方向对齐方式为Stretch/自动扩展  -->
    <FlexLayout
        AlignItems="Stretch"
        Direction="Column"
        JustifyContent="Start"
        Wrap="NoWrap">
        <Label
            BackgroundColor="Red"
            HorizontalTextAlignment="Center"
            Text="Header" />
        <!--内层FlexLayout,作为外层FlexLayout的子元素,附加属性FlexLayout.Grow为1,在交叉轴-水平方向上填满剩余空间-->
        <!--内层FlexLayout,主轴方向为Row,自左向右水平排列,不换行-->
        <FlexLayout
            Direction="Row"
            FlexLayout.Grow="1"
            Wrap="NoWrap">
            <!--内层FlexLayout的子元素,BoxView设置附加属性FlexLayout.Basis,主轴方向的基础尺寸为50-->
            <BoxView FlexLayout.Basis="50" Color="Yellow" />
            <!--内层FlexLayout的子元素,Lable设置附加属性FlexLayout.Grow,主轴方向上扩展填满剩余空间-->
            <Label
                BackgroundColor="Green"
                FlexLayout.Grow="1"
                Text="Content" />
            <BoxView FlexLayout.Basis="50" Color="Yellow" />
        </FlexLayout>
        <Label
            BackgroundColor="Gray"
            HorizontalTextAlignment="Center"
            Text="Footer" />
    </FlexLayout>
</ContentPage>

 

  

 

 

四、绑定布局BindableLayout,以附加属性的形式,在宿主布局容器内,实现一个集合展示。实现的功能,与ListView或CollectionView类似,在条目数较少、无滚动、无选择按钮情况时,可以使用BindableLayout。

1、定义一个ViewModel,作为数据源 

//直接New一个Employee集合
//ImageSource为Resources/Images目录下的图像
public partial class MainPageViewModel: ObservableObject
{
    [ObservableProperty]
    private List<Employee> employees = new List<Employee>
    {
        new Employee{Name = "HeLiu",ImageSource="he_liu.png"},
        new Employee{Name = "HaiShang",ImageSource="hai_shang.png"},
        new Employee{Name = "LuoRi",ImageSource="luo_ri.png"},
        new Employee{Name = "GongYuan",ImageSource="gong_yuan.png"},
    };
}

  

2、使用BindableLayout 

<ContentPage
    x:Class="MauiApp12.MainPage"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:vm="clr-namespace:MauiApp12.ViewModels">

    <!--直接创建ViewModel对象,并设置为页面的BindingContext-->
    <ContentPage.BindingContext>
        <vm:MainPageViewModel />
    </ContentPage.BindingContext>
    
    <!--BindableLayout.ItemsSource,数据源-->
    <!--BindableLayout.ItemTemplate,数据模板-->
    <!--BindableLayout.EmptyView,无数据时显示的文字提示-->
    <!--BindableLayout.EmptyView,还支持定义复杂的外观-->
    <!--BindableLayout.ItemTemplateSelector,相当于迭代中的if,详见数据模板的DataTemplateSelector-->
    <StackLayout
        BindableLayout.EmptyView="无数据"
        BindableLayout.ItemsSource="{Binding Employees}"
        Orientation="Horizontal">
        <BindableLayout.ItemTemplate>
            <DataTemplate>
                <Image
                    Aspect="AspectFill"
                    HeightRequest="44"
                    Source="{Binding ImageSource}"
                    WidthRequest="44" />
            </DataTemplate>
        </BindableLayout.ItemTemplate>
        <!--<BindableLayout.EmptyView>
            <Label Text="数据为空时显示的外观"/>
        </BindableLayout.EmptyView>-->
    </StackLayout>
</ContentPage>

 

 

  

 

五、状态容器StateContainer,以附加属性的形式,在宿主布局容器内,根据不同的状态条件,显示不同的外观。

1、安装Nuget包,Community.Toolkit.Maui,并在入口文件MauiProgram.cs文件中设置【builder.UseMauiApp<App>().UseMauiCommunityToolkit()】

2、定义一个ViewModel,作为数据源

public partial class MainPageViewModel: ObservableObject
{
    [ObservableProperty]
    private string myCurrentState;

    [RelayCommand]
    private void ChangeMyCurrentStateLoading()
    {
        MyCurrentState = "Loading";
    }

    [RelayCommand]
    private void ChangeMyCurrentStateSuccess()
    {
        MyCurrentState = "Success";
    }

    [RelayCommand]
    private void ChangeMyCurrentStateEmpty()
    {
        MyCurrentState = "";
    }
}

 

3、使用StateContainer

<ContentPage
    ......
    xmlns:tk="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
    xmlns:vm="clr-namespace:MauiApp12.ViewModels">

    <!--  直接创建ViewModel对象,并设置为页面的BindingContext  -->
    <ContentPage.BindingContext>
        <vm:MainPageViewModel />
    </ContentPage.BindingContext>

    <VerticalStackLayout>
        <!--tk:StateContainer.CurrentState的值和tk:StateView.StateKey匹配-->
        <VerticalStackLayout tk:StateContainer.CurrentState="{Binding MyCurrentState}">
            <tk:StateContainer.StateViews>
                <!--tk:StateContainer.CurrentState的值为Loading时,显示如下内容-->
                <VerticalStackLayout tk:StateView.StateKey="Loading">
                    <ActivityIndicator IsRunning="True" />
                    <Label Text="加载中..." />
                </VerticalStackLayout>
                <!--tk:StateContainer.CurrentState的值为Success时,显示如下内容-->
                <Label tk:StateView.StateKey="Success" Text="Success!" />
            </tk:StateContainer.StateViews>
            <!--tk:StateContainer.CurrentState的值为Null或空字符串时默认显示的内容-->
            <Label Text="默认内容" />
        </VerticalStackLayout>

<!--按钮更改MyCurrentState值--> <Button Command="{Binding ChangeMyCurrentStateLoadingCommand}" Text="Loading" /> <Button Command="{Binding ChangeMyCurrentStateSuccessCommand}" Text="Success" /> <Button Command="{Binding ChangeMyCurrentStateEmptyCommand}" Text="Empty" /> </VerticalStackLayout> </ContentPage>

 

标签:控件,5.3,Layout,布局,FlexLayout,对齐,方向,元素
From: https://www.cnblogs.com/functionMC/p/17001254.html

相关文章