做?个?德地图的|做?个?德地图的 iOS / Android MAUI 控件(下)
我们已经介绍了如何通过 .NET 绑定 iOS 原?库 ,本篇开始介绍?下如何通过 .NET 绑定 Android 原?库。
Android 的库
Android 的库以 .jar 做打包, 通过?具你可以将多个 .jar 完成绑定,然后通过 C# 调?原?的 Java 库。对?起 iOS , Android 的库绑定简单很多。
文章图片
从上图可以看到 Xamarin.Android / .NET for Android 通过使?托管可调?包装器 (MCW) 实现绑定。MCW 是?个 JNI 桥,在托管代码需要调? Java 代码时会使?它。托管可调?包装器还?持对 Java 类型进??类 化以及覆盖 Java 类型的虚拟?法。同样,每当 Android 运?时 (ART) 代码需要调?托管代码时,它都会通 过另?个称为 Android 可调?包装器 (ACW) 的 JNI 桥来实现。
创建?个 Android 原?库绑定项?
通过命令?创建?个 Android 原?库绑定项?d
otnet new android-bindinglib -o Droid.AMap
进?该项?我们看看?件结构
文章图片
项???有 Transforms ?件夹有对应的三个 xml ?件,分别是 EnumFields.xml ,EnumMethods.xml , Metadata.xml , 各?作?如下 :
- MetaData.xml – 允许对最终 API 进?更改,例如更改?成的绑定的命名空间。
- EnumFields.xml – 包含 Java int 常量与 C# enums 之间的映射。
- EnumMethods.xml – 允许将?法参数和返回类型从 Java int 常量更改为 C# enums
删除不需要的命名空间、类、?法或字段。
将类移到不同的命名空间。
添加其他?持类以使绑定的设计遵循 .NET 框架模式。
▌把 jar ?件添加到绑定项? 在项?中添加 Jars ?录 ,把?德地图的 jar 包添加到该?录下 ,并把 arm64-v8a ,armeabi-v7a ,x86_64 这三个?录添加进来
文章图片
添加完成后,修改 .csproj ?件
net6.0-android
21
enable
enable
这样就把项?添加好了,没有像 iOS 原?库绑定那么繁琐。然后编译?下 ,凡尔赛 + 星??海了
文章图片
排雷工作 看?这么多错,真的要考虑?下是不是放弃,其实这也?常治愈,我们逐个来排雷。
- 'PoiCreator' does not implement interface member 'IParcelableCreator.NewArray(int)'.
- 'PoiCreator.NewArray(int)' cannot implement 'IParcelableCreator.NewArray(int)'
错误对应的是这个?法 ,实际就是返回类型出错了,我们先根据源?件看看 path 路径就可以解决
// Metadata.xml XPath method reference:
path="/api/package[@name='com.amap.api.maps.model']/class[@name='PoiCreato
r']/method[@name='newArray' and count(parameter)=1 and parameter[1]
[@type='int']]"
[Register ("newArray", "(I)[Lcom/amap/api/maps/model/Poi;
",
"GetNewArray_IHandler")]
public virtual unsafe global::Com.Amap.Api.Maps.Model.Poi[]? NewArray (int
p0)
{
const string __id = "newArray.(I)[Lcom/amap/api/maps/model/Poi;
";
try {
JniArgumentValue* __args = stackalloc JniArgumentValue [1];
__args [0] = new JniArgumentValue (p0);
var __rm = _members.InstanceMethods.InvokeVirtualObjectMethod
(__id, this, __args);
return (global::Com.Amap.Api.Maps.Model.Poi[]?)
JNIEnv.GetArray (__rm.Handle, JniHandleOwnership.TransferLocalRef, typeof
(global::Com.Amap.Api.Maps.Model.Poi));
} finally {
}}
【做?个?德地图的|做?个?德地图的 iOS / Android MAUI 控件(下)】确认好后,需要在 Metadata.xml 做添加
Java.Lang.Object[]
- The type 'AMap' already contains a definition for 'MarkerDragEnd'
- 'BusLineSearch': member names cannot be the same as their enclosing type
AmapBusLineSearch
- cannot change access modifiers when overriding 'protected'
protected
解决上述的所有问题,基本上就可以治愈了,当编译通过?刻你会?常兴奋
文章图片
找个 .NET for Android 项?看看
文章图片
- ?家可以去我的 GitHub 下载该示例
我们知道 MAUI 是开发跨平台应?的解决?案 ,? C# 可以直接把 iOS , Android , Windows , macOS , Linux ,Tizen 等应?开发出来。那我们在这个框架除了?底层?定义的 UI 控件外,如果我们要?如?德地图这样的 第三?控件,要如何做呢?接下来我就和?家介绍?下。
如果你还没有学习原?库绑定的知识,可以到以下链接学习相关内容:
- 关于做?个?德地图的 iOS / Android MAUI 控件(iOS 原?库绑定)
- 做?个?德地图的 iOS / Android MAUI 控件(Android 原?库绑定)
文章图片
我们可以清楚看到, 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 MapMapper = new
PropertyMapper(ViewHandler.ViewMapper)
{ };
public AMapHandler() : base(MapMapper)
{ }
}
然后在 Platforms 下的 Android 和 iOS ?件夹添加各?的平台 AMap 调??法。
文章图片
为 AMap.Android.cs 添加 Android 环境下?德地图的渲染?式
namespace AMap.UI.Apps
{
public partial class AMapHandler : ViewHandler
{
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);
03.UIControls.md 7/5/2022
4 / 8
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 环境下?德地图的渲染?式
namespace AMap.UI.Apps
{
public partial class AMapHandler : ViewHandler
{
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();
}
}
}
这?我们要修改 MAUI 的项??件,这?有?个设定需要注意的
- 因为这个控件只是针对 iOS / Android 两个平台,所以我们只保留 net6.0-android 和 net6.0-ios
- ?德 SDK 运?建议在真机下使?,特别是 iOS ,需要制定版本号,还有编译环境,我的环境是在 Apple silicon 下所以也要设定好 RuntimeIdentifier,还有就是编译的时候,我花了特别多时间在这?, ?家可以参考我这个在 GitHub 上?问?答的 Issue
https://github.com/xamarin/xa... macios/issues/15372
ios-arm64
true
4
SdkOnly
13.0
true
true
true
true
true
true
true
3. 记得按照平台引?原?库的绑定
- 查看完整项??件,请点击该链接
- 也别忘记去把?些平台特有的设定设置好,具体可以 iOS 设定请点击该链接
- Android 设定请点击该链接
builder
.UseMauiApp()
.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 的?持。这样才能为这个新的技术注?活?。
相关资料:
- .通过 Microsoft Docs 了解MAUI
- 通过 Microsoft Learn 学习MAUI
- 使??德地图 SDK for Android 请访问
- 了解 Android 原?库绑定的内容,请访问
- 学习 ViewHandler ?定义 MAUI组件 请点击访问该链接
文章图片
长按识别二维码
关注微软中国MSDN
点击了解MAUI~
推荐阅读
- 我们和沪江有个约会
- 投稿|被“抛弃”的摩天大楼:一个黄金时代的终结
- 华为服务器管理口在哪个位置,华为服务器默认管理口地址吗
- “七个神经病”——评《火星上的人类学家》
- 680篇时间管理文章第44篇-高效能第六个习惯感悟
- 这样的你多来几个我也照收
- 人生需要做减法
- 夏天,最让人爽快的方式,莫过于喝上一瓶这个!
- 零基础学习UI,如何4个月入职互联网公司成为一名月薪过万的UI设计师()
- 心疼