Aracılığıyla paylaş


Bir Harita Raptiyesini Özelleştirme

Bu makalede, harita denetimi için özelleştirilmiş bir pin ve her platformdaki pin verilerinin özelleştirilmiş bir görünümüyle yerel bir harita görüntüleyen özel işleyici oluşturma işlemleri gösterilmektedir.

Her Xamarin.Forms görünümde, yerel denetimin bir örneğini oluşturan her platform için eşlik eden bir işleyici vardır. iOS'ta Map bir Xamarin.Forms uygulama tarafından işlendiğinde, MapRenderer sınıfı örneği oluşturulur ve bu da yerel MKMapView bir denetimin örneğini oluşturur. Android platformunda MapRenderer , sınıfı yerel MapView bir denetim örneği oluşturur. sınıfı Evrensel Windows Platformu (UWP) MapRenderer üzerinde yerel MapControlbir örneği oluşturur. Eşlenmeyi denetleen Xamarin.Forms işleyici ve yerel denetim sınıfları hakkında daha fazla bilgi için bkz . oluşturucu Temel Sınıfları ve Yerel Denetimler.

Aşağıdaki diyagramda, bunu uygulayan ve buna karşılık gelen yerel denetimler arasındaki Map ilişki gösterilmektedir:

Eşleme Denetimi ile Yerel Denetimleri Uygulama Arasındaki İlişki

İşleme işlemi, her platformda bir için özel işleyici oluşturarak platforma özgü özelleştirmeler uygulamak için Map kullanılabilir. Bunu yapma işlemi aşağıdaki gibidir:

  1. Özel bir Xamarin.Forms harita oluşturun.
  2. uygulamasından özel haritayı Xamarin.Formskullanma.
  3. Her platformda harita için özel işleyici oluşturun .

Artık her öğe, özelleştirilmiş bir CustomMap pin ve her platformda pin verilerinin özelleştirilmiş bir görünümünü içeren yerel bir harita görüntüleyen bir işleyici uygulamak için ele alınacaktır.

Not

Xamarin.Forms.Maps kullanılmadan önce başlatılmalı ve yapılandırılmalıdır. Daha fazla bilgi için bkz. Maps Control.

Özel Harita Oluşturma

Özel eşleme denetimi, aşağıdaki kod örneğinde gösterildiği gibi sınıfın alt sınıfı Map oluşturularak oluşturulabilir:

public class CustomMap : Map
{
    public List<CustomPin> CustomPins { get; set; }
}

Denetim CustomMap .NET Standart kitaplık projesinde oluşturulur ve özel harita için API'yi tanımlar. Özel eşleme, her platformda CustomPins yerel harita denetimi tarafından işlenecek nesnelerin koleksiyonunu CustomPin temsil eden özelliği kullanıma sunar. CustomPin sınıfı aşağıdaki kod örneğinde gösterilmiştir:

public class CustomPin : Pin
{
    public string Name { get; set; }
    public string Url { get; set; }
}

Bu sınıf, sınıfın CustomPin özelliklerini Pin devralan ve ekleyen Name ve Url özellikleri olarak tanımlar.

Özel Haritayı Kullanma

Denetimin CustomMap konumu için bir ad alanı bildirilerek ve özel eşleme denetiminde ad alanı ön eki kullanılarak .NET Standart kitaplık projesindeki XAML'de denetime başvurulabilir. Aşağıdaki kod örneği, denetimin CustomMap bir XAML sayfası tarafından nasıl tüketilebileceğini gösterir:

<ContentPage ...
			       xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer">
	<local:CustomMap x:Name="customMap"
                   MapType="Street" />
</ContentPage>

Ad local alanı ön eki herhangi bir adla adlandırılabilir. clr-namespace Ancak ve assembly değerleri özel eşlemenin ayrıntılarıyla eşleşmelidir. Ad alanı bildirildikten sonra, özel eşlemeye başvurmak için ön ek kullanılır.

Aşağıdaki kod örneği, denetimin CustomMap bir C# sayfası tarafından nasıl kullanılıp kullanılamayabileceğini gösterir:

public class MapPageCS : ContentPage
{
    public MapPageCS()
    {
        CustomMap customMap = new CustomMap
        {
            MapType = MapType.Street
        };
        // ...
        Content = customMap;
    }
}

Örnek CustomMap , her platformda yerel haritayı görüntülemek için kullanılır. MapType özelliği, numaralandırmada tanımlanmakta Mapolan olası değerler ile öğesinin MapType görüntüleme stilini ayarlar.

Haritanın konumu ve içerdiği pinler aşağıdaki kod örneğinde gösterildiği gibi başlatılır:

public MapPage()
{
    // ...
    CustomPin pin = new CustomPin
    {
        Type = PinType.Place,
        Position = new Position(37.79752, -122.40183),
        Label = "Xamarin San Francisco Office",
        Address = "394 Pacific Ave, San Francisco CA",
        Name = "Xamarin",
        Url = "http://xamarin.com/about/"
    };
    customMap.CustomPins = new List<CustomPin> { pin };
    customMap.Pins.Add(pin);
    customMap.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(37.79752, -122.40183), Distance.FromMiles(1.0)));
}

Bu başlatma özel bir pin ekler ve bir ve öğesinden Position Distanceoluşturarak MapSpan haritanın konumunu ve yakınlaştırma düzeyini değiştiren yöntemiyle MoveToRegion haritanın görünümünü konumlandırır.

Artık yerel harita denetimlerini özelleştirmek için her uygulama projesine özel işleyici eklenebilir.

Her Platformda Özel oluşturucu oluşturma

Özel işleyici sınıfını oluşturma işlemi aşağıdaki gibidir:

  1. Özel eşlemeyi MapRenderer işleyen sınıfının bir alt sınıfını oluşturun.
  2. Özel eşlemeyi OnElementChanged işleyen yöntemini geçersiz kılın ve özelleştirmek için mantık yazın. Bu yöntem, karşılık gelen Xamarin.Forms özel eşleme oluşturulduğunda çağrılır.
  3. Özel eşlemeyi işlemek için kullanılacağını belirtmek için özel işleyici sınıfına Xamarin.Forms bir ExportRenderer öznitelik ekleyin. Bu öznitelik, özel işleyiciyi ile Xamarin.Formskaydetmek için kullanılır.

Not

Her platform projesinde özel işleyici sağlamak isteğe bağlıdır. Özel işleyici kaydedilmemişse, denetimin temel sınıfı için varsayılan işleyici kullanılır.

Aşağıdaki diyagramda, örnek uygulamadaki her projenin sorumlulukları ve aralarındaki ilişkiler gösterilmektedir:

CustomMap Özel oluşturucu proje sorumlulukları

Denetim CustomMap , her platform için sınıfından MapRenderer türetilen platforma özgü işleyici sınıfları tarafından işlenir. Bu, aşağıdaki ekran görüntülerinde gösterildiği gibi her CustomMap denetimin platforma özgü denetimlerle işlenmesine neden olur:

Her Platformda CustomMap

MapRenderer sınıfı, ilgili yerel denetimi işlemek için özel eşleme oluşturulduğunda çağrılan Xamarin.Forms yöntemini kullanıma sunarOnElementChanged. Bu yöntem ve NewElement özelliklerini içeren OldElement bir ElementChangedEventArgs parametre alır. Bu özellikler, işleyicinin eklendiği öğeyi ve Xamarin.Forms sırasıyla işleyicinin eklendiği öğeyi temsil Xamarin.Forms edilir. Örnek uygulamada OldElement özelliği olur null ve NewElement özelliği örneğe bir başvuru CustomMap içerir.

Her platforma özgü işleyici sınıfında yöntemin OnElementChanged geçersiz kılınmış bir sürümü, yerel denetim özelleştirmesinin gerçekleştirebileceğiniz yerdir. Platformda kullanılan yerel denetime yazılan başvuruya özelliği üzerinden Control erişilebilir. Ayrıca, işlenen denetime Xamarin.Forms bir başvuru özelliği aracılığıyla Element elde edilebilir.

Aşağıdaki kod örneğinde gösterildiği gibi yöntemindeki OnElementChanged olay işleyicilerine abone olurken dikkatli olunmalıdır:

protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.View> e)
{
  base.OnElementChanged (e);

  if (e.OldElement != null)
  {
      // Unsubscribe from event handlers
  }

  if (e.NewElement != null)
  {
      // Configure the native control and subscribe to event handlers
  }
}

Yerel denetim yapılandırılmalıdır ve olay işleyicileri yalnızca özel işleyici yeni Xamarin.Forms bir öğeye eklendiğinde abone olmalıdır. Benzer şekilde, abone olunan tüm olay işleyicileri yalnızca işleyicinin eklendiği öğe değiştiğinde aboneliği kaldırılmalıdır. Bu yaklaşımı benimsemek, bellek sızıntılarından muzdarip olmayan özel bir işleyici oluşturmaya yardımcı olur.

Her özel işleyici sınıfı, işleyiciyi ile kaydeden bir ExportRenderer öznitelikle Xamarin.Formsdekore edilmiştir. özniteliği iki parametre alır: işlenen özel denetimin Xamarin.Forms tür adı ve özel işleyicinin tür adı. assembly özniteliğinin ön eki, özniteliğin tüm derleme için geçerli olduğunu belirtir.

Aşağıdaki bölümlerde platforma özgü özel işleyici sınıflarının uygulanması açıklanmıştır.

iOS'ta Özel oluşturucu oluşturma

Aşağıdaki ekran görüntüleri, özelleştirmeden önce ve sonra haritayı gösterir:

Ekran görüntüleri, sıradan bir pin ve ek açıklamalı pin içeren bir mobil cihazı gösterir.

iOS'ta raptiye ek açıklama olarak adlandırılır ve özel bir görüntü veya çeşitli renklerden oluşan sistem tanımlı bir raptiye olabilir. Ek açıklamalar isteğe bağlı olarak, ek açıklamayı seçen kullanıcıya yanıt olarak görüntülenen bir açıklama balonu gösterebilir. Açıklama balonu, isteğe bağlı sol ve sağ aksesuar görünümleriyle örneğin ve Address özelliklerini Pin görüntülerLabel. Yukarıdaki ekran görüntüsünde, sol aksesuar görünümü bir maymunun resmidir ve sağ aksesuar görünümü Bilgi düğmesidir.

Aşağıdaki kod örneği, iOS platformu için özel işleyiciyi gösterir:

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace CustomRenderer.iOS
{
    public class CustomMapRenderer : MapRenderer
    {
        UIView customPinView;
        List<CustomPin> customPins;

        protected override void OnElementChanged(ElementChangedEventArgs<View> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                var nativeMap = Control as MKMapView;
                if (nativeMap != null)
                {
                    nativeMap.RemoveAnnotations(nativeMap.Annotations);
                    nativeMap.GetViewForAnnotation = null;
                    nativeMap.CalloutAccessoryControlTapped -= OnCalloutAccessoryControlTapped;
                    nativeMap.DidSelectAnnotationView -= OnDidSelectAnnotationView;
                    nativeMap.DidDeselectAnnotationView -= OnDidDeselectAnnotationView;
                }
            }

            if (e.NewElement != null)
            {
                var formsMap = (CustomMap)e.NewElement;
                var nativeMap = Control as MKMapView;
                customPins = formsMap.CustomPins;

                nativeMap.GetViewForAnnotation = GetViewForAnnotation;
                nativeMap.CalloutAccessoryControlTapped += OnCalloutAccessoryControlTapped;
                nativeMap.DidSelectAnnotationView += OnDidSelectAnnotationView;
                nativeMap.DidDeselectAnnotationView += OnDidDeselectAnnotationView;
            }
        }
        // ...
    }
}

yöntemiOnElementChanged, özel işleyicinin yeni Xamarin.Forms bir öğeye MKMapView eklenmesi koşuluyla örneğin aşağıdaki yapılandırmasını gerçekleştirir:

  • GetViewForAnnotation özelliği yöntemine GetViewForAnnotation ayarlanır. Bu yöntem, ek açıklamanın konumu haritada görünür hale geldiğinde çağrılır ve görüntülenmeden önce ek açıklamayı özelleştirmek için kullanılır.
  • , DidSelectAnnotationViewve DidDeselectAnnotationView olayları için CalloutAccessoryControlTappedolay işleyicileri kaydedilir. Bu olaylar, kullanıcı açıklama balonunda doğru aksesuara dokunduğunda ve kullanıcı ek açıklamayı sırasıyla seçip seçimini kaldırdığında tetikler. Olaylar, yalnızca işleyicinin değişikliklere eklendiği öğe olduğunda abonelikten çıkarılır.

Ek Açıklamayı Görüntüleme

GetViewForAnnotation yöntemi, ek açıklamanın konumu haritada görünür hale geldiğinde çağrılır ve görüntülenmeden önce ek açıklamayı özelleştirmek için kullanılır. Ek açıklamanın iki bölümü vardır:

  • MkAnnotation – ek açıklamanın başlığını, alt başlığını ve konumunu içerir.
  • MkAnnotationView – ek açıklamayı temsil eden görüntüyü ve isteğe bağlı olarak kullanıcı ek açıklamaya dokunduğunda gösterilen açıklama balonunu içerir.

yöntemi, GetViewForAnnotation ek açıklamanın verilerini içeren bir IMKAnnotation değerini kabul eder ve haritada görüntülemek için bir MKAnnotationView döndürür ve aşağıdaki kod örneğinde gösterilir:

protected override MKAnnotationView GetViewForAnnotation(MKMapView mapView, IMKAnnotation annotation)
{
    MKAnnotationView annotationView = null;

    if (annotation is MKUserLocation)
        return null;

    var customPin = GetCustomPin(annotation as MKPointAnnotation);
    if (customPin == null)
    {
        throw new Exception("Custom pin not found");
    }

    annotationView = mapView.DequeueReusableAnnotation(customPin.Name);
    if (annotationView == null)
    {
        annotationView = new CustomMKAnnotationView(annotation, customPin.Name);
        annotationView.Image = UIImage.FromFile("pin.png");
        annotationView.CalloutOffset = new CGPoint(0, 0);
        annotationView.LeftCalloutAccessoryView = new UIImageView(UIImage.FromFile("monkey.png"));
        annotationView.RightCalloutAccessoryView = UIButton.FromType(UIButtonType.DetailDisclosure);
        ((CustomMKAnnotationView)annotationView).Name = customPin.Name;
        ((CustomMKAnnotationView)annotationView).Url = customPin.Url;
    }
    annotationView.CanShowCallout = true;

    return annotationView;
}

Bu yöntem, ek açıklamanın sistem tanımlı pin yerine özel bir görüntü olarak görüntülenmesini ve ek açıklamaya dokunulduğunda ek açıklama başlığının ve adresinin solunda ve sağında ek içerik içeren bir açıklama balonu görüntülenmesini sağlar. Bu, aşağıdaki gibi gerçekleştirilir:

  1. yöntemi GetCustomPin , ek açıklama için özel pin verilerini döndürmek için çağrılır.
  2. Bellek tasarrufu yapmak için, ek açıklamanın görünümü çağrısıyla yeniden kullanılmak üzere havuza DequeueReusableAnnotationeklenir.
  3. sınıfı, CustomMKAnnotationView sınıfını örnekteki MKAnnotationView özdeş özelliklere karşılık gelen ve Url özellikleriyle Name genişletirCustomPin. Ek açıklamanın nullolması koşuluyla yeni bir örneği CustomMKAnnotationView oluşturulur:
    • CustomMKAnnotationView.Image özelliği, eşlemedeki ek açıklamayı temsil edecek görüntüye ayarlanır.
    • CustomMKAnnotationView.CalloutOffset özelliği, açıklama balonunun ek açıklamanın üzerinde ortalandığını belirten bir CGPoint olarak ayarlanır.
    • CustomMKAnnotationView.LeftCalloutAccessoryView özelliği, ek açıklama başlığının ve adresinin solunda görünecek bir maymun görüntüsüne ayarlanır.
    • CustomMKAnnotationView.RightCalloutAccessoryView özelliği, ek açıklama başlığının ve adresinin sağındaki Bir Bilgi düğmesine ayarlanır.
    • CustomMKAnnotationView.Name özelliği, yöntemi tarafından GetCustomPin döndürülen özelliğe ayarlanırCustomPin.Name. Bu, açıklama balonunun daha fazla özelleştirilebilmesi için ek açıklamanın tanımlanmasını sağlar.
    • CustomMKAnnotationView.Url özelliği, yöntemi tarafından GetCustomPin döndürülen özelliğe ayarlanırCustomPin.Url. Kullanıcı sağ açıklama balonu aksesuar görünümünde görüntülenen düğmeye dokunduğunda URL'ye gidilir.
  4. MKAnnotationView.CanShowCallout ek açıklamaya dokunulduğunda belirtme çizgisinin görüntülenmesi için true özelliği olarak ayarlanır.
  5. Ek açıklama, haritada görüntülenmek üzere döndürülür.

Ek Açıklamayı Seçme

Kullanıcı ek açıklamaya dokunduğunda olay DidSelectAnnotationView tetikler ve bu da yöntemini yürütür OnDidSelectAnnotationView :

void OnDidSelectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
    CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
    customPinView = new UIView();

    if (customView.Name.Equals("Xamarin"))
    {
        customPinView.Frame = new CGRect(0, 0, 200, 84);
        var image = new UIImageView(new CGRect(0, 0, 200, 84));
        image.Image = UIImage.FromFile("xamarin.png");
        customPinView.AddSubview(image);
        customPinView.Center = new CGPoint(0, -(e.View.Frame.Height + 75));
        e.View.AddSubview(customPinView);
    }
}

Bu yöntem, seçili ek açıklamanın özelliği olarak ayarlanmış Xamarinolması koşuluyla, Xamarin logosunun görüntüsünü içeren bir UIView örnek ekleyerek mevcut açıklama balonunu (sol ve sağ aksesuar görünümlerini Name içeren) genişletir. Bu, farklı ek açıklamalar için farklı açıklama balonlarının görüntülenebildiği senaryolara olanak tanır. Örnek UIView , mevcut açıklama balonunun üzerinde ortalanır.

Sağ Açıklama Balonu Aksesuar Görünümüne Dokunma

Kullanıcı sağ açıklama balonu aksesuar görünümünde Bilgi düğmesine dokunduğunda olay CalloutAccessoryControlTapped tetikler ve bu da yöntemini yürütürOnCalloutAccessoryControlTapped:

void OnCalloutAccessoryControlTapped(object sender, MKMapViewAccessoryTappedEventArgs e)
{
    CustomMKAnnotationView customView = e.View as CustomMKAnnotationView;
    if (!string.IsNullOrWhiteSpace(customView.Url))
    {
        UIApplication.SharedApplication.OpenUrl(new Foundation.NSUrl(customView.Url));
    }
}

Bu yöntem bir web tarayıcısı açar ve özelliğinde depolanan adrese CustomMKAnnotationView.Url gider. .NET Standart kitaplık projesinde koleksiyon oluşturulurken CustomPin adresin tanımlandığını unutmayın.

Ek Açıklama seçimini kaldırma

Ek açıklama görüntülendiğinde ve kullanıcı haritaya dokunduğunda, DidDeselectAnnotationView olay tetikler ve bu da yöntemini yürütür OnDidDeselectAnnotationView :

void OnDidDeselectAnnotationView(object sender, MKAnnotationViewEventArgs e)
{
    if (!e.View.Selected)
    {
        customPinView.RemoveFromSuperview();
        customPinView.Dispose();
        customPinView = null;
    }
}

Bu yöntem, mevcut belirtme çizgisi seçilmediğinde açıklama balonunun genişletilmiş bölümünün de (Xamarin logosunun resmi) görüntülenmemesini ve kaynaklarının yayımlanmasını sağlar.

Örneği MKMapView özelleştirme hakkında daha fazla bilgi için bkz . iOS Haritalar.

Android'de Özel oluşturucu oluşturma

Aşağıdaki ekran görüntüleri, özelleştirmeden önce ve sonra haritayı gösterir:

Ekran görüntüleri, sıradan bir işaretçi ve özelleştirilmiş bir işaretçi içeren bir mobil cihazı gösterir.

Android'de raptiye işaretçi olarak adlandırılır ve özel bir görüntü veya çeşitli renklerde sistem tanımlı bir işaretçi olabilir. İşaretçiler, kullanıcının işaretçiye dokunmasına yanıt olarak görüntülenen bir bilgi penceresi gösterebilir. Bilgi penceresinde örneğin ve Address özellikleri Pin görüntülenir Label ve diğer içeriği içerecek şekilde özelleştirilebilir. Ancak, aynı anda yalnızca bir bilgi penceresi gösterilebilir.

Aşağıdaki kod örneği, Android platformu için özel işleyiciyi gösterir:

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace CustomRenderer.Droid
{
    public class CustomMapRenderer : MapRenderer, GoogleMap.IInfoWindowAdapter
    {
        List<CustomPin> customPins;

        public CustomMapRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Map> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                NativeMap.InfoWindowClick -= OnInfoWindowClick;
            }

            if (e.NewElement != null)
            {
                var formsMap = (CustomMap)e.NewElement;
                customPins = formsMap.CustomPins;
            }
        }

        protected override void OnMapReady(GoogleMap map)
        {
            base.OnMapReady(map);

            NativeMap.InfoWindowClick += OnInfoWindowClick;
            NativeMap.SetInfoWindowAdapter(this);
        }
        ...
    }
}

Özel işleyicinin yeni Xamarin.Forms bir öğeye eklenmesi koşuluyla OnElementChanged , yöntemi denetimden özel pinlerin listesini alır. GoogleMap Örnek kullanılabilir olduğunda geçersiz OnMapReady kılma çağrılır. Bu yöntem, olay için InfoWindowClick bir olay işleyicisi kaydeder; bu, bilgi penceresine tıklandığında tetiklenir ve yalnızca işleyicinin değişikliklere eklendiği öğe olduğunda aboneliği kaldırılır. Geçersiz OnMapReady kılma, sınıf örneğinin SetInfoWindowAdapter CustomMapRenderer bilgi penceresini özelleştirme yöntemlerini sağlayacağını belirtmek için yöntemini de çağırır.

sınıfı, CustomMapRenderer bilgi penceresini özelleştirmek için arabirimini uygularGoogleMap.IInfoWindowAdapter. Bu arabirim, aşağıdaki yöntemlerin uygulanması gerektiğini belirtir:

  • public Android.Views.View GetInfoWindow(Marker marker) – İşaretçi için özel bilgi penceresi döndürmek için bu yöntem çağrılır. döndürürse null, varsayılan pencere işleme kullanılır. bir döndürürse View, bu View bilgi penceresi çerçevesinin içine yerleştirilir.
  • public Android.Views.View GetInfoContents(Marker marker) – Bu yöntem, bilgi penceresinin içeriğini içeren bir View döndürmek için çağrılır ve yalnızca yöntemi döndürdüğünde GetInfoWindow çağrılır null. döndürürse null, bilgi penceresi içeriğinin varsayılan işlemesi kullanılır.

Örnek uygulamada, yalnızca bilgi penceresi içeriği özelleştirilir ve bu nedenle GetInfoWindow yöntemi bunu etkinleştirmek için geri döner null .

İşaretçiyi Özelleştirme

bir işaretçiyi temsil etmek için kullanılan simge yöntemi çağrılarak MarkerOptions.SetIcon özelleştirilebilir. Bu, eşlemeye CreateMarker eklenen her Pin biri için çağrılan yöntemini geçersiz kılarak gerçekleştirilebilir:

protected override MarkerOptions CreateMarker(Pin pin)
{
    var marker = new MarkerOptions();
    marker.SetPosition(new LatLng(pin.Position.Latitude, pin.Position.Longitude));
    marker.SetTitle(pin.Label);
    marker.SetSnippet(pin.Address);
    marker.SetIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.pin));
    return marker;
}

Bu yöntem her Pin örnek için yeni MarkerOption bir örnek oluşturur. İşaretçinin konumunu, etiketini ve adresini ayarladıktan sonra, simgesi yöntemiyle SetIcon ayarlanır. Bu yöntem, simgesini işlemek için gerekli verileri içeren bir BitmapDescriptor nesne alır ve BitmapDescriptorFactory sınıfı, oluşturulmasını BitmapDescriptorbasitleştirmek için yardımcı yöntemler sağlar. Bir işaretçiyi özelleştirmek için sınıfını BitmapDescriptorFactory kullanma hakkında daha fazla bilgi için bkz . İşaretçiyi Özelleştirme.

Not

Gerekirse, GetMarkerForPin yöntemi bir 'den Pinalmak Marker için harita işleyicinizde çağrılabilir.

Bilgi Penceresini Özelleştirme

Kullanıcı işaretçiye dokunduğunda, GetInfoContents yöntemi döndürdüğünde GetInfoWindow yöntemi yürütülür null. Aşağıdaki kod örneği yöntemini gösterir GetInfoContents :

public Android.Views.View GetInfoContents(Marker marker)
{
    var inflater = Android.App.Application.Context.GetSystemService(Context.LayoutInflaterService) as Android.Views.LayoutInflater;
    if (inflater != null)
    {
        Android.Views.View view;

        var customPin = GetCustomPin(marker);
        if (customPin == null)
        {
            throw new Exception("Custom pin not found");
        }

        if (customPin.Name.Equals("Xamarin"))
        {
            view = inflater.Inflate(Resource.Layout.XamarinMapInfoWindow, null);
        }
        else
        {
            view = inflater.Inflate(Resource.Layout.MapInfoWindow, null);
        }

        var infoTitle = view.FindViewById<TextView>(Resource.Id.InfoWindowTitle);
        var infoSubtitle = view.FindViewById<TextView>(Resource.Id.InfoWindowSubtitle);

        if (infoTitle != null)
        {
            infoTitle.Text = marker.Title;
        }
        if (infoSubtitle != null)
        {
            infoSubtitle.Text = marker.Snippet;
        }

        return view;
    }
    return null;
}

Bu yöntem, bilgi penceresinin içeriğini içeren bir View döndürür. Bu, aşağıdaki gibi gerçekleştirilir:

  • Bir LayoutInflater örnek alınır. Bu, bir düzen XML dosyasının örneğini ilgili Viewiçine oluşturmak için kullanılır.
  • GetCustomPin Yöntem, bilgi penceresi için özel pin verilerini döndürmek için çağrılır.
  • XamarinMapInfoWindow Özelliği değerine eşitse CustomPin.Name Xamarindüzen şişirilir. Aksi takdirde, MapInfoWindow düzen şişirilir. Bu, farklı işaretçiler için farklı bilgi penceresi düzenlerinin görüntülenebildiği senaryolara olanak tanır.
  • InfoWindowTitle ve InfoWindowSubtitle kaynakları, şişirilen düzenden alınır ve kaynaklar Text olmaması nullkoşuluyla özellikleri örnekten Marker ilgili verilere ayarlanır.
  • Örnek View , haritada görüntülenmek üzere döndürülür.

Not

Bilgi penceresi canlı Viewdeğildir. Bunun yerine Android, öğesini View statik bit eşlem olarak dönüştürür ve bunu görüntü olarak görüntüler. Bu, bir bilgi penceresinin tıklama olayına yanıt verebildiği halde herhangi bir dokunma olayına veya hareketine yanıt veremeyeceği ve bilgi penceresindeki tek tek denetimlerin kendi tıklama olaylarına yanıt veremeyeceği anlamına gelir.

Bilgi Penceresi'ne tıklama

Kullanıcı bilgi penceresine tıkladığında olay InfoWindowClick tetikler ve bu da yöntemini yürütür OnInfoWindowClick :

void OnInfoWindowClick(object sender, GoogleMap.InfoWindowClickEventArgs e)
{
    var customPin = GetCustomPin(e.Marker);
    if (customPin == null)
    {
        throw new Exception("Custom pin not found");
    }

    if (!string.IsNullOrWhiteSpace(customPin.Url))
    {
        var url = Android.Net.Uri.Parse(customPin.Url);
        var intent = new Intent(Intent.ActionView, url);
        intent.AddFlags(ActivityFlags.NewTask);
        Android.App.Application.Context.StartActivity(intent);
    }
}

Bu yöntem bir web tarayıcısı açar ve için alınan CustomPin örneğin özelliğinde Url depolanan adrese Markergider. .NET Standart kitaplık projesinde koleksiyon oluşturulurken CustomPin adresin tanımlandığını unutmayın.

Örneği MapView özelleştirme hakkında daha fazla bilgi için bkz . Haritalar API'si.

Evrensel Windows Platformu Üzerinde Özel oluşturucu oluşturma

Aşağıdaki ekran görüntüleri, özelleştirmeden önce ve sonra haritayı gösterir:

Ekran görüntüleri, sıradan bir harita simgesi ve özelleştirilmiş harita simgesi içeren bir mobil cihazı gösterir.

UWP'de raptiye harita simgesi olarak adlandırılır ve özel bir görüntü veya sistem tanımlı varsayılan görüntü olabilir. Harita simgesi, kullanıcının harita simgesine dokunmasına yanıt olarak görüntülenen bir UserControlöğesini gösterebilir. , UserControl örneğin ve Address özellikleri Pin de dahil olmak üzere Label tüm içeriği görüntüleyebilir.

Aşağıdaki kod örneği, UWP özel işleyicisini gösterir:

[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
namespace CustomRenderer.UWP
{
    public class CustomMapRenderer : MapRenderer
    {
        MapControl nativeMap;
        List<CustomPin> customPins;
        XamarinMapOverlay mapOverlay;
        bool xamarinOverlayShown = false;

        protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
        {
            base.OnElementChanged(e);

            if (e.OldElement != null)
            {
                nativeMap.MapElementClick -= OnMapElementClick;
                nativeMap.Children.Clear();
                mapOverlay = null;
                nativeMap = null;
            }

            if (e.NewElement != null)
            {
                var formsMap = (CustomMap)e.NewElement;
                nativeMap = Control as MapControl;
                customPins = formsMap.CustomPins;

                nativeMap.Children.Clear();
                nativeMap.MapElementClick += OnMapElementClick;

                foreach (var pin in customPins)
                {
                    var snPosition = new BasicGeoposition { Latitude = pin.Pin.Position.Latitude, Longitude = pin.Pin.Position.Longitude };
                    var snPoint = new Geopoint(snPosition);

                    var mapIcon = new MapIcon();
                    mapIcon.Image = RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///pin.png"));
                    mapIcon.CollisionBehaviorDesired = MapElementCollisionBehavior.RemainVisible;
                    mapIcon.Location = snPoint;
                    mapIcon.NormalizedAnchorPoint = new Windows.Foundation.Point(0.5, 1.0);

                    nativeMap.MapElements.Add(mapIcon);                    
                }
            }
        }
        ...
    }
}

yöntemi OnElementChanged , özel işleyicinin yeni Xamarin.Forms bir öğeye eklenmesi koşuluyla aşağıdaki işlemleri gerçekleştirir:

  • Olay için bir olay işleyicisi MapControl.Children kaydetmeden önce mevcut kullanıcı arabirimi öğelerini eşlemeden kaldırmak için MapElementClick koleksiyonu temizler. Bu olay, kullanıcı öğesine MapControldokunduğunda veya üzerine tıkladığında MapElement tetiklenir ve yalnızca işleyicinin değişikliklere ekli olduğu öğe abonelikten çıkarılır.
  • Koleksiyondaki her raptiye customPins haritada doğru coğrafi konumda aşağıdaki gibi görüntülenir:
    • Pinin konumu örnek Geopoint olarak oluşturulur.
    • MapIcon Pini temsil eden bir örnek oluşturulur.
    • öğesini temsil MapIcon etmek için kullanılan görüntü, özelliği ayarlanarak MapIcon.Image belirtilir. Ancak haritadaki diğer öğeler tarafından gizlenebileceği için harita simgesinin görüntüsünün her zaman gösterilmesi garanti edilemez. Bu nedenle, harita simgesinin CollisionBehaviorDesired özelliği görünür kaldığından emin olmak için olarak ayarlanır MapElementCollisionBehavior.RemainVisible.
    • konumu MapIcon özelliği ayarlanarak MapIcon.Location belirtilir.
    • MapIcon.NormalizedAnchorPoint özelliği, işaretçinin görüntüdeki yaklaşık konumuna ayarlanır. Bu özellik, görüntünün sol üst köşesini temsil eden varsayılan değerini (0,0) korursa, haritanın yakınlaştırma düzeyindeki değişiklikler görüntünün farklı bir konuma işaret etmesine neden olabilir.
    • Örnek MapIcon koleksiyona MapControl.MapElements eklenir. Bu, üzerinde harita simgesinin görüntülenmesine MapControlneden olur.

Not

Birden çok harita simgesi için aynı görüntüyü kullanırken, RandomAccessStreamReference en iyi performans için örnek sayfada veya uygulama düzeyinde bildirilmelidir.

UserControl'i görüntüleme

Kullanıcı harita simgesine OnMapElementClick dokunduğunda yöntemi yürütülür. Aşağıdaki kod örneği bu yöntemi gösterir:

private void OnMapElementClick(MapControl sender, MapElementClickEventArgs args)
{
    var mapIcon = args.MapElements.FirstOrDefault(x => x is MapIcon) as MapIcon;
    if (mapIcon != null)
    {
        if (!xamarinOverlayShown)
        {
            var customPin = GetCustomPin(mapIcon.Location.Position);
            if (customPin == null)
            {
                throw new Exception("Custom pin not found");
            }

            if (customPin.Name.Equals("Xamarin"))
            {
                if (mapOverlay == null)
                {
                    mapOverlay = new XamarinMapOverlay(customPin);
                }

                var snPosition = new BasicGeoposition { Latitude = customPin.Position.Latitude, Longitude = customPin.Position.Longitude };
                var snPoint = new Geopoint(snPosition);

                nativeMap.Children.Add(mapOverlay);
                MapControl.SetLocation(mapOverlay, snPoint);
                MapControl.SetNormalizedAnchorPoint(mapOverlay, new Windows.Foundation.Point(0.5, 1.0));
                xamarinOverlayShown = true;
            }
        }
        else
        {
            nativeMap.Children.Remove(mapOverlay);
            xamarinOverlayShown = false;
        }
    }
}

Bu yöntem, pin hakkındaki bilgileri görüntüleyen bir UserControl örnek oluşturur. Bu, aşağıdaki gibi gerçekleştirilir:

  • Örnek MapIcon alınır.
  • GetCustomPin yöntemi, görüntülenecek özel pin verilerini döndürmek için çağrılır.
  • XamarinMapOverlay Özel pin verilerini görüntülemek için bir örnek oluşturulur. Bu sınıf bir kullanıcı denetimidir.
  • üzerinde MapControl örneğin görüntüleneceği XamarinMapOverlay coğrafi konum örnek Geopoint olarak oluşturulur.
  • Örnek XamarinMapOverlay koleksiyona MapControl.Children eklenir. Bu koleksiyon, haritada görüntülenecek XAML kullanıcı arabirimi öğelerini içerir.
  • Örneğin haritadaki coğrafi konumu XamarinMapOverlay yöntemi çağrılarak SetLocation ayarlanır.
  • Örnekte belirtilen konuma karşılık gelen göreli konum XamarinMapOverlay yöntemi çağrılarak SetNormalizedAnchorPoint ayarlanır. Bu, haritanın XamarinMapOverlay yakınlaştırma düzeyindeki değişikliklerin, örneğin her zaman doğru konumda görüntülenmesini sağlar.

Alternatif olarak, raptiye hakkındaki bilgiler haritada zaten görüntüleniyorsa haritaya dokunulduğunda örnek koleksiyondan MapControl.Children kaldırılırXamarinMapOverlay.

Bilgi Düğmesine dokunma

Kullanıcı, kullanıcı denetimindeki Bilgi düğmesine dokunduğunda XamarinMapOverlay , Tapped olay tetikler ve bu da yöntemini yürütür OnInfoButtonTapped :

private async void OnInfoButtonTapped(object sender, TappedRoutedEventArgs e)
{
    await Launcher.LaunchUriAsync(new Uri(customPin.Url));
}

Bu yöntem bir web tarayıcısı açar ve örneğin özelliğinde Url depolanan adrese CustomPin gider. .NET Standart kitaplık projesinde koleksiyon oluşturulurken CustomPin adresin tanımlandığını unutmayın.

Örneği MapControl özelleştirme hakkında daha fazla bilgi için bkz . MSDN'de Haritalar ve Konuma Genel Bakış .