我們知道 MAUI 是開發跨平臺應用的解決方案 ,用 C# 可以直接把 iOS , Android , Windows , macOS , Linux ,Tizen 等應用開發出來。那我們在這個框架除了用底層自定義的 UI 控件外,如果我們要用如高德地圖這樣的第三方控件,要如何做呢?接下來我就和大家介紹一下。
如果你還沒有學習原生庫綁定的知識,可以到以下鏈接學習相關內容:
CA周記 - 跟我做?個?德地圖的 iOS / Android MAUI控件(iOS 原生庫綁定)
CA周記 - 跟我做?個?德地圖的 iOS / Android MAUI控件(Android 原?庫綁定)
在上面兩個例子中我們學習到把原生高德的 iOS / Android SDK 綁定,也用 .NET for iOS 和 .NET for Android 進行了調用。但要用 MAUI 就意味著調用方式改變, 一次性編寫多平臺使用。要實現這個效果,先看看 MAUI 的基礎架構。
我們可以清楚看到, MAUI 除了公用的 xmal 文件外, 實際上也把特定平臺的一些設定放置到 Platforms 的文件夾內, Platforms 的自文件夾就是對應的平臺。我們知道可以根據不同平臺去渲染平臺界面。這就是我們常說的自定義平臺控件了。
在前言部分我們也提到了 MAUI 采用 Handler 模式去設定平臺界面。如果我們要實現一個高德地圖的 MAUI 控件,具體的架構是這樣的:
我們需要去創建如上圖的一個結構,我們需要為 AMap 添加一個共享文件 AMap.shared.cs ,這個文件 AMapHandler 繼自 ViewHandler。
public interface IAMap : IView{}public class AMap : View, IAMap{}partial class AMapHandler{public static IPropertyMapper<AMap, AMapHandler> MapMapper = new PropertyMapper<AMap, AMapHandler>(ViewHandler.ViewMapper){ };public AMapHandler() : base(MapMapper){ }}
然后在 Platforms 下的 Android 和 iOS 文件夾添加各自的平臺 AMap 調用方法。
為 AMap.Android.cs 添加 Android 環境下高德地圖的渲染方式
namespace AMap.UI.Apps
{public partial class AMapHandler : ViewHandler<IAMap, MapView>{private AMapHelper _mapHelper;private MapView mapView;internal static Bundle Bundle { get; set; }public AMapHandler(IPropertyMapper mapper, CommandMapper commandMapper = null) : base(mapper, commandMapper){}protected override MapView CreatePlatformView(){mapView = new Com.Amap.Api.Maps.MapView(Context);return mapView;}protected override void ConnectHandler(MapView platformView){base.ConnectHandler(platformView);AMapLocationClient.UpdatePrivacyAgree(Context, true);AMapLocationClient.UpdatePrivacyShow(Context, true, true);_mapHelper = new AMapHelper(Bundle, platformView);mapView = _mapHelper.CallCreateMap();}}class AMapHelper : Java.Lang.Object{private Bundle _bundle;private MapView _mapView;public event EventHandler MapIsReady;public MapView Map { get; set; }public AMapHelper(Bundle bundle, MapView mapView){_bundle = bundle;_mapView = mapView;}public MapView CallCreateMap(){_mapView.OnCreate(_bundle);return _mapView;}}}
為 AMap.iOS.cs 添加 iOS 環境下高德地圖的渲染方式
amespace AMap.UI.Apps
{public partial class AMapHandler : ViewHandler<IAMap, MAMapView>
{public AMapHandler(IPropertyMapper mapper, CommandMapper commandMapper = null) : base(mapper, commandMapper){}protected override MAMapView CreatePlatformView(){MAMapView.UpdatePrivacyShow(AMapPrivacyShowStatus.DidShow, AMapPrivacyInfoStatus.DidContain);MAMapView.UpdatePrivacyAgree(AMapPrivacyAgreeStatus.DidAgree);AMapServices.SharedServices.ApiKey = "";AMapServices.SharedServices.EnableHTTPS = true;//try//{MAMapView map = new MAMapView();map.SetShowsUserLocation(true);map.SetUserTrackingMode(MAUserTrackingMode.Follow);return map;}protected override void ConnectHandler(MAMapView PlatformView){ }protected override void DisconnectHandler(MAMapView PlatformView){if (PlatformView.Delegate != null){PlatformView.Delegate.Dispose();PlatformView.Delegate = null;}PlatformView.RemoveFromSuperview();}}}
項???有 Transforms ?件夾有對應的三個 xml ?件,分別是 EnumFields.xml ,EnumMethods.xml , Metadata.xml , 各?作?如下 :
1.因為這個控件只是針對 iOS / Android 兩個平臺,所以我們只保留 net6.0-android 和 net6.0-ios
2.高德 SDK 運行建議在真機下使用,特別是 iOS ,需要制定版本號,還有編譯環境,我的環境是在 Apple silicon 下所以也要設定好 RuntimeIdentifier,還有就是編譯的時候,我花了特別多時間在這里,大家可以參考我這個在 GitHub 上自問自答的Issue?https://github.com/xamarin/xamarin-macios/issues/15372
<PropertyGroup Condition="$(TargetFramework.Contains('-ios'))"><RuntimeIdentifier>ios-arm64</RuntimeIdentifier><UseMSBuildEngine>true</UseMSBuildEngine><WarningLevel>4</WarningLevel><MtouchLink>SdkOnly</MtouchLink><SupportedOSPlatformVersion>13.0</SupportedOSPlatformVersion><DeviceSpecificBuild>true</DeviceSpecificBuild><MtouchDebug>true</MtouchDebug><MtouchFastDev>true</MtouchFastDev><MtouchProfiling>true</MtouchProfiling><MtouchUseSGen>true</MtouchUseSGen><MtouchUseRefCounting>true</MtouchUseRefCounting><MtouchFloat32>true</MtouchFloat32></PropertyGroup>
3.記得按照平臺引入原生庫的綁定
<ItemGroup Condition=" '$(TargetPlatformIdentifier)' == 'ios' "><ProjectReference Include="..\iOS.AmapSDK.Foundation\iOS.AmapSDK.Foundation.csproj" /> <ProjectReference Include="..\iOS.AmapSDK.3D\iOS.AmapSDK.3D.csproj" /> </ItemGroup><ItemGroup Condition=" '$(TargetPlatformIdentifier)' == 'android' "><ProjectReference Include="..\Droid.AmapSDK\Droid.AmapSDK.csproj" /> </ItemGroup>
查看完整項目文件,請點擊該鏈接:
https://github.com/kinfey/AMapMAUIControls/blob/main/src/AMap.UI.Demo/AMap.UI.Apps/AMap.UI.Apps.csproj
也別忘記去把一些平臺特有的設定設置好,具體可以
(1)iOS 設定請點擊該鏈接:
https://github.com/kinfey/AMapMAUIControls/blob/main/src/AMap.UI.Demo/AMap.UI.Apps/Platforms/iOS/Info.plist
(2)Android 設定請點擊該鏈接:
https://github.com/kinfey/AMapMAUIControls/blob/main/src/AMap.UI.Demo/AMap.UI.Apps/Platforms/Android/AndroidManifest.xml
4.在 MauiProgram.cs 上注冊
builder.UseMauiApp<App>().ConfigureFonts(fonts =>{fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");}).ConfigureMauiHandlers(handlers =>{handlers.AddHandler(typeof(AMap), typeof(AMapHandler));});
選擇編譯運行就可以看到高德地圖終于可以在 MAUI 環境下跑起來了。
小結
對于很多人來說或者都是初步接觸了 MAUI ,實際上要做好多平臺的兼容還要有非常長的路要走。希望通過這個系列的文章,能給一些第三方廠商和開發者一些幫助,能盡快提供 MAUI 的支持。這樣才能為這個新的技術注入活力。
*相關資料
1. 通過 Microsoft Docs 了解 MAUI?
https://aka.ms/Docs.MAUI
2. 通過 Microsoft Learn 學習 MAUI?
https://aka.ms/Learn.MAUI
3. 學習 ViewHandler 自定義 MAUI組件 請點擊訪問該鏈接?
https://docs.microsoft.com/zh-cn/dotnet/maui/user-interface/handlers/customize
CA周記往期回顧:
更多原創文章與資源共享
請關注Kinfey Techtalk