.NET MAUI 从入门到精通:构建跨平台原生应用的终极指南

摘要:随着移动和桌面应用开发需求的日益增长,跨平台框架成为了开发者提升效率、降低维护成本的首选。.NET Multi-platform App UI(.NET MAUI)作为 Xamarin.Forms 的继任者,是微软官方推出的统一跨平台应用开发框架,允许开发者使用 C# 和 XAML 编写一次代码,即可部署到 Android、iOS、macOS 和 Windows 四大平台。本教程将带你从零开始,深入浅出地掌握 .NET MAUI 的核心概念、开发技巧和高级特性,助你快速构建现代化、高性能的跨平台原生应用。


第一章:初识 .NET MAUI

1.1 什么是 .NET MAUI?

.NET MAUI 是一个开源的跨平台应用 UI 框架,它建立在 .NET 6 及更高版本之上。其核心思想是“一次编写,多处运行”(Write Once, Run Anywhere),但这里的“运行”并非简单的解释执行,而是通过 AOT(Ahead-of-Time)编译或 JIT(Just-in-Time)编译,生成针对每个平台高度优化的原生应用。

与传统的混合应用(如 Cordova、Ionic)不同,.NET MAUI 应用拥有:

  • 真正的原生性能:直接调用各平台的原生 UI 控件和 API。
  • 统一的开发体验:使用熟悉的 C# 语言和 XAML 标记语言进行开发。
  • 共享的业务逻辑:高达 95% 以上的代码可以在多个平台间共享。
  • 现代化的设计:内置对 Material Design (Android) 和 Cupertino (iOS) 等设计规范的支持。
1.2 .NET MAUI 与 Xamarin.Forms 的关系

你可以将 .NET MAUI 理解为 Xamarin.Forms 的“进化版”和“整合版”。Xamarin.Forms 在过去几年取得了巨大成功,但其架构存在一些历史包袱。.NET MAUI 在继承其优点的同时,进行了以下重大改进:

  • 统一的 .NET 平台:不再需要单独安装 Xamarin SDK,它已成为 .NET SDK 的一部分。
  • 简化项目结构:告别复杂的多项目模板(Shared Project / PCL),现在只有一个单一的 .csproj 文件。
  • 性能大幅提升:通过减少抽象层、优化渲染管道等方式,启动速度和内存占用得到显著改善。
  • 更丰富的内置功能:将许多曾经需要通过社区插件(如 Essentials)实现的功能(如文件系统、网络、传感器等)直接集成到框架中。

简而言之,.NET MAUI = Xamarin.Forms + .NET 6+ + 性能优化 + 功能增强 + 项目简化

1.3 开发环境准备

要开始 .NET MAUI 开发,你需要安装以下工具:

  1. Visual Studio 2022 (17.3 或更高版本)

    • 推荐使用 Community(社区版),它是免费的。
    • 在安装时,务必勾选 “.NET Multi-platform App UI development” 工作负载。这个工作负载会自动包含 Android SDK、iOS 开发工具(需 macOS)、.NET MAUI 工作负载以及必要的模拟器/仿真器。
  2. (可选) Visual Studio Code

    • 如果你更喜欢轻量级编辑器,也可以使用 VS Code 配合 .NET CLI 进行开发,但对于 UI 调试和模拟器管理,VS 2022 仍然是首选。
  3. (仅限 iOS/macOS 开发)

    • 你需要一台运行 macOS Monterey (12.0) 或更高版本 的 Mac 电脑。
    • 在 Mac 上安装 Xcode 14.0 或更高版本
    • Visual Studio 2022 for Windows 可以通过网络连接到 Mac 来进行 iOS 应用的编译和调试。

安装完成后,重启你的电脑,确保所有环境变量生效。


第二章:Hello, .NET MAUI! —— 第一个应用

2.1 创建新项目

打开 Visual Studio 2022,选择 “创建新项目”

  1. 在搜索框中输入 “maui”
  2. 选择 “.NET MAUI App (Preview)” 模板(注意:虽然标记为 Preview,但在 .NET 8 中已是正式版)。
  3. 点击 “下一步”
  4. 配置项目名称(如 MyFirstMauiApp)、位置和解决方案名称。
  5. 点击 “创建”

Visual Studio 将为你生成一个标准的 .NET MAUI 项目结构。

2.2 项目结构解析

打开解决方案资源管理器,你会看到一个非常简洁的项目结构:

MyFirstMauiApp/
├── Platforms/          # 平台特定代码
│   ├── Android/
│   ├── iOS/
│   ├── MacCatalyst/
│   └── Windows/
├── Resources/          # 共享资源
│   ├── AppIcon/        # 应用图标
│   ├── Images/         # 图片资源
│   ├── Raw/            # 原始文件(如字体)
│   └── Styles/         # 样式文件
├── App.xaml            # 应用级别的 XAML
├── App.xaml.cs         # 应用级别的 C# 代码
├── MainPage.xaml       # 主页面 XAML
└── MainPage.xaml.cs    # 主页面 C# 代码
  • Platforms 文件夹:这是 .NET MAUI 实现跨平台的关键。每个子文件夹都包含了针对特定平台的入口点、配置文件和可以放置平台专属代码的地方。例如,Platforms/Android/MainActivity.cs 是 Android 应用的主 Activity。
  • Resources 文件夹:存放所有平台共享的资源,如图片、字体、样式等。.NET MAUI 会根据目标平台自动处理这些资源的适配。
  • App.xaml:定义了整个应用的全局资源、样式和启动页面。
  • MainPage.xaml:这是应用启动后显示的第一个页面。
2.3 代码剖析:MainPage.xaml

让我们看看默认生成的 MainPage.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"
             x:Class="MyFirstMauiApp.MainPage">

    <ScrollView>
        <VerticalStackLayout
            Padding="30,0"
            Spacing="25">
            <Image
                Source="dotnet_bot.png"
                HeightRequest="185" />

            <Label
                Text="Hello, World!"
                Style="{StaticResource Headline}"
                SemanticProperties.HeadingLevel="Level1" />

            <!-- ... 更多控件 ... -->

        </VerticalStackLayout>
    </ScrollView>

</ContentPage>
  • 根元素 <ContentPage>:代表一个页面。所有页面内容都必须放在一个容器内。
  • <ScrollView>:一个可滚动的容器,当内容超出屏幕时,用户可以滑动查看。
  • <VerticalStackLayout>:一个垂直堆叠布局容器,其子元素会从上到下依次排列。
  • <Image><Label>:基础的 UI 控件,分别用于显示图片和文本。
2.4 运行你的应用

在 Visual Studio 顶部的工具栏中,选择一个目标平台和设备(如 Android EmulatorWindows Machine),然后点击 “启动” 按钮(绿色三角形)。

Visual Studio 会编译你的代码,并在选定的模拟器或设备上启动应用。恭喜你,你已经成功运行了第一个 .NET MA UI 应用!


第三章:核心概念与 UI 构建

3.1 XAML 与 C# 的协同工作

.NET MAUI 的 UI 主要通过 XAML (eXtensible Application Markup Language) 来声明。XAML 是一种基于 XML 的语言,它让 UI 的结构和布局变得直观易读。

每个 XAML 文件都有一个对应的 Code-behind 文件(.xaml.cs),用于处理逻辑、事件和数据绑定。

  • x:Class 属性:在 XAML 根元素中指定,它将 XAML 文件与 Code-behind 类关联起来。
  • x:Name 属性:为 XAML 中的控件指定一个名称,这样就可以在 C# 代码中直接引用它。

示例
MainPage.xaml 中添加一个按钮:

<Button x:Name="myButton" Text="Click Me!" Clicked="OnButtonClicked" />

MainPage.xaml.cs 中处理点击事件:

private void OnButtonClicked(object sender, EventArgs e)
{
    // 处理按钮点击逻辑
    myButton.Text = "Clicked!";
}
3.2 常用布局容器

合理的布局是良好用户体验的基础。.NET MAUI 提供了多种布局容器:

  • VerticalStackLayout / HorizontalStackLayout:最常用的线性布局,子元素按垂直或水平方向排列。
  • Grid:强大的网格布局,通过行(Row)和列(Column)来精确定位子元素。非常适合构建复杂的表单或仪表盘。
  • FlexLayout:灵感来源于 CSS Flexbox,提供了灵活的、响应式的布局能力。
  • AbsoluteLayout:允许你通过绝对坐标来放置子元素,通常用于需要精确控制位置的场景(如游戏)。
3.3 基础控件概览

.NET MAUI 提供了一套丰富的跨平台 UI 控件:

  • Label: 显示只读文本。
  • Button: 触发操作的按钮。
  • Entry: 单行文本输入框。
  • Editor: 多行文本输入框。
  • Image: 显示图片。
  • CollectionView: 高性能的列表/网格视图,用于展示大量数据。
  • Shell: 一个强大的应用容器,内置了导航、底部标签栏、侧边栏抽屉等功能,可以极大地简化应用的整体架构。

第四章:深入数据驱动与 MVVM 模式

现代应用开发的核心是 数据驱动。.NET MAUI 通过 数据绑定 (Data Binding)MVVM (Model-View-ViewModel) 模式来实现这一目标。

4.1 什么是 MVVM?

MVVM 是一种软件架构模式,旨在分离 UI(View)和业务逻辑(ViewModel),并通过数据模型(Model)进行通信。

  • Model: 代表应用的数据和业务逻辑。
  • View: 用户界面,负责展示数据和接收用户输入。
  • ViewModel: View 和 Model 之间的桥梁。它暴露公共属性和命令供 View 绑定,并处理来自 View 的交互,最终更新 Model。

这种分离使得代码更易于测试、维护和重用。

4.2 实现数据绑定

数据绑定允许 View 自动反映 ViewModel 中数据的变化。

步骤

  1. 创建 ViewModel:

    public class MainViewModel : INotifyPropertyChanged
    {
        private string _message = "Hello from ViewModel!";
        public string Message
        {
            get => _message;
            set
            {
                _message = value;
                OnPropertyChanged();
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
  2. 在 View 中设置 BindingContext:
    MainPage.xaml.cs 的构造函数中:

    public MainPage()
    {
        InitializeComponent();
        BindingContext = new MainViewModel();
    }
    
  3. 在 XAML 中绑定数据:

    <Label Text="{Binding Message}" />
    

现在,当你在 ViewModel 中更改 Message 属性时,界面上的 Label 会自动更新。

4.3 使用命令 (Commands)

为了处理用户交互(如按钮点击),MVVM 使用 ICommand 接口。

public class MainViewModel : INotifyPropertyChanged
{
    // ... 其他代码 ...

    public ICommand UpdateMessageCommand { get; }

    public MainViewModel()
    {
        UpdateMessageCommand = new Command(() =>
        {
            Message = $"Updated at {DateTime.Now:T}";
        });
    }
}

在 XAML 中绑定命令:

<Button Text="Update Message" Command="{Binding UpdateMessageCommand}" />

第五章:访问平台功能与依赖注入

虽然 .NET MAUI 提供了统一的 API,但有时我们仍需要访问某个平台独有的功能(如 Android 的 Toast,iOS 的 FaceID)。同时,为了更好地组织代码和实现解耦,我们会用到依赖注入。

5.1 使用 .NET MAUI Essentials

.NET MAUI 内置了 Microsoft.Maui.Essentials,它提供了一系列跨平台的 API,用于访问设备功能,如:

  • 地理位置 (Geolocation)
  • 加速计 (Accelerometer)
  • 电池状态 (Battery)
  • 文件系统 (FileSystem)
  • 启动浏览器 (Launcher)

示例:获取电池电量

var batteryLevel = Battery.ChargeLevel; // 返回 0.0 到 1.0 之间的值
5.2 平台特定代码 (Platform-Specific Code)

对于 Essentials 未覆盖的功能,你需要编写平台特定代码。

  1. 定义共享接口:
    在共享项目中创建一个接口:

    public interface IToastService
    {
        void Show(string message);
    }
    
  2. 在 Platforms 文件夹中实现:

    • Android (Platforms/Android/Services/ToastService.cs):
      using Android.Widget;
      using MyFirstMauiApp.Services;
      using Microsoft.Maui.ApplicationModel;
      
      namespace MyFirstMauiApp.Platforms.Android.Services
      {
          public class ToastService : IToastService
          {
              public void Show(string message)
              {
                  Toast.MakeText(Application.Context, message, ToastLength.Short).Show();
              }
          }
      }
      
    • iOS (Platforms/iOS/Services/ToastService.cs): (需要第三方库或自定义实现)
  3. 注册依赖服务:
    MauiProgram.cs 中使用依赖注入容器注册服务:

    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });
    
            // 注册平台特定服务
            #if ANDROID
            builder.Services.AddSingleton<IToastService, Platforms.Android.Services.ToastService>();
            #elif IOS
            builder.Services.AddSingleton<IToastService, Platforms.iOS.Services.ToastService>();
            #endif
    
            return builder.Build();
        }
    }
    
  4. 在 ViewModel 中使用:

    public class MainViewModel
    {
        private readonly IToastService _toastService;
    
        public MainViewModel(IToastService toastService)
        {
            _toastService = toastService;
        }
    
        public ICommand ShowToastCommand => new Command(() => _toastService.Show("Hello from DI!"));
    }
    

第六章:美化你的应用 —— 样式与主题

一个美观的应用离不开精心的设计。.NET MAUI 提供了强大的样式和主题系统。

6.1 使用内置样式

.NET MAUI 内置了许多预定义的样式,如 Headline, Subtitle, Body 等。你可以在 Resources/Styles/Colors.xamlResources/Styles/Styles.xaml 中找到它们。

<Label Text="This is a headline" Style="{StaticResource Headline}" />
6.2 创建自定义样式

你可以在 Styles.xaml 中定义自己的样式:

<!-- 定义一个名为 "MyCustomButtonStyle" 的样式 -->
<Style TargetType="Button" x:Key="MyCustomButtonStyle">
    <Setter Property="BackgroundColor" Value="LightBlue" />
    <Setter Property="TextColor" Value="Black" />
    <Setter Property="CornerRadius" Value="10" />
</Style>

然后在 XAML 中应用:

<Button Text="Styled Button" Style="{StaticResource MyCustomButtonStyle}" />
6.3 应用主题

.NET MAUI 支持 Light/Dark 主题。你可以在 App.xaml 中定义两种主题下的颜色:

<Application.Resources>
    <ResourceDictionary>
        <!-- Light Theme Colors -->
        <Color x:Key="PrimaryColor">#512BD4</Color>
        <!-- Dark Theme Colors -->
        <Color x:Key="DarkPrimaryColor">#BF36FF</Color>
    </ResourceDictionary>
</Application.Resources>

框架会根据系统主题自动切换。你也可以通过代码强制设置主题:

Application.Current.UserAppTheme = AppTheme.Dark;

第七章:发布你的应用

开发完成只是第一步,将应用分发给用户才是最终目标。

7.1 Android 打包 (APK/AAB)
  1. 创建 Keystore:
    如前所述,使用 keytool 创建签名密钥。

    keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
    
  2. 配置项目文件:
    .csproj 文件中添加 Release 配置:

    <PropertyGroup Condition="'$(Configuration)' == 'Release'">
        <AndroidKeyStore>true</AndroidKeyStore>
        <AndroidSigningKeyStore>my-release-key.keystore</AndroidSigningKeyStore>
        <AndroidSigningStorePass>your-store-password</AndroidSigningStorePass>
        <AndroidSigningKeyAlias>my-key-alias</AndroidSigningKeyAlias>
        <AndroidSigningKeyPass>your-key-password</AndroidSigningKeyPass>
        <!-- 生成 AAB (推荐用于 Google Play) -->
        <AndroidPackageFormat>aab</AndroidPackageFormat>
    </PropertyGroup>
    
  3. 发布:
    在 Visual Studio 中,将配置切换为 Release,然后选择 “生成” -> “发布” -> “发布解决方案”

    • APK 路径: bin\Release\net8.0-android\android-arm64\publish\YourApp-Signed.apk
    • AAB 路径: bin\Release\net8.0-android\android-arm64\publish\YourApp.aab
  4. 上传到 Google Play Console

7.2 Windows 打包 (MSIX)

对于 Windows 应用,.NET MAUI 默认会生成一个可安装的 MSIX 包。

  1. 在解决方案资源管理器中,右键点击你的项目,选择 “发布” -> “创建应用包...”
  2. 按照向导选择 “Sideloading”(旁加载)或 “Microsoft Store”
  3. 完成向导后,会在 bin\Release\net8.0-windows10.0.19041.0\win10-x64\AppPackages 目录下生成 .msix 文件和安装脚本。

第八章:常见问题与最佳实践

8.1 性能优化
  • 避免在 OnAppearing 中做耗时操作:这会阻塞 UI 线程。使用 async/await 或后台任务。
  • 合理使用 CollectionView:它比旧的 ListView 性能更好。
  • 启用 AOT 编译(Android):可以在项目文件中设置 <RunAOTCompilation>true</RunAOTCompilation> 来进一步提升启动速度和运行性能(会增加包体积和编译时间)。
8.2 调试技巧
  • Hot Reload:.NET MAUI 支持 XAML 和部分 C# 代码的热重载,让你在不重启应用的情况下即时查看 UI 变化。
  • 使用 Debug.WriteLine:在输出窗口查看调试信息。
  • 检查设备日志:对于 Android,可以使用 adb logcat;对于 iOS,可以在 Xcode 的设备日志中查看。
8.3 社区与资源

结语

.NET MAUI 代表了微软在跨平台应用开发领域的最新成果,它不仅继承了 Xamarin.Forms 的强大基因,更在性能、易用性和功能丰富度上实现了质的飞跃。通过本教程的学习,你应该已经掌握了 .NET MAUI 开发的核心技能。现在,是时候动手实践,将你的创意转化为现实中的跨平台应用了!记住,最好的学习方式就是不断地编码、调试和优化。祝你在 .NET MAUI 的世界里探索愉快!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

君莫笑2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值