用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中獲取。