SlideShare una empresa de Scribd logo
1 de 16
Descargar para leer sin conexión
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Custom Render
Los Custom Render proporcionan un enfoque poderoso para personalizar la apariencia y el
comportamiento de los controles de Xamarin.Forms. Se pueden usar para pequeños cambios de estilo o
diseño sofisticado específico de la plataforma, así mismo como la personalización del comportamiento.
Xamarin.Forms utiliza abstracciones para definir los elementos. Posteriormente se transforma cada
abstracción ofreciendo una implementación y mecanismo en cada plataforma
Con la llegada de la versión 1.3 de Xamarin.Forms llegaron los estilos, los cuales nos ayudan a definir
múltiples propiedades visuales de elementos de la interfaz de forma reutilizable.
Por lo tanto, para modificaciones visuales simples no es necesario realizar ningún tipo de Custom Render.
Pero entonces, ¿cuándo son necesarios los Custom Render?
Para responder lo anterior, tenemos distintas opciones:
• Modificar la apariencia de elementos a niveles no posibles por estilos.
• Modificar el comportamiento de elementos existentes.
• Crear nuevos controles personales.
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Los elementos de Xamarin.Forms (páginas, layouts y controles), utilizan una API común que permite crear
interfaces visuales con el mismo código para todas las plataformas. Cada página, layout o control se
renderiza de forma diferente en cada plataforma. El esquema de que ocurre es el siguiente:
Todos los elementos de Xamarin.Forms se componen de dos partes diferenciadas, Element y Renderer.
Element: Es una clase que define al control, es decir, es el conjunto de propiedades y eventos que
permitirán gestionar tanto la apariencia, contenido y comportamiento del mismo. En el esquema superior
nos centramos en el elemento Button. La clase Element define el conjunto de propiedades de contenido
(Text), como las de apariencia (TextColor) y eventos.
Renderer: El elemento definido se renderiza (transforma) en cada plataforma a un elemento 100% nativo.
En el esquema anterior, la clase Renderer en cada plataforma creará un control nativo, UIButton en iOS y
Button en Android, asignando las definiciones que vienen establecidas desde el Element.
Ahora bien, el proceso para crear una clase de Custom Render es el siguiente:
• Crear una subclase de la clase del render que brinde el control nativo.
• Reemplazar el método que hace que el control nativo y la lógica de escritura personalicen el
control. A menudo, el método OnElementChanged se usa para representar el control nativo, que
se invoca cuando se crea el control Xamarin.Forms correspondiente.
• Agregar un atributo ExportRenderer a la clase del Custom Render para especificar que se usará
para representar el control Xamarin.Forms. Este atributo se usa para registrar el Custom Render
con Xamarin.Forms.
Ing. Vicente G. Guzman Lucio
Xamarin Developer
El siguiente código muestra un ejemplo de subclases del control Entry:
public class MyEntry : Entry
{
public MyEntry ()
{
BackgroundColor = Color.Gray;
}
}
El control MyEntry es un control de entrada donde BackgroundColor se establece en gris, y se puede hacer
referencia en XAML al declarar un espacio de nombres para su ubicación y usar el prefijo del espacio de
nombres en el elemento de control. El siguiente ejemplo de código muestra cómo un ContentPage puede
consumir el control personalizado MyEntry:
<ContentPage
...
xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
...>
...
<local:MyEntry Text="Xamarin Basic Concepts Code" />
...
</ContentPage>
El prefijo del espacio de nombres local puede ser cualquier cosa. Sin embargo, los valores de espacio de
nombre y ensamblaje deben coincidir con los detalles del control personalizado. Una vez que se declara
el espacio de nombres, el prefijo se utiliza para hacer referencia al control personalizado.
Ing. Vicente G. Guzman Lucio
Xamarin Developer
A continuación, conocerás el proceso para crear un Custom Render enfocado a visualizar Google Maps.
CODING TIME
Empecemos generando una nueva aplicación Cross Platform App (Xamarin).
Denominémosla como CustomRenders
Elijamos la platilla en blanco con las siguientes opciones: Xamarin.Forms – PCL
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Una vez creado nuestra solución, generemos las carpetas Controls y Views en nuestro proyecto Portable,
en donde agregaremos las clases relacionadas a las necesidades que soportara la aplicación. En Android
y iOS, solo agreguemos la carpeta Renders.
Antes Después
Primeramente, en Views agregaremos un ContenPage, la cual será nuestra pantalla de inicio de sesión
(LoginPage), después añadiremos una TabbedPage, que será la de la funcionalidad principal.
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Modifiquemos el archivo LoginPage, por el siguiente código:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CustomRenders.Views.LoginPage">
<ContentPage.Content>
<StackLayout VerticalOptions="StartAndExpand">
<Label Text="Username" />
<Entry x:Name="usernameEntry" Placeholder="username" />
<Label Text="Password" />
<Entry x:Name="passwordEntry" IsPassword="true" />
<Button Text="Login" Clicked="OnLoginButtonClicked" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
Antes:
Después:
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Ahora en nuestro archivo .CS, agreguemos la navegación hacia nuestra pantalla de inicio (HomePAge)
async void OnLoginButtonClicked(object sender, EventArgs e)
{
await Navigation.PushModalAsync(new HomePage());
}
Antes:
Después:
Nota: Si te aparece la pantalla de Welcome to Xamarin.Forms!, es que se te olvido algo…
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Tip – Es en el archivo App.xaml.cs
Después de realizar esto, en nuestro archivo de HomePage, en el Tab 2, agregaremos la funcionalidad
del mapa, pero antes de esto, es necesario, realizar lo siguiente:
Primero debemos instalar los Nugets: Xamarin.Forms.Maps y Xam.Plugin.Geolocator en todos los
proyectos (PCL, Android y iOS), para esto, solo hacemos click secundario en References (PCL) - Manage
Nuget Packages - Browse – Xamarin.Forms.Maps - Install
Ahora bien, en nuestro PCL, dentro de la carpeta Controls, agregaremos una nueva clase con el nombre
de CustomMap. Esta clase heredara de algún otro elemento que contenga ya el comportamiento o
aspecto visual similar al objetivo buscado, en nuestro caso, el mostrar un Mapa (Map).
Editemos la clase, de tal forma que quede así:
using Xamarin.Forms.Maps;
namespace CustomRenders.Controls
{
public class CustomMap : Map
{
public CustomCircle Circle { get; set; }
}
}
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Antes:
Después:
Al hacer esto, CustomCircle nos indica que no puede ser encontrado o que nos falta alguna referencia
que indique su existencia, para ello, en nuestra misma carpeta crearemos su clase.
La que llevara la información necesaria para indicar el posicionamiento de nuestro dispositivo.
using Xamarin.Forms.Maps;
namespace CustomRenders.Controls
{
public class CustomCircle
{
public Position Position { get; set; }
public double Radius { get; set; }
}
}
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Posteriormente, en nuestra carpeta de Renders del proyecto Android, agregaremos una clase
(CustomMapRenderer), la cual llevara toda la lógica del Mapa.
Antes de continuar, recordemos el último punto del proceso:
• Agregar un atributo ExportRenderer a la clase del Custom Render para especificar que se usará
para representar el control Xamarin.Forms. Este atributo se usa para registrar el Custom Render
con Xamarin.Forms.
Tomando en cuenta esto, deberemos de añadir el siguiente atributo
[assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))]
El cual va después de los “using”, y al cual le estamos definiendo el control del que hereda y el tipo.
Ya con esto, agreguemos el siguiente bloque de código:
/// <summary>
/// Render para los mapas personalizados
/// </summary>
public class CustomMapRenderer : MapRenderer
{
CustomCircle circle;
bool isDrawn;
protected override void
OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.Map
s.Map> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// Unsubscribe
}
if (e.NewElement != null)
{
var formsMap = (CustomMap)e.NewElement;
Ing. Vicente G. Guzman Lucio
Xamarin Developer
circle = formsMap.Circle;
Control.GetMapAsync(this);
}
}
protected override void OnElementPropertyChanged(object sender,
System.ComponentModel.PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName.Equals("VisibleRegion") && !isDrawn)
{
var circleOptions = new CircleOptions();
circleOptions.InvokeCenter(new LatLng(circle.Position.Latitude,
circle.Position.Longitude));
circleOptions.InvokeRadius(circle.Radius);
circleOptions.InvokeFillColor(0x66ffff00);
circleOptions.InvokeStrokeColor(0x66ffff00);
circleOptions.InvokeStrokeWidth(0);
NativeMap.AddCircle(circleOptions);
isDrawn = true;
}
}
}
}
Ahora regresemos a nuestro archivo HomePage.xaml, al cual le declararemos un espacio de nombres para
poder ubicar al control:
xmlns:controls="clr-namespace:CustomRenders.Controls"
Posterior a esto, es necesario el acceder al prefijo antes declarado para así integrar nuestro control:
<controls:CustomMap
x:Name="customMap"
AbsoluteLayout.LayoutBounds="0,0,1,1"
AbsoluteLayout.LayoutFlags="All"
IsShowingUser="true"
MapType="Street" />
Ing. Vicente G. Guzman Lucio
Xamarin Developer
XAML - HomePage
En nuestro .CS (HomePage.xaml.cs) deberemos de indicarle al mapa nuestra posición, la cual como
sabemos deriva de latitud y longitud, para poder realizar esto, creemos una carpeta el proyecto PCL que
se llame Models, el cual llevara una clase denominada Location, la que contara con lo siguiente:
namespace CustomRenders.Models
{
public class Location
{
public static double Latitude { get; set; }
public static double Longitude { get; set; }
}
}
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Contemplando lo anterior, editemos nuestro .CS de tal forma que quede semejante a este:
using CustomRenders.Controls;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Xaml;
namespace CustomRenders.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class HomePage : TabbedPage
{
string location;
public HomePage()
{
InitializeComponent();
var pin = new Pin
{
Type = PinType.Place,
Position = new Position(Models.Location.Latitude,
Models.Location.Longitude),
Label = "Aqui estoy...",
Address = ""
};
location = $"{pin.Position.Latitude}|{pin.Position.Longitude}";
var position = new Position(Models.Location.Latitude,
Models.Location.Longitude);
customMap.Circle = new CustomCircle
{
Position = position,
Radius = 2500
};
customMap.Pins.Add(pin);
customMap.MoveToRegion(MapSpan.FromCenterAndRadius(position,
Distance.FromMiles(1.0)));
}
}
}
Ya para casi finalizar, en nuestro archivo AndroidManifest que se encuentra dentro de Properties,
deberemos de agregar el siguiente meta-data, el cual indica el uso de los mapas de Google:
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="########" />
Para adquirir el value, bastara con que naveguemos al portal:
https://developers.google.com/maps/documentation/static-maps/intro
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Y demos clic al botón de:
A continuación, solo seguiremos los pasos que se indiquen y después no arrojara la clave que
ingresaremos en el paso anterior.
En nuestro archivo App.xaml.cs indicaremos mediante el plugin de Geolocator que nos ubique con
respecto a nuestra posición actual, a través del siguiente código:
var maplocator = CrossGeolocator.Current;
maplocator.DesiredAccuracy = 500;
var geoCoder = new Geocoder(); Device.BeginInvokeOnMainThread(async () =>
{
try
{
if (!maplocator.IsListening)
{
Ing. Vicente G. Guzman Lucio
Xamarin Developer
await maplocator.StartListeningAsync(TimeSpan.FromMinutes(1), 50,
true);
}
}
catch (Exception ex)
{ }
});
maplocator.PositionChanged += (sender, e) =>
{
var position = e.Position;
Models.Location.Latitude = position.Latitude;
Models.Location.Longitude = position.Longitude;
};
Por último, no olvidemos habilitar los permisos en el AndroidManifest:
- ACCESS_COARSE_LOCATION
- ACCESS_FINE_LOCATION
- ACCESS_LOCATION_EXTRA_COMMANDS
- ACCESS_MOCK_LOCATION
- INTERNET
Y agregar la siguiente línea en nuestro MainActivity.cs
Xamarin.FormsMaps.Init(this, bundle);
Ing. Vicente G. Guzman Lucio
Xamarin Developer
Con esto habremos terminado, revisemos el resultado, ejecutemos…
Mas información: Entry Custom Renderer

Más contenido relacionado

Similar a Custom Renders Xamarin.Forms

Extendiendo Xamarin.Forms con Custom Renders
Extendiendo Xamarin.Forms con Custom RendersExtendiendo Xamarin.Forms con Custom Renders
Extendiendo Xamarin.Forms con Custom RendersJavier Suárez Ruiz
 
Creando controles para Xamarin.Forms
Creando controles para Xamarin.FormsCreando controles para Xamarin.Forms
Creando controles para Xamarin.FormsJavier Suárez Ruiz
 
Topicos Selectos de Xamarin
Topicos Selectos de XamarinTopicos Selectos de Xamarin
Topicos Selectos de XamarinLuis Beltran
 
Php Bitter Sweet Symfony!
Php Bitter Sweet Symfony!Php Bitter Sweet Symfony!
Php Bitter Sweet Symfony!Ricard Luquero
 
LabAndroid: Taller "Mi Primera Aplicación Android"
LabAndroid: Taller "Mi Primera Aplicación Android"LabAndroid: Taller "Mi Primera Aplicación Android"
LabAndroid: Taller "Mi Primera Aplicación Android"Alberto Ruibal
 
Framework .NET 3.5 06 Operativa básica del framework .net
Framework .NET 3.5 06 Operativa básica del framework .netFramework .NET 3.5 06 Operativa básica del framework .net
Framework .NET 3.5 06 Operativa básica del framework .netAntonio Palomares Sender
 
Primeros pasos con Backbone js, por Xavier Aznar
Primeros pasos con Backbone js, por Xavier AznarPrimeros pasos con Backbone js, por Xavier Aznar
Primeros pasos con Backbone js, por Xavier AznarPablo Aguilera
 
Resumen el gran libro de andorid
Resumen el gran libro de andoridResumen el gran libro de andorid
Resumen el gran libro de andoridJilton Delgado
 
INFOSAN VISUAL BASIC
INFOSAN VISUAL BASICINFOSAN VISUAL BASIC
INFOSAN VISUAL BASICFRANCIACOCO
 

Similar a Custom Renders Xamarin.Forms (20)

Extendiendo Xamarin.Forms
Extendiendo Xamarin.FormsExtendiendo Xamarin.Forms
Extendiendo Xamarin.Forms
 
Extendiendo Xamarin.Forms con Custom Renders
Extendiendo Xamarin.Forms con Custom RendersExtendiendo Xamarin.Forms con Custom Renders
Extendiendo Xamarin.Forms con Custom Renders
 
Custom Renderers Made Simple
Custom Renderers Made SimpleCustom Renderers Made Simple
Custom Renderers Made Simple
 
Creando controles para Xamarin.Forms
Creando controles para Xamarin.FormsCreando controles para Xamarin.Forms
Creando controles para Xamarin.Forms
 
Windows.forms.ejercicios
Windows.forms.ejerciciosWindows.forms.ejercicios
Windows.forms.ejercicios
 
Topicos Selectos de Xamarin
Topicos Selectos de XamarinTopicos Selectos de Xamarin
Topicos Selectos de Xamarin
 
Php Bitter Sweet Symfony!
Php Bitter Sweet Symfony!Php Bitter Sweet Symfony!
Php Bitter Sweet Symfony!
 
Novedades Xamarin.Forms 2
Novedades Xamarin.Forms 2Novedades Xamarin.Forms 2
Novedades Xamarin.Forms 2
 
LabAndroid: Taller "Mi Primera Aplicación Android"
LabAndroid: Taller "Mi Primera Aplicación Android"LabAndroid: Taller "Mi Primera Aplicación Android"
LabAndroid: Taller "Mi Primera Aplicación Android"
 
Mi dlet
Mi dletMi dlet
Mi dlet
 
Framework .NET 3.5 06 Operativa básica del framework .net
Framework .NET 3.5 06 Operativa básica del framework .netFramework .NET 3.5 06 Operativa básica del framework .net
Framework .NET 3.5 06 Operativa básica del framework .net
 
Primeros pasos con Backbone js, por Xavier Aznar
Primeros pasos con Backbone js, por Xavier AznarPrimeros pasos con Backbone js, por Xavier Aznar
Primeros pasos con Backbone js, por Xavier Aznar
 
Controles Telerik {Rate App Reminder}
Controles Telerik {Rate App Reminder}Controles Telerik {Rate App Reminder}
Controles Telerik {Rate App Reminder}
 
Resumen el gran libro de andorid
Resumen el gran libro de andoridResumen el gran libro de andorid
Resumen el gran libro de andorid
 
Aplicación abc. asp net mvc 3
Aplicación abc. asp net mvc 3Aplicación abc. asp net mvc 3
Aplicación abc. asp net mvc 3
 
DotNetDom: El futuro de Xamarin
DotNetDom: El futuro de XamarinDotNetDom: El futuro de Xamarin
DotNetDom: El futuro de Xamarin
 
Sesion 02 clases en_vb_net
Sesion 02 clases en_vb_netSesion 02 clases en_vb_net
Sesion 02 clases en_vb_net
 
.NET Day Guatemala
.NET Day Guatemala.NET Day Guatemala
.NET Day Guatemala
 
INFOSAN VISUAL BASIC
INFOSAN VISUAL BASICINFOSAN VISUAL BASIC
INFOSAN VISUAL BASIC
 
Vb
VbVb
Vb
 

Más de Vicente Gerardo Guzman Lucio

Bienvenido .Net MAUI - la evolución de Xamarin.Forms
Bienvenido .Net MAUI - la evolución de Xamarin.FormsBienvenido .Net MAUI - la evolución de Xamarin.Forms
Bienvenido .Net MAUI - la evolución de Xamarin.FormsVicente Gerardo Guzman Lucio
 
Consumiendo un servicio externo con Axios en Alexa
Consumiendo un servicio externo con Axios en AlexaConsumiendo un servicio externo con Axios en Alexa
Consumiendo un servicio externo con Axios en AlexaVicente Gerardo Guzman Lucio
 

Más de Vicente Gerardo Guzman Lucio (20)

GPPB2024 - Integrando ChatGPT en Power Automate
GPPB2024 - Integrando ChatGPT en Power AutomateGPPB2024 - Integrando ChatGPT en Power Automate
GPPB2024 - Integrando ChatGPT en Power Automate
 
Introducción a Amazon Alexa.pptx
Introducción a Amazon Alexa.pptxIntroducción a Amazon Alexa.pptx
Introducción a Amazon Alexa.pptx
 
Creando un Chatbot en C# con ChatGPT.pdf
Creando un Chatbot en C# con ChatGPT.pdfCreando un Chatbot en C# con ChatGPT.pdf
Creando un Chatbot en C# con ChatGPT.pdf
 
ChatGPT & Alexa.pptx
ChatGPT & Alexa.pptxChatGPT & Alexa.pptx
ChatGPT & Alexa.pptx
 
Bienvenido .Net MAUI - la evolución de Xamarin.Forms
Bienvenido .Net MAUI - la evolución de Xamarin.FormsBienvenido .Net MAUI - la evolución de Xamarin.Forms
Bienvenido .Net MAUI - la evolución de Xamarin.Forms
 
Conectando un Azure Bot con una Alexa Skill
Conectando un Azure Bot con una Alexa SkillConectando un Azure Bot con una Alexa Skill
Conectando un Azure Bot con una Alexa Skill
 
Azure DevOps y Blazor Web Assembly
Azure DevOps y Blazor Web AssemblyAzure DevOps y Blazor Web Assembly
Azure DevOps y Blazor Web Assembly
 
Desarrollo de Interfaces de Voz: Alexa Skills
Desarrollo de Interfaces de Voz: Alexa SkillsDesarrollo de Interfaces de Voz: Alexa Skills
Desarrollo de Interfaces de Voz: Alexa Skills
 
Blazor vs VUE
Blazor vs VUEBlazor vs VUE
Blazor vs VUE
 
Introducción a Blazor
Introducción a BlazorIntroducción a Blazor
Introducción a Blazor
 
Infraestructura como Código en Azure
Infraestructura como Código en AzureInfraestructura como Código en Azure
Infraestructura como Código en Azure
 
Diseño de Experiencias de Voz con Amazon Alexa
Diseño de Experiencias de Voz con Amazon AlexaDiseño de Experiencias de Voz con Amazon Alexa
Diseño de Experiencias de Voz con Amazon Alexa
 
Alexa Skill con .NETCore & AWS Lambda
Alexa Skill con .NETCore & AWS LambdaAlexa Skill con .NETCore & AWS Lambda
Alexa Skill con .NETCore & AWS Lambda
 
Skills Nights - Vol.III - Primeros Pasos
Skills Nights - Vol.III - Primeros PasosSkills Nights - Vol.III - Primeros Pasos
Skills Nights - Vol.III - Primeros Pasos
 
¿Qué es la Nube?
¿Qué es la Nube?¿Qué es la Nube?
¿Qué es la Nube?
 
Consumiendo un servicio externo con Axios en Alexa
Consumiendo un servicio externo con Axios en AlexaConsumiendo un servicio externo con Axios en Alexa
Consumiendo un servicio externo con Axios en Alexa
 
La era de los Chatbots
La era de los ChatbotsLa era de los Chatbots
La era de los Chatbots
 
Android 64x con Xamarin.Forms
Android 64x con Xamarin.FormsAndroid 64x con Xamarin.Forms
Android 64x con Xamarin.Forms
 
Creando nuestra propia Skill de YouTube
Creando nuestra propia Skill de YouTubeCreando nuestra propia Skill de YouTube
Creando nuestra propia Skill de YouTube
 
Alexa Skill en 5 pasos
Alexa Skill en 5 pasosAlexa Skill en 5 pasos
Alexa Skill en 5 pasos
 

Custom Renders Xamarin.Forms

  • 1. Ing. Vicente G. Guzman Lucio Xamarin Developer Custom Render Los Custom Render proporcionan un enfoque poderoso para personalizar la apariencia y el comportamiento de los controles de Xamarin.Forms. Se pueden usar para pequeños cambios de estilo o diseño sofisticado específico de la plataforma, así mismo como la personalización del comportamiento. Xamarin.Forms utiliza abstracciones para definir los elementos. Posteriormente se transforma cada abstracción ofreciendo una implementación y mecanismo en cada plataforma Con la llegada de la versión 1.3 de Xamarin.Forms llegaron los estilos, los cuales nos ayudan a definir múltiples propiedades visuales de elementos de la interfaz de forma reutilizable. Por lo tanto, para modificaciones visuales simples no es necesario realizar ningún tipo de Custom Render. Pero entonces, ¿cuándo son necesarios los Custom Render? Para responder lo anterior, tenemos distintas opciones: • Modificar la apariencia de elementos a niveles no posibles por estilos. • Modificar el comportamiento de elementos existentes. • Crear nuevos controles personales.
  • 2. Ing. Vicente G. Guzman Lucio Xamarin Developer Los elementos de Xamarin.Forms (páginas, layouts y controles), utilizan una API común que permite crear interfaces visuales con el mismo código para todas las plataformas. Cada página, layout o control se renderiza de forma diferente en cada plataforma. El esquema de que ocurre es el siguiente: Todos los elementos de Xamarin.Forms se componen de dos partes diferenciadas, Element y Renderer. Element: Es una clase que define al control, es decir, es el conjunto de propiedades y eventos que permitirán gestionar tanto la apariencia, contenido y comportamiento del mismo. En el esquema superior nos centramos en el elemento Button. La clase Element define el conjunto de propiedades de contenido (Text), como las de apariencia (TextColor) y eventos. Renderer: El elemento definido se renderiza (transforma) en cada plataforma a un elemento 100% nativo. En el esquema anterior, la clase Renderer en cada plataforma creará un control nativo, UIButton en iOS y Button en Android, asignando las definiciones que vienen establecidas desde el Element. Ahora bien, el proceso para crear una clase de Custom Render es el siguiente: • Crear una subclase de la clase del render que brinde el control nativo. • Reemplazar el método que hace que el control nativo y la lógica de escritura personalicen el control. A menudo, el método OnElementChanged se usa para representar el control nativo, que se invoca cuando se crea el control Xamarin.Forms correspondiente. • Agregar un atributo ExportRenderer a la clase del Custom Render para especificar que se usará para representar el control Xamarin.Forms. Este atributo se usa para registrar el Custom Render con Xamarin.Forms.
  • 3. Ing. Vicente G. Guzman Lucio Xamarin Developer El siguiente código muestra un ejemplo de subclases del control Entry: public class MyEntry : Entry { public MyEntry () { BackgroundColor = Color.Gray; } } El control MyEntry es un control de entrada donde BackgroundColor se establece en gris, y se puede hacer referencia en XAML al declarar un espacio de nombres para su ubicación y usar el prefijo del espacio de nombres en el elemento de control. El siguiente ejemplo de código muestra cómo un ContentPage puede consumir el control personalizado MyEntry: <ContentPage ... xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer" ...> ... <local:MyEntry Text="Xamarin Basic Concepts Code" /> ... </ContentPage> El prefijo del espacio de nombres local puede ser cualquier cosa. Sin embargo, los valores de espacio de nombre y ensamblaje deben coincidir con los detalles del control personalizado. Una vez que se declara el espacio de nombres, el prefijo se utiliza para hacer referencia al control personalizado.
  • 4. Ing. Vicente G. Guzman Lucio Xamarin Developer A continuación, conocerás el proceso para crear un Custom Render enfocado a visualizar Google Maps. CODING TIME Empecemos generando una nueva aplicación Cross Platform App (Xamarin). Denominémosla como CustomRenders Elijamos la platilla en blanco con las siguientes opciones: Xamarin.Forms – PCL
  • 5. Ing. Vicente G. Guzman Lucio Xamarin Developer Una vez creado nuestra solución, generemos las carpetas Controls y Views en nuestro proyecto Portable, en donde agregaremos las clases relacionadas a las necesidades que soportara la aplicación. En Android y iOS, solo agreguemos la carpeta Renders. Antes Después Primeramente, en Views agregaremos un ContenPage, la cual será nuestra pantalla de inicio de sesión (LoginPage), después añadiremos una TabbedPage, que será la de la funcionalidad principal.
  • 6. Ing. Vicente G. Guzman Lucio Xamarin Developer Modifiquemos el archivo LoginPage, por el siguiente código: <?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="CustomRenders.Views.LoginPage"> <ContentPage.Content> <StackLayout VerticalOptions="StartAndExpand"> <Label Text="Username" /> <Entry x:Name="usernameEntry" Placeholder="username" /> <Label Text="Password" /> <Entry x:Name="passwordEntry" IsPassword="true" /> <Button Text="Login" Clicked="OnLoginButtonClicked" /> </StackLayout> </ContentPage.Content> </ContentPage> Antes: Después:
  • 7. Ing. Vicente G. Guzman Lucio Xamarin Developer Ahora en nuestro archivo .CS, agreguemos la navegación hacia nuestra pantalla de inicio (HomePAge) async void OnLoginButtonClicked(object sender, EventArgs e) { await Navigation.PushModalAsync(new HomePage()); } Antes: Después: Nota: Si te aparece la pantalla de Welcome to Xamarin.Forms!, es que se te olvido algo…
  • 8. Ing. Vicente G. Guzman Lucio Xamarin Developer Tip – Es en el archivo App.xaml.cs Después de realizar esto, en nuestro archivo de HomePage, en el Tab 2, agregaremos la funcionalidad del mapa, pero antes de esto, es necesario, realizar lo siguiente: Primero debemos instalar los Nugets: Xamarin.Forms.Maps y Xam.Plugin.Geolocator en todos los proyectos (PCL, Android y iOS), para esto, solo hacemos click secundario en References (PCL) - Manage Nuget Packages - Browse – Xamarin.Forms.Maps - Install Ahora bien, en nuestro PCL, dentro de la carpeta Controls, agregaremos una nueva clase con el nombre de CustomMap. Esta clase heredara de algún otro elemento que contenga ya el comportamiento o aspecto visual similar al objetivo buscado, en nuestro caso, el mostrar un Mapa (Map). Editemos la clase, de tal forma que quede así: using Xamarin.Forms.Maps; namespace CustomRenders.Controls { public class CustomMap : Map { public CustomCircle Circle { get; set; } } }
  • 9. Ing. Vicente G. Guzman Lucio Xamarin Developer Antes: Después: Al hacer esto, CustomCircle nos indica que no puede ser encontrado o que nos falta alguna referencia que indique su existencia, para ello, en nuestra misma carpeta crearemos su clase. La que llevara la información necesaria para indicar el posicionamiento de nuestro dispositivo. using Xamarin.Forms.Maps; namespace CustomRenders.Controls { public class CustomCircle { public Position Position { get; set; } public double Radius { get; set; } } }
  • 10. Ing. Vicente G. Guzman Lucio Xamarin Developer Posteriormente, en nuestra carpeta de Renders del proyecto Android, agregaremos una clase (CustomMapRenderer), la cual llevara toda la lógica del Mapa. Antes de continuar, recordemos el último punto del proceso: • Agregar un atributo ExportRenderer a la clase del Custom Render para especificar que se usará para representar el control Xamarin.Forms. Este atributo se usa para registrar el Custom Render con Xamarin.Forms. Tomando en cuenta esto, deberemos de añadir el siguiente atributo [assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))] El cual va después de los “using”, y al cual le estamos definiendo el control del que hereda y el tipo. Ya con esto, agreguemos el siguiente bloque de código: /// <summary> /// Render para los mapas personalizados /// </summary> public class CustomMapRenderer : MapRenderer { CustomCircle circle; bool isDrawn; protected override void OnElementChanged(Xamarin.Forms.Platform.Android.ElementChangedEventArgs<Xamarin.Forms.Map s.Map> e) { base.OnElementChanged(e); if (e.OldElement != null) { // Unsubscribe } if (e.NewElement != null) { var formsMap = (CustomMap)e.NewElement;
  • 11. Ing. Vicente G. Guzman Lucio Xamarin Developer circle = formsMap.Circle; Control.GetMapAsync(this); } } protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (e.PropertyName.Equals("VisibleRegion") && !isDrawn) { var circleOptions = new CircleOptions(); circleOptions.InvokeCenter(new LatLng(circle.Position.Latitude, circle.Position.Longitude)); circleOptions.InvokeRadius(circle.Radius); circleOptions.InvokeFillColor(0x66ffff00); circleOptions.InvokeStrokeColor(0x66ffff00); circleOptions.InvokeStrokeWidth(0); NativeMap.AddCircle(circleOptions); isDrawn = true; } } } } Ahora regresemos a nuestro archivo HomePage.xaml, al cual le declararemos un espacio de nombres para poder ubicar al control: xmlns:controls="clr-namespace:CustomRenders.Controls" Posterior a esto, es necesario el acceder al prefijo antes declarado para así integrar nuestro control: <controls:CustomMap x:Name="customMap" AbsoluteLayout.LayoutBounds="0,0,1,1" AbsoluteLayout.LayoutFlags="All" IsShowingUser="true" MapType="Street" />
  • 12. Ing. Vicente G. Guzman Lucio Xamarin Developer XAML - HomePage En nuestro .CS (HomePage.xaml.cs) deberemos de indicarle al mapa nuestra posición, la cual como sabemos deriva de latitud y longitud, para poder realizar esto, creemos una carpeta el proyecto PCL que se llame Models, el cual llevara una clase denominada Location, la que contara con lo siguiente: namespace CustomRenders.Models { public class Location { public static double Latitude { get; set; } public static double Longitude { get; set; } } }
  • 13. Ing. Vicente G. Guzman Lucio Xamarin Developer Contemplando lo anterior, editemos nuestro .CS de tal forma que quede semejante a este: using CustomRenders.Controls; using Xamarin.Forms; using Xamarin.Forms.Maps; using Xamarin.Forms.Xaml; namespace CustomRenders.Views { [XamlCompilation(XamlCompilationOptions.Compile)] public partial class HomePage : TabbedPage { string location; public HomePage() { InitializeComponent(); var pin = new Pin { Type = PinType.Place, Position = new Position(Models.Location.Latitude, Models.Location.Longitude), Label = "Aqui estoy...", Address = "" }; location = $"{pin.Position.Latitude}|{pin.Position.Longitude}"; var position = new Position(Models.Location.Latitude, Models.Location.Longitude); customMap.Circle = new CustomCircle { Position = position, Radius = 2500 }; customMap.Pins.Add(pin); customMap.MoveToRegion(MapSpan.FromCenterAndRadius(position, Distance.FromMiles(1.0))); } } } Ya para casi finalizar, en nuestro archivo AndroidManifest que se encuentra dentro de Properties, deberemos de agregar el siguiente meta-data, el cual indica el uso de los mapas de Google: <meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="########" /> Para adquirir el value, bastara con que naveguemos al portal: https://developers.google.com/maps/documentation/static-maps/intro
  • 14. Ing. Vicente G. Guzman Lucio Xamarin Developer Y demos clic al botón de: A continuación, solo seguiremos los pasos que se indiquen y después no arrojara la clave que ingresaremos en el paso anterior. En nuestro archivo App.xaml.cs indicaremos mediante el plugin de Geolocator que nos ubique con respecto a nuestra posición actual, a través del siguiente código: var maplocator = CrossGeolocator.Current; maplocator.DesiredAccuracy = 500; var geoCoder = new Geocoder(); Device.BeginInvokeOnMainThread(async () => { try { if (!maplocator.IsListening) {
  • 15. Ing. Vicente G. Guzman Lucio Xamarin Developer await maplocator.StartListeningAsync(TimeSpan.FromMinutes(1), 50, true); } } catch (Exception ex) { } }); maplocator.PositionChanged += (sender, e) => { var position = e.Position; Models.Location.Latitude = position.Latitude; Models.Location.Longitude = position.Longitude; }; Por último, no olvidemos habilitar los permisos en el AndroidManifest: - ACCESS_COARSE_LOCATION - ACCESS_FINE_LOCATION - ACCESS_LOCATION_EXTRA_COMMANDS - ACCESS_MOCK_LOCATION - INTERNET Y agregar la siguiente línea en nuestro MainActivity.cs Xamarin.FormsMaps.Init(this, bundle);
  • 16. Ing. Vicente G. Guzman Lucio Xamarin Developer Con esto habremos terminado, revisemos el resultado, ejecutemos… Mas información: Entry Custom Renderer