Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 77050

Truly Bindable Maps, gauging demand

$
0
0

Hey Forms Community.

For the past several months I've been neck deep in maps, and I've nearly re-written Xamarin.Forms.Maps entirely. I'm trying to gauge the demand for truly bindable maps, and if I should submit this stuff back to Xamarin.

Features:

  • BindableMarker (all properties are bindable)
    • public Xamarin.Forms.Color Color;... yes that's right, full RGB marker support for markers
    • public event MarkerSelected;
    • public event MarkerDeselected;
  • BindablePolygon (all properties are bindable)
    • public bool IsVisible;
    • public IEnumberable<IList<Position>> Holes;
    • public IEnumerable<Position> Area;
    • public Xamarin.Forms.Color FillColor;
    • public Xamarin.Forms.Color StrokeColor;
  • NativeMarkerImage
    • public Xamarin.Forms.Color Color; - a View with a custom renderer allowing you to extract the native map pin into your XAML code.
  • BindableMap
    • Lots and lots. The highlights here are the fact that markers are truly bindable without leveraging the native map's clear(); methods. This allows us to keep callouts open and keep unchanging markers on the view at all times.
    • Has a CalloutTemplate that allows us to write our callouts in Xaml (see example below)
    • Fixes VisibleRegion to allow us to set the visible region from the ViewModel (two way binding).
    • public event EventHandler<MapBoundsChangedEventArgs> BoundsChanged;
    • public event EventHandler MapLoaded;
    • public event EventHandler MarkersChanging;
    • public event EventHandler PolygonsChanging;
    • public event EventHandler MarkersChanged;
    • public event EventHandler PolygonsChanged;
    • public event EventHandler MapClicked;
    • LatLongBounds - new class that should be part of MapSpan
    • returns the NorthEast and the SoutWest corners of the visible map
    • public bool Contains(IEnumerable<Position>);
    • might expose CalculateCentroid();

side note: I've completely done away the the MessagingCenter as I'm really not a fan. I have hard event subscriptions between the PCL and the native, and they're not exposed to you... just to keep it clean.

image

note: the video above is on iOS, but it works equally as well on Android... even the native Android markers and a fully bindable callout... and yes, even buttons on the callout work for Android. - what a PITA that was.

Here's the xaml for a map

<rdr:ExtendedMap x:Name="StreetlightsMap" 
                  HorizontalOptions="FillAndExpand"
                  MapClicked="StreetlightsMap_OnMapClicked"
                  MapLoaded="StreetlightsMap_OnMapLoaded"
                  VerticalOptions="FillAndExpand"
                  MarkerSource="{Binding Streetlights}"
                  MapBounds="{Binding MapBounds}"
                  VisibleRegion="{Binding VisibleRegion}"
                  ServiceArea="{Binding ServiceArea}"
                  HideOutOfViewElements="False"
                  AllowRotation="False"
                  MarkerAlignmentForCallout="Bottom"
                  MapType="{Binding MapType}"
                  RelativeLayout.XConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                  RelativeLayout.YConstraint="{ConstraintExpression Type=Constant, Constant=0}"
                  RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1 }"
                  RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1 }">
    <rdr:ExtendedMap.Behaviors>
        <behaviors:MapBoundsChangedCommandBehavior Command="{Binding GetStreetlightsCommand}"
                                                    CommandParameter="{Binding .}" />
    </rdr:ExtendedMap.Behaviors>
    <rdr:ExtendedMap.CalloutTemplate>
        <DataTemplate>
            <controls:StreetlightMarkerCallout />
        </DataTemplate>
    </rdr:ExtendedMap.CalloutTemplate>
    <!-- Sets the initial map location.-->
    <x:Arguments>
        <maps:MapSpan>
            <x:Arguments>
                <!-- These coordinates land near Red Deer at a fairly high altitude (birds eye view). -->
                <maps:Position>
                    <x:Arguments>
                        <!-- Latitude-->
                        <x:Double>52.325</x:Double>
                        <!-- Longitude-->
                        <x:Double>-113.9</x:Double>
                    </x:Arguments>
                </maps:Position>
                <!-- Elevation lat/long-->
                <x:Double>.8</x:Double>
                <x:Double>.8</x:Double>
            </x:Arguments>
        </maps:MapSpan>
    </x:Arguments>
</rdr:ExtendedMap>

and here's the xaml for a callout

<?xml version="1.0" encoding="utf-8"?>

<customMap:BindableMapCallout xmlns="http://xamarin.com/schemas/2014/forms"
                              xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                              xmlns:loc="clr-namespace:MyApp.Mobile.Localization;assembly=MyApp.Mobile"
                              xmlns:customMap="clr-namespace:MyApp.Mobile.CustomMap;assembly=MyApp.Mobile"
                              x:Class="MyApp.Mobile.Controls.StreetlightMarkerCallout"
                              Title="{loc:Translate StreetlightCallout_Title}">
    <StackLayout Padding="0">

        <!-- Address-->
        <Label Text="{loc:Translate StreetlightCallout_Address}"
               Style="{StaticResource Common-BoldText}" />
        <!-- this stupidity exists because the iOS callout doesn't auto-resize... yet. -->
        <Label Text="{Binding Address}" HeightRequest="45" WidthRequest="200">
            <Label.IsVisible>
                <OnPlatform x:TypeArguments="x:Boolean" Android="False" iOS="True" />
            </Label.IsVisible>
        </Label>
        <Label Text="{Binding Address}">
            <Label.IsVisible>
                <OnPlatform x:TypeArguments="x:Boolean" Android="True" iOS="False" />
            </Label.IsVisible>
        </Label>

        <Label Text="Repair Requested Date:"
               Style="{StaticResource Common-BoldText}"
               IsVisible="{Binding IsOut}" />
        <Label Text="{Binding RepairRequestedDate}"
               IsVisible="{Binding IsOut}" />

        <!--Information-->
        <Label Text="{loc:Translate StreetlightCallout_Info}"
               Style="{StaticResource Common-BoldText}" />
      <!-- this stupidity exists because the iOS callout doesn't auto-resize... yet. -->
      <Label Text="{Binding Info}" HeightRequest="65" WidthRequest="220">
        <Label.IsVisible>
          <OnPlatform x:TypeArguments="x:Boolean" Android="False" iOS="True" />
        </Label.IsVisible>
      </Label>
      <Label Text="{Binding Info}">
        <Label.IsVisible>
          <OnPlatform x:TypeArguments="x:Boolean" Android="True" iOS="False" />
        </Label.IsVisible>
      </Label>

        <!-- Report Button-->
        <Button Text="{loc:Translate StreetlightCallout_RepairButtonText}"
                HorizontalOptions="FillAndExpand"
                VerticalOptions="Center"
                Command="{Binding ReportStreetlightCommand}"
                BorderRadius="0"
                BorderWidth="0"
                CommandParameter="{Binding .}"
                IsVisible="{Binding SubmitButtonVisible}" />
    </StackLayout>
</customMap:BindableMapCallout>

Viewing all articles
Browse latest Browse all 77050

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>