用Xamarin.Forms 也有一段时间了,跨平台,生成native代码的噱头 天花乱坠的,
其中的坑,只有用过的人才懂。。。
就拿地图来说。。。总不能用google地图吧 于是只能自己想办法了。
首先官网上有篇文章,大家可以看下
首先我们需要做的是 将地图的android sdk转为C#能用的dll ,也就是需要对android sdk做一个binding
由于百度地图及高德地图的api key申请都需要sha1值,个人嫌麻烦,所以选择了腾讯地图,腾讯地图只要api key即可。
1.先创建一个Android Bindings Library项目,命名为TencentMapBinding
2.将腾讯地图官网下载的sdk拖到Jars目录下,并将此jar文件的属性改为EmbeddedJar
3.修改Transforms目录下的Metadata.xml,将MapController类删掉
4.编译
然后再新建一个xamarin.forms项目,命名为MyTencentMap,在Portable中添加地图的页面
1 public class TencentMapPage : ContentPage { 2 3 public static BindableProperty PinsProperty = 4 BindableProperty.Create<TencentMapPage, IEnumerable>(p => p.Pins, default(IEnumerable)); 5 6 public IEnumerable Pins { 7 get { 8 return (IEnumerable)GetValue(PinsProperty); 9 } 10 set { 11 this.SetValue(PinsProperty, value); 12 } 13 } 14 }
再增加一个类
public class Page1:TencentMapPage { }
随便弄个实体类,显示数据用
public class UserTaskEntInfo : BaseIntInfo { public string PsCode { get; set; } public string BaseInfo { get; set; } public string ProduceInfo { get; set; } public string TreatmentInfo { get; set; } public string DischargeInfo { get; set; } public string Address { get; set; } public double? Longitude { get; set; } public double? Latitude { get; set; } } public class BaseIntInfo : BaseInfo<int> { } public abstract class BaseInfo<TId> { /// <summary> /// 标识 /// </summary> public TId Id { get; set; } /// <summary> /// 名称 /// </summary> public string Name { get; set; } }
App.cs文件中添加如下代码:
public App() { // The root page of your application var pins = new List<UserTaskEntInfo>() { }; pins.Add(new UserTaskEntInfo() { Name = "上海市浦东新区陆家嘴街道乳山二村", Longitude = 31.2317331909, Latitude = 121.5170146362 }); pins.Add(new UserTaskEntInfo() { Name = "上海市浦东新区昌邑路555弄", Longitude = 31.2431982838, Latitude = 121.5215228609 }); pins.Add(new UserTaskEntInfo() { Name = "上海市浦东新区东昌路267号", Longitude = 31.2316324310, Latitude = 121.5063730654 }); pins.Add(new UserTaskEntInfo() { Name = "上海市浦东新区滨江大道", Longitude = 31.2379863826, Latitude = 121.4959153979 }); pins.Add(new UserTaskEntInfo() { Name = "上海市浦东新区即墨路", Longitude = 31.2435242682, Latitude = 121.5104350816 }); NavigationTestPage = new NavigationPage(new Page1() { Pins = pins }); MainPage = NavigationTestPage; }
在MyTencentMap.Droid中将第一步binding生成的dll引入进来,
添加CustomTencentMapRenderer.cs
[assembly: ExportRenderer(typeof(TencentMapPage), typeof(CustomTencentMapRenderer))] namespace MyTencentMap.Droid { public class CustomTencentMapRenderer : PageRenderer { private TencentMapPage myAMapPage; private LinearLayout layout1; private MapView mapView; private Bundle bundle; protected override void OnElementChanged(ElementChangedEventArgs<Page> e) { base.OnElementChanged(e); myAMapPage = e.NewElement as TencentMapPage; layout1 = new LinearLayout(this.Context); this.AddView(layout1); mapView = new MapView(this.Context) { LayoutParameters = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent) }; LatLng SHANGHAI = new LatLng( 31.238068, 121.501654); mapView.Map.SetCenter(SHANGHAI); var pins = myAMapPage.Pins; Drawable d = Resources.GetDrawable(Resource.Drawable.red_location); Bitmap bitmap = ((BitmapDrawable)d).Bitmap; LatLng latLng1; foreach (UserTaskEntInfo pin in pins) { latLng1 = new LatLng(pin.Longitude ?? 31.238068, pin.Latitude ?? 121.501654); var markOption = new MarkerOptions(); markOption.InvokeIcon(new BitmapDescriptor(bitmap)); markOption.InvokeTitle(pin.Name); markOption.InvokePosition(latLng1); var fix = mapView.Map.AddMarker(markOption); fix.ShowInfoWindow(); } mapView.Map.SetZoom(15); mapView.OnCreate(bundle); layout1.AddView(mapView); } protected override void OnLayout(bool changed, int l, int t, int r, int b) { base.OnLayout(changed, l, t, r, b); var msw = View.MeasureSpec.MakeMeasureSpec(r - l, MeasureSpecMode.Exactly); var msh = View.MeasureSpec.MakeMeasureSpec(b - t, MeasureSpecMode.Exactly); layout1.Measure(msw, msh); layout1.Layout(0, 0, r - l, b - t); } } }
编译即可。
最后附上截图:
本文的代码可以从https://github.com/Joetangfb/Sharper中获取。