Menú Flotante en Xamarin Forms

Menú Flotante en Xamarin Forms
Menú Flotante en Xamarin Forms

Hola amigos de JaapSystem, espero se encuentren muy bien y sigan aprendiendo de esta herramienta muy útil que es Xamarin Forms y por supuesto sigan aprendiendo aquí en JaapSystem donde todo es mas fácil :D, compartan la pagina para que mas personas conozcan sobre esta herramienta que día a día está creciendo más, hoy veremos la creación de un componente el cual hemos llamado Menú Flotante en Xamarin Forms. Ya que presenta la característica de un menú el cual podremos agregar en cualquier proyecto, muy pronto realizare el mismo ejemplo pero en MVVM para que puedan llevar un mejor uso de las herramientas y de esa forma dividir, el Model View y ViewModel de nuestro proyecto. Sigamos los pasos para poder realizar este menú:

Sigamos los pasos para poder realizar este menú:

1.- Creamos nuestro proyecto, si no saben; reciben los ejemplos anteriores para que puedan aprender a como crear un proyecto en Xamarin Forms. También pueden descargar el ejemplo de MichiGato que realice hace algunos días.

2.- Creamos un archivo .XAML al cual le pondremos como nombre FilterMenu, quien será el encargado de contener nuestras imágenes, y realizar la funcionalidad animada, en este archivo es donde agregaremos toda la lógica, usaremos algunos métodos que nos ayudan a agregar animaciones a nuestro menú.

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Menu_Flotante.FilterMenu">
  <ContentView.Content>
    <Grid>
      <Image x:Name="OuterCircle" WidthRequest="60" HeightRequest="60" VerticalOptions="Center" HorizontalOptions="Center" Source="outer_circle"></Image>
      <Image x:Name="InnerButtonMenu" Opacity="1" WidthRequest="60" HeightRequest="60" VerticalOptions="Center" HorizontalOptions="Center" Source="menu_circle"></Image>
      <Image x:Name="InnerButtonClose" Opacity="0" WidthRequest="60" HeightRequest="60" VerticalOptions="Center" HorizontalOptions="Center" Source="close_circle"></Image>
      <!-- NW -->
      <Image x:Name="NW" Opacity="0" Margin="0,0,90,90" Source="menu_acorn" WidthRequest="38" HeightRequest="38" VerticalOptions="Center" HorizontalOptions="Center"></Image>
      <!-- W -->
      <Image x:Name="W" Opacity="0" Margin="0,0,130,0" Source="menu_add_person" WidthRequest="38" HeightRequest="38" VerticalOptions="Center" HorizontalOptions="Center"></Image>
      <!-- SW -->
      <Image x:Name="SW" Opacity="0" Margin="0,90,90,0" Source="menu_award" WidthRequest="38" HeightRequest="38" VerticalOptions="Center" HorizontalOptions="Center"></Image>
      <!-- SE -->
      <Image x:Name="SE" Opacity="0" Margin="90,90,0,0" Source="menu_cow" WidthRequest="38" HeightRequest="38" VerticalOptions="Center" HorizontalOptions="Center"></Image>
      <!-- E -->
      <Image x:Name="E" Opacity="0" Margin="130,0,0,0" Source="menu_factory" WidthRequest="38" HeightRequest="38" VerticalOptions="Center" HorizontalOptions="Center"></Image>
      <!-- NE -->
      <Image x:Name="NE" Opacity="0" Margin="90,0,0,90" Source="menu_lorry" WidthRequest="38" HeightRequest="38" VerticalOptions="Center" HorizontalOptions="Center"></Image>
      <!-- N -->
      <Image x:Name="S" Opacity="0" Margin="0,130,0,0" Source="menu_paint" WidthRequest="38" HeightRequest="38" VerticalOptions="Center" HorizontalOptions="Center"></Image>
      <!-- S -->
      <Image x:Name="N" Opacity="0" Margin="0,0,0,130" Source="menu_plane" WidthRequest="38" HeightRequest="38" VerticalOptions="Center" HorizontalOptions="Center"></Image>
    </Grid>
  </ContentView.Content>
</ContentView>
using System;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Menu_Flotante
{
    public partial class FilterMenu : ContentView
    {
        public event EventHandler ItemTapped;

        private bool _isAnimating = false;
        private uint _animationDelay = 300;

        public FilterMenu()
        {
            InitializeComponent();

            InnerButtonClose.IsVisible = false;
            InnerButtonMenu.IsVisible = true;
            HandleMenuCenterClicked();
            HandleCloseClicked();

            HandleOptionsClicked();
        }

        private void HandleOptionsClicked()
        {
            HandleOptionClicked(N, "Plane");
            HandleOptionClicked(NE, "Van");
            HandleOptionClicked(E, "Factory");
            HandleOptionClicked(SE, "Cow");
            HandleOptionClicked(S, "Paintbrush");
            HandleOptionClicked(SW, "Award");
            HandleOptionClicked(W, "Add Person");
            HandleOptionClicked(NW, "Acorn");

        }

        private void HandleOptionClicked(Image image, string value)
        {
            image.GestureRecognizers.Add(new TapGestureRecognizer()
            {
                Command = new Command(() =>
                {
                    ItemTapped?.Invoke(this, new SelectedItemChangedEventArgs(value));
                    CloseMenu();
                }),
                NumberOfTapsRequired = 1
            });
        }

        private void HandleCloseClicked()
        {
            InnerButtonClose.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = new Command(async () =>
                {
                    await CloseMenu();
                }),
                NumberOfTapsRequired = 1
            });

        }

        private async Task CloseMenu()
        {
            if (!_isAnimating)
            {

                _isAnimating = true;

                InnerButtonMenu.IsVisible = true;
                InnerButtonClose.IsVisible = true;
                await HideButtons();

                InnerButtonClose.RotateTo(0, _animationDelay);
                InnerButtonClose.FadeTo(0, _animationDelay);
                InnerButtonMenu.RotateTo(0, _animationDelay);
                InnerButtonMenu.FadeTo(1, _animationDelay);
                await OuterCircle.ScaleTo(1, 1000, Easing.BounceOut);
                InnerButtonClose.IsVisible = false;

                _isAnimating = false;
            }
        }

        private void HandleMenuCenterClicked()
        {
            InnerButtonMenu.GestureRecognizers.Add(new TapGestureRecognizer
            {
                Command = new Command(async () =>
                {
                    if (!_isAnimating)
                    {
                        _isAnimating = true;

                        InnerButtonClose.IsVisible = true;
                        InnerButtonMenu.IsVisible = true;

                        InnerButtonMenu.RotateTo(360, _animationDelay);
                        InnerButtonMenu.FadeTo(0, _animationDelay);
                        InnerButtonClose.RotateTo(360, _animationDelay);
                        InnerButtonClose.FadeTo(1, _animationDelay);

                        await OuterCircle.ScaleTo(3.3, 1000, Easing.BounceIn);
                        await ShowButtons();
                        InnerButtonMenu.IsVisible = false;

                        _isAnimating = false;

                    }
                }),
                NumberOfTapsRequired = 1
            });

        }

        private async Task HideButtons()
        {
            var speed = 25U;
            await N.FadeTo(0, speed);
            await NE.FadeTo(0, speed);
            await E.FadeTo(0, speed);
            await SE.FadeTo(0, speed);
            await S.FadeTo(0, speed);
            await SW.FadeTo(0, speed);
            await W.FadeTo(0, speed);
            await NW.FadeTo(0, speed);
        }

        private async Task ShowButtons()
        {
            var speed = 25U;
            await N.FadeTo(1, speed);
            await NE.FadeTo(1, speed);
            await E.FadeTo(1, speed);
            await SE.FadeTo(1, speed);
            await S.FadeTo(1, speed);
            await SW.FadeTo(1, speed);
            await W.FadeTo(1, speed);
            await NW.FadeTo(1, speed);
        }
    }
}

3.- En nuestro archivo  MainPage.Xaml agregamos el siguiente codigo, el cual hara la instancia a nuestro ContentView Creado.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Menu_Flotante"
             x:Class="Menu_Flotante.MainPage">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition></RowDefinition>
      <RowDefinition Height="40"></RowDefinition>
    </Grid.RowDefinitions>
    <local:FilterMenu x:Name="Menu" HorizontalOptions="Center" VerticalOptions="Center" ></local:FilterMenu>
    <Label x:Name="Notifier" Grid.Row="1" HorizontalTextAlignment="Center"></Label>
  </Grid>
</ContentPage>
using System.Threading.Tasks;
using Xamarin.Forms;

namespace Menu_Flotante
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            Menu.ItemTapped += async (sender, e) =>
            {
                var evnt = (SelectedItemChangedEventArgs)e;
                Notifier.Text = (string)evnt.SelectedItem;
                await Task.Delay(2000);
                Notifier.Text = "";

            };
        }
    }
}

4.- también dejare el contenido del archivo App.xaml y App.xaml.cs para que puedan tener todas las fuentes de este ejemplo.

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Menu_Flotante.App">
  <Application.Resources> 
  </Application.Resources>
</Application>
using Xamarin.Forms;

namespace Menu_Flotante
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();

            MainPage = new Menu_Flotante.MainPage();
        }

        protected override void OnStart()
        {
            // Handle when your app starts
        }

        protected override void OnSleep()
        {
            // Handle when your app sleeps
        }

        protected override void OnResume()
        {
            // Handle when your app resumes
        }
    }
}

5.- Buenos amigos esto sería todo lo que les puedo ofrecer, espero este Menú Flotante en Xamarin Forms les sea muy útil y no olviden compartir de esa forma me estarían agradeciendo :D, pronto subiré la creación de un Checkbox Personalizado en Xamarin Forms.

Nota: si tienen alguna inquietud o quisieran que haga un post sobre algun tema de su interés, solo comenten para poder organizarme y realizar un ejemplo para ustedes mis lectores :D, un fuerte abrazo y sigamos aprendiendo sobre Xamarin Forms, y no se olviden dar like a mi FanPage para asi tener novedades sobre Xamarin Forms y otros lenguajes de programación nos vemos :D.

Sé el primero en comentar

Dejar una contestacion

Tu dirección de correo electrónico no será publicada.


*