Debugando pela rede WiFi

Tudo bem pessoal?

Bom, me deparei recentemente com um problema onde eu não tinha disponível a porta micro-usb do meu device disponível para download.

Um amigo me disse que era possível fazer o deploy e debuggar pela rede (Vlw Jefferson!)  Bom, é isto que vou mostrar hoje.

Primeiramente seu pc e o seu device devem estar na mesma rede.

Conecte seu device ao pc atráves do cabo usb e via adb shell execute os comandos abaixo:

  1. adb tcpip 555 
  2. Para localizar o ip execute adb shell netcfg ou adb shell ifconfig
  3. Execute adb connect <DEVICE_IP>:5555
  4. Desconecte o cabo usb e veja o resultado:

    Capturar

Para retornar a executar via cabo usb execute:

adb -s <DEVICE_IP_ADDRESS>:5555 usb

Fácil não?

 

Conhecendo o Shimmer

A algum tempo ja tinha notado este efeito Shimmer no aplicativo do facebook mas não tinha tempo para implementar em algo.
Graças a NAXAM, este efeito pode ser usado em aplicativo desenvolvidos com Xamarin.
O uso é bem simples. Vou apenas apresentar um teste e depois irei mostrar os demais efeitos desta biblioteca.
Primeiramente devemos baixar pelo Nuget o biblioteca Naxam.Shimmer.Droid.
Vamos criar nosso layout assim. Note que colocamos nosso conteudo dentro da tag com.facebook.shimmer.ShimmerFrameLayout
<com.facebook.shimmer.ShimmerFrameLayout
      android:id="@+id/shimmer"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      shimmer:duration="1000">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

      <RelativeLayout
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:id="@+id/relativeLayout">

        <ImageView
            android:background="#c2c2c2"
            android:layout_width="90dp"
            android:layout_height="70dp"
            android:id="@+id/imageView" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_marginStart="9dp"
            android:layout_toEndOf="@+id/imageView"
            android:background="#c2c2c2"
            android:id="@+id/textView" />

        <TextView
            android:id="@+id/textView22"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignStart="@+id/textView"
            android:layout_below="@+id/textView"
            android:layout_marginTop="5dp"
            android:background="#c2c2c2" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignStart="@+id/textView22"
            android:layout_below="@+id/textView22"
            android:layout_marginTop="5dp"
            android:background="#c2c2c2"
            android:id="@+id/textView4" />

      </RelativeLayout>

      <TextView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentStart="true"
          android:layout_below="@+id/textView3"
          android:layout_marginTop="5dp"
          android:background="#c2c2c2" />

      <TextView
          android:id="@+id/textView2"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentStart="true"
          android:layout_marginTop="5dp"
          android:layout_below="@+id/textView4"
          android:background="#c2c2c2" />

      <TextView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentStart="true"
          android:layout_below="@+id/textView2"
          android:layout_marginTop="5dp"
          android:background="#c2c2c2"
          android:id="@+id/textView3" />
    </LinearLayout>
  </com.facebook.shimmer.ShimmerFrameLayout>

 

Agora basta iniciar a animação:
      mShimmer.StartShimmerAnimation();
O resultado:
unnamed
Bem legal, não acha?

Detectando face com Mobile Vision / Face detection Android Mobile Vision

Olá, hoje vou mostrar para vocês como detectar face em imagens através do Mobile Vision.

Mobile Vision é um framework do Android que possui recursos incríveis para detectar faces em fotos e vídeos, além disto você pode trabalhar com reconhecimento de textos e QRcodes.

A ideia hoje é trabalhar com detecção de face em fotos, em breve irei mostrar como fazer durante a captura de fotos.

O Android Mobile Vision possui estes recursos principais.

  • Face detection: detecção de rosto é o conceito de localização de rostos em fotos ou vídeos automaticamente.
  • Face tracking: Detecção de Rosto em Vídeos, por exemplo, para rastrear um rosto de uma pessoa em quadros de vídeo consecutivos.
  • Landmark: é um ponto de interesse dentro de um rosto. por exemplo. olho, base do nariz.

Vamos começar.

Como vamos identificar faces em fotos devemos primeiramente carregar a foto e transforma-la em um objeto Bitmap. Nossa imagem esta localizada na pasta Asset do nosso projeto.

 mFaceOverlay = (FaceOverlay)FindViewById(Resource.Id.view_facedetector);

            var stream = Assets.Open("japan.jpg");

            Bitmap bitmap = BitmapFactory.DecodeStream(stream);<span data-mce-type="bookmark" style="display: inline-block; width: 0px; overflow: hidden; line-height: 0;" class="mce_SELRES_start"></span>

 

Agora vamos configurar os parâmetros do FaceDetector. Utilizei o modo de detecção rápido e detecção de todas as landmarks.

 FaceDetector detector = new FaceDetector.Builder(this)
                    .SetLandmarkType(LandmarkDetectionType.All)
                    .SetMode(FaceDetectionMode.Fast)
                    .Build();

 

Vamos criar nossa classe que ira receber o bitmap e desenhar o retângulo sobre cada rosto detectado.

public class FaceOverlay : View
    {
        private Bitmap mBitmap;
        private SparseArray mFaces;

        public FaceOverlay(Context context, IAttributeSet attr) : base(context, attr)
        {

        }
        public void SetData(Bitmap bitmap, SparseArray faces)
        {
            mBitmap = bitmap;
            mFaces = faces;
            Invalidate();
        }

        protected override void OnDraw(Canvas canvas)
        {
            base.OnDraw(canvas);

            if (mBitmap != null && mFaces != null)
            {
                double deviceScale = DrawBitmapToDeviceSize(canvas);
                DrawFaceDetectionBox(canvas, deviceScale);
            }
        }

        private double DrawBitmapToDeviceSize(Canvas canvas)
        {
            double viewWidth = canvas.Width;
            double viewHeight = canvas.Height;
            double imageWidth = mBitmap.Width;
            double imageHeight = mBitmap.Height;
            double scale = Math.Min(viewWidth / imageWidth, viewHeight / imageHeight);

            Rect bitmapBounds = new Rect(0, 0, (int)(imageWidth * scale), (int)(imageHeight * scale));
            canvas.DrawBitmap(mBitmap, null, bitmapBounds, null);
            return scale;
        }

        private void DrawFaceDetectionBox(Canvas canvas, double deviceScale)
        {
            Paint paint = new Paint();
            paint.Color = Color.Yellow;
            paint.SetStyle(Paint.Style.Stroke);
            paint.StrokeWidth = 3;

            for (int i = 0; i < mFaces.Size(); ++i)
            {
                Face face = (Face)mFaces.ValueAt(i);
                float x1 = (float)(face.Position.X * deviceScale);
                float y1 = (float)(face.Position.Y * deviceScale);
                float x2 = (float)(x1 + face.Width * deviceScale);
                float y2 = (float)(y1 + face.Height * deviceScale);

                canvas.DrawRect(x1, y1, x2, y2,
                        paint);
            }
        }

    }

 

Na nossa view precisamos inserir o controle FaceOverlay que irá receber nosso bitmap e as marcações de face.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" >
  <FaceVision.Control.FaceOverlay android:id="@+id/view_facedetector" android:layout_width="match_parent" android:layout_height="match_parent" />
</LinearLayout>

Nota: Na primeira vez que rodar o GMS irá baixar uma biblioteca nativa para o dispositivo para fazer a detecção de rosto. Normalmente, isso é feito pelo instalador antes que o aplicativo seja executado pela primeira vez. Mas se esse download ainda não foi concluído, o método “detectar” acima não detectará nenhum rosto.

O resultado será este:

1221.png

Lendo código QRCode com a lib ZXing.Net

Hoje vamos aprender como ler um código de barra, neste exemplo um código QRCode, com a lib ZXing.Net.

Após criar o projeto precisamos baixar a lib. No NuGet procure por ZXing.Net.Mobile.

Link: https://components.xamarin.com/view/zxing.net.mobile

Instale no projeto PCL / Android /iOS.

Como sempre, precisamos inicializar o serviço em cada plataforma.

No Android: MobileBarcodeScanner.Initialize (Application);

Agora criamos nossa View:

 <StackLayout Spacing="20" HorizontalOptions="CenterAndExpand" Padding="10, 50, 20, 10">
            <Label x:Name="lblScan" Text="" TextColor="Black" FontAttributes="Bold" HorizontalTextAlignment="Center" />
            <Label Text="Clique no ícone para ler o QRCode"  TextColor="Black"/>
            <Button x:Name="btnReadQrcode" BackgroundColor="Transparent" Image="qrcode.png" />
        </StackLayout>

 

Criamos um evento no botão para chamar o Scanner:

        public QrCodePage()
        {
            InitializeComponent();

            btnReadQrcode.Clicked += async (sender, e) => {

                var objScanner = new ZXing.Mobile.MobileBarcodeScanner();

                var objResult = await objScanner.Scan();

                if (objResult != null)
                {
                    lblScan.Text = "Código lido: " + objResult.Text;
                }
            };
        }

 

Se não ocorrer nenhum problema o resultado será este:

 

Espero que tenho gostado!

 

Extensões de marcação – XAML Markup Extensions

Hoje vamos utilizar as extensões de marcação.

Bom, hoje vou dar um exemplo bem simples de como utiliza extensões compartilhadas e ao poucos vou adicionando outros exemplos para vocês.

O que são os XAML Markup Extensions?

As extensões de marcação XAML constituem uma característica importante no XAML que permite que as propriedades sejam definidas para objetos ou valores que são referenciados indiretamente de outras fontes. As extensões de marcação XAML são particularmente importantes para o compartilhamento de objetos e as constantes de referência usadas em todo o aplicativo, mas encontram sua maior utilidade em ligações de dados.

Imagine que você tenha diversas propriedades definidas com os mesmos valores e vários elementos, não seria bom criar um único recurso que altere o valor delas em todos os locais?

Eu acho que sim, então utilizar vamos aprender como.

Primeiro criamos um dicionário de recursos. e adicionamos os atributos que pretendemos compartilhar. Criei um recurso para setar a cor de fundo dos stacklayouts.

   <ContentPage.Resources>
    <ResourceDictionary x:Name="AppDictionary">
      <Color x:Key="BackgroundColorRed">#FF0000</Color>
      <Color x:Key="BackgroundColorWhite">#FFFFFF</Color>
    </ResourceDictionary>

Agora para chamar basta utilizar o StaticResource passando o nome da sua propriedade.

 <StackLayout BackgroundColor="{StaticResource BackgroundColorRed}"                Grid.Row="0">
      </StackLayout>
      <StackLayout BackgroundColor="{StaticResource BackgroundColorWhite}"                Grid.Row="1">
      </StackLayout>

Olha o código final:


  <ContentPage.Resources>
    <ResourceDictionary x:Name="AppDictionary">
      <Color x:Key="BackgroundColorRed">#FF0000</Color>
      <Color x:Key="BackgroundColorWhite">#FFFFFF</Color>
    </ResourceDictionary>

  </ContentPage.Resources>
  <ContentPage.Content>
    <Grid RowSpacing="0" ColumnSpacing="2" BackgroundColor="#F9F9F9">
      <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
      </Grid.ColumnDefinitions>
      <StackLayout BackgroundColor="{StaticResource BackgroundColorRed}" Grid.Row="0">
      </StackLayout>
      <StackLayout BackgroundColor="{StaticResource BackgroundColorWhite}" Grid.Row="1">
      </StackLayout>
    </Grid >
  </ContentPage.Content>

 

Resultado:

tela colors

 

Simples não achou? Espero que tenha gostado.

Criando menu “sanduíche” (MasterDetail Page) com Xamarin.Forms

Tudo bem pessoal!

O post de hoje é sobre o menu sanduíche ou o Master-Detail Page.

Muita gente utiliza este recurso em suas aplicações e realmente fica bem bacana. Vou mostrar como utiliza-lo em sua aplicação com alguma modificações, ou seja, você pode customizá-lo, colocando imagens por exemplo.

O resultado final será:

tela7

Menu

O fonte de criação do menu já foi feito pela equipe do Xamarin  logo ficaremos apenas com a parte de customizá-lo.

A primeira coisa a ser feita é criar o projeto, acredito que você já saiba. Escolhi o projeto Cross-Plataform ->XamarinForms Portable.

Agora vamos criar três pastas para estruturar melhor nosso projeto. As pasta são :

  • Menu : Implementação relacionada ao menu;
  • Views: Todas as telas do aplicativo;
  • Model: Modelo de domínio de uma aplicação.
tela1

Estrutura de pastas da solução

Como já foi dito, a implementação do menu já esta pronta e o que vamos fazer e customizar de acordo com a nossa necessidade. Vamos criar as classes MenuListView, MenuPage e MenuCell.

A classe MenuListView é responsável por retornar a lista de opções do menu, na nossa aplicação criei as opções “Editar” e “Configurações”. Em cada item desta lista podemos definir o título, a cor do texto, estilo, ícone e qual página ele irá abrir.

private List < ItemMenu > GetMenuItemList() {
    List < ItemMenu > lstItemMenu = new List < ItemMenu > ();

    lstItemMenu.Add(new ItemMenu() {
        Title = "Editar",
            TitleColor = Color.FromHex("454545"),
            TitleWeight = FontAttributes.Bold,
            IconSource = "ic_edit.png",
            TargetType = typeof(FirstPage)
    });
    return lstItemMenu;
}

A classe MenuPage é o nosso menu, nele é criar toda a organização dos controles (Labels, StackLayout, botões, Listview). O nosso menu terá um stacklayout que possui dentro dele dois label de identificação e o controle Image. Utilizei o plugin Image Circle Control para dar o contorno redondo na imagem. Ficou bem bacana o resultado final.

tela4

Parte superior do menu.

Note que em cada opção do menu existe um ícone e um texto ao lado, esta implementação esta na classe MenuCell. Vou explicar melhor. Como eu disse, o nosso menu tem um Stacklayout e um Listview. Dentro do Listview se encontra as opções, estas opções são as cells do Listview e podemos customizá-las. Para customizar a cell do Listview foi criado um Stacklayout com Image e um Label dentro dele.

tela3

Cell customizada com ícone e texto

Agora vamos falar das nossas Views, criaremos duas para realizar as trocas de telas. As telas são a FirstPage e SecondPage.

A classe MastePage herda da MasterDetailPage, dentro do seu construtor instanciamos a MenuPage e definimos as propriedades Master e Detail.

public class MasterPage: MasterDetailPage {

    MenuPage objMenuPage;

    public MasterPage() {
        objMenuPage = new MenuPage();

        objMenuPage.lstMenuItem.ItemSelected += (object sender, SelectedItemChangedEventArgs e) => {
            NavigateTo(e.SelectedItem as ItemMenu);
        };

        Master = objMenuPage;
        Detail = new NavigationPage(new FirstPage()) {};
    }

    private void NavigateTo(ItemMenu objItemMenu) {

        Page objPageDisplay;

        if (objItemMenu == null) {
            return;
        }

        objPageDisplay = (Page) Activator.CreateInstance(objItemMenu.TargetType);

        Detail = new NavigationPage(objPageDisplay);

        objMenuPage.lstMenuItem.SelectedItem = null;

        IsPresented = false;
    }
}

Agora é chamar o MenuPage na Class App e rodar.

 public class App: Application {
     public App() {
         MainPage = new MasterPage();
     }
 }

 

 

O projeto esta disponível aqui.

Referências

https://developer.xamarin.com/guides/xamarin-forms/user-interface/navigation/master-detail-page/

Utilizando um serviço com Xamarin.Forms

Boa noite.

Hoje vou mostrar como chamar um serviço através de um aplicativo feito com o Forms.

Já podemos imaginar que iremos utilizar um DependencyService para chamar o serviço e se existir alguma dúvida sobre como criar o DependencyService clique neste link.

Bom, o que é um serviço?

O Google Developer Android diz:

A Serviceé um componente de aplicativo que pode executar operações de longa execução em segundo plano e não fornece uma interface de usuário. Outro componente do aplicativo pode iniciar um serviço e ele continua a ser executado em segundo plano mesmo se o usuário alternar para outro aplicativo.

Podemos perceber que se pretendermos fazer alguma tarefa como baixar uma imagem, fazer upload, recuperar posição pelo gps ou outra tarefa de sincronização utilizar um serviço é uma boa ideia.

Vamos lá.

Primeiramente, criaremos nossa interface com os métodos StartService e StopService.

 public interface IServices
    {
        void StartService();
        void StopService();
    }

No projeto Android, vamos criar a classe que irá gerenciar o serviço.

[Service]
    public class ManagerService : Service
    {
        private string TAG = "ManagerService";

        public override void OnCreate()
        {
            base.OnCreate();
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            if (!IsRunningService())
            {
                Log.Debug(TAG, "Serviço iniciado");
            }
            else
            {
                Log.Debug(TAG, "Serviço já está iniciado");
            }

            return StartCommandResult.NotSticky;
        }

        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public override void OnDestroy()
        {
            Log.Debug(TAG, "Serviço encerrado");

            base.OnDestroy();
        }

        private bool IsRunningService()
        {
            var objManager = (ActivityManager)GetSystemService(ActivityService);
            var lstServices = objManager.GetRunningServices(int.MaxValue).Select(
                service => service.Service.ClassName).ToList();

            return lstServices.Exists(e => e.Contains(typeof(ManagerService).Name));
        }
    }

Agora devemos criar a classe que será chamada pelo PCL e assim iniciar/parar o serviço

    public class DroidService : TutorialService.Interface.IServices
    {
        public void StartService()
        {
            Xamarin.Forms.Forms.Context.StartService(new Intent(Xamarin.Forms.Forms.Context, typeof(ManagerService)));
        }

        public void StopService()
        {
            Xamarin.Forms.Forms.Context.StopService(new Intent(Xamarin.Forms.Forms.Context, typeof(ManagerService)));
        }
    }

Na minha tela inicial criei dois botões, btnStartService e btnStopService. O nome já deixa claro, um irá iniciar e outro parar o serviço.

            btnStartService = new Button
            {
                Text = "Iniciar serviço"
            };
            btnStartService.Clicked += StarService_Command;

            btnStopService = new Button
            {
                Text = "Parar serviço"
            };
            btnStopService.Clicked += StopService_Command;
            // The root page of your application
            var content = new ContentPage
            {
                Title = "TutorialService",
                Content = new StackLayout
                {
                    VerticalOptions = LayoutOptions.Center,
                    Padding = new Thickness(20, 50, 20, 20),
                    Children = { btnStartService, btnStopService }
                }
            };

            MainPage = new NavigationPage(content);

Agora chamamos via o DependencyService o serviço

        private void StopService_Command(object sender, EventArgs e)
        {
            DependencyService.Get<Interface.IServices>().StopService();
        }

        private void StarService_Command(object sender, EventArgs e)
        {
            DependencyService.Get<Interface.IServices>().StartService();
        }

 

Resultado:

1232.png

O código está aqui.

Referências

https://developer.android.com/guide/components/services.html

Atualizando o ListView com Pull To Refresh – Xamarin Forms

Olá.

Vamos falar sobre o Pull To Refresh. Ele é uma das maneiras para atualizar a lista de elementos dentro do ListView.

Para habilitá-lo você deve setar como true a propriedade IsPullToRefreshEnabled.

O resultado em cada plataforma fica assim:

iOS/Android/Wp

Vamos para nosso exemplo. Primeiro setamos o IsPullToRefreshEnable no ListView.

<ListView x:Name="lstViewAnimal" RowHeight="90" IsPullToRefreshEnabled="True" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.ContextActions>
<MenuItem Clicked="OnInfo" CommandParameter="{Binding .}" Text="Info" />
<MenuItem Clicked="OnDelete" CommandParameter="{Binding .}" Text="Deletar" IsDestructive="True" />
</ViewCell.ContextActions>
<StackLayout Orientation="Horizontal" HorizontalOptions="Fill" Padding="10">
<Image Source="{Binding Image}" HorizontalOptions="Start" />
<StackLayout Orientation="Vertical" Padding="10,5,5,10">
<Label Text = "{Binding Name}" FontSize="15" FontAttributes="Bold" />
<Label Text = "{Binding Family}" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Agora vamos implementar o evento que atualiza a lista. Vamos adicionar mais um item toda fez que solicitarmos o Refresh.

lstViewAnimal.Refreshing += LstViewAnimal_Refreshing;

private async void LstViewAnimal_Refreshing(object sender, EventArgs e)
{
await Task.Delay(2000);

lstAnimal.Insert(0, new Animal { Name = "Random " + new Random().Next(0,50).ToString(), Family = "Família: " + new Random().Next(0, 50).ToString(), Image = "icon.png" });

lstViewAnimal.IsRefreshing = false;
}

Agora deslize o dedo de cima para baixo no ListView e aguarde a atualização.

ezgif-com-crop-1

PullToRefresh no ListView

O código está aqui.

Até a próxima.

Referência

https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/interactivity/#Pull_to_Refresh

Utilizando Context Actions no ListView – Xamarin Forms

Olá!

Vamos imaginar que você quer realizar alguma ação sobre um item do ListView, por exemplo, deletá-lo. Bom, um recurso bem interessante que podemos utilizar para isto é o Context Actions.

Está curioso para saber como fica a aparência? Da uma olhada.

1.png

iOS/android/Wp

Bacana não? A implementação é bem simples, pode ser feito no Xaml ou em código. O meu exemplo foi feito no Xaml mas caso queira em código na documentação tem um exemplo.

Lembra do ultimo projeto que customizamos um ViewCell? Vamos utilizá-lo para implementar nosso Context Action.

Vamos adicionar este código no DataTemplate do ListView da nossa page.

<ViewCell>
            <ViewCell.ContextActions>
              <MenuItem Clicked="OnInfo" CommandParameter="{Binding .}"                  Text="Info" />
              <MenuItem Clicked="OnDelete" CommandParameter="{Binding .}"                  Text="Deletar" IsDestructive="True" />
            </ViewCell.ContextActions>
</ViewCell>

Agora implementamos os eventos, “Clicked”, no codebehind.

        public void OnInfo(object sender, EventArgs e)
        {
            var objMenu= ((MenuItem)sender);
            var objAnimal = (Animal)objMenu.CommandParameter;
            DisplayAlert("Context Action", objAnimal.Name + " selecionado.", "OK");
        }

        public void OnDelete(object sender, EventArgs e)
        {
            var objMenu = ((MenuItem)sender);
            var objAnimal = (Animal)objMenu.CommandParameter;
            lstAnimal.Remove(objAnimal);
            DisplayAlert("Context Action", objAnimal.Name + " deletado.", "OK");
        }

 

Selecione um item e mantenha ele pressionado, as opções Info e Deletar irão aparecer na actionbar (android).

 

É isto, o código esta aqui.

Até a próxima.

Referências

https://developer.xamarin.com/guides/xamarin-forms/user-interface/listview/interactivity/#Context_Actions

Plugin para Dialogs – Xamarin Forms

Olá pessoal.

Já apresentei para vocês o DisplayAlert do XamarinForms, mas já vi muita gente perguntando como se implementa um Toast, efeito de Loading e outros dialogs.

Bom existe um plugin que pode ajudar muita gente que procura a implementação pronta. O plugin é o ACR User Dialogs, do aritchie.

Atualmente ele tem os seguintes recursos:

  • Action Sheet
  • Alert
  • Confirm
  • Date
  • Loading/Progress
  • Login
  • Prompt
  • Toasts
  • Time

Bem simples de usar, basta você baixá-lo para cada plataforma e não se esqueçer de iniciar o UserDialogs na Activity para Android. No iOS é opcional.

Meu exemplo possui apenas alguns recursos, não fiz todos. Criei o Toast, Loading, Loading com barra de progresso e o ActionSheet. Lembrando que os teste foram feitos para o Android, é claro que o comportamento de cada recurso é diferente para cada plataforma.

Vamos lá. Após baixar o plugin, inicialize o serviço, UserDialogs.Init(), na Activity.

     global::Xamarin.Forms.Forms.Init(this, bundle);
     UserDialogs.Init(this);
     LoadApplication(new App());

A view ficou assim:

<?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="TutorialDialogs.Views.MainPage" Title="Dialogs">
  <ContentPage.Content>
    <StackLayout Spacing="10">
      <Button x:Name="btnToast" Text="TOAST" VerticalOptions="Center" HorizontalOptions="Center" WidthRequest="150" />
      <Button x:Name="btnLoading" Text="LOADING" VerticalOptions="Center" HorizontalOptions="Center" WidthRequest="150"/>
      <Button x:Name="btnLoadingProgress" Text="LOADING PROGRESS" VerticalOptions="Center" HorizontalOptions="Center" WidthRequest="150" />
      <Button x:Name="btnActionSheet" Text="ACTION SHEET" VerticalOptions="Center" HorizontalOptions="Center" WidthRequest="150" />
    </StackLayout>
  </ContentPage.Content>
</ContentPage>
1

View

Como fica o Toast:

 private void ButtonToast_Clicked(object sender, EventArgs e)
 {
       UserDialogs.Instance.Toast("Olá sou o Toast!!", TimeSpan.FromSeconds(5));
 }
2

Toast

Como fica o Loading:

 private async void ButtonLoading_Clicked(object sender, EventArgs e)
 {
      using (var objDialog = UserDialogs.Instance.Loading("Carregando..", null, null, true, MaskType.Black))
      {
           await Task.Delay(5000);
      }
 }
3

Loading

Como fica o Loading Progress:

private async void ButtonProgress_Clicked(object sender, EventArgs e)
 {
     using (var objDialog = UserDialogs.Instance.Progress("Loading Progress"))
     {
        while(objDialog.PercentComplete < 100)
        {
           await Task.Delay(TimeSpan.FromMilliseconds(100));
           objDialog.PercentComplete += 2;
        }
     }
 }
4

Loading com progresso

Como fica o ActionSheet:

private void ButtonActionSheet_Clicked(object sender, EventArgs e)
 {
       var objActionSheetConfig = new ActionSheetConfig()
            .SetTitle("Compartilhar")
            .SetUseBottomSheet(true);

    for (var i = 0; i < lstImage.Count; i++)     {         var strOption = lstImage[i - 1].Replace(".png", "");         var objBitmapLoader = BitmapLoader.Current.LoadFromResource(lstImage[i], null, null).Result;         objActionSheetConfig.Add(              lstImage[i].Replace(".png", ""),              () => Result("Você selecionou a opção: " + strOption),
             objBitmapLoader
        );
     }

        UserDialogs.Instance.ActionSheet(objActionSheetConfig);
 }
5.png

ActionSheet

O código está aqui.

Referências

https://github.com/aritchie/userdialogs#ios-and-windows