Tag Archives: Transparency ContentPage

Build yo own awesome Activity/Loading Indicator Page for Xamarin Forms…

Have you ever wanted to have an Activity or Loading indicator dialog screen overlay, that is transparent, and fully customized by you? in your Xamarin.Forms project?

Then you stopped at the right place.

Today I’m gonna share how to build a fully customizable Activity Indicator /Loading Screen from Xamarin.Forms with a bit of native magic. To be honest, more of a continuation of my previous blog post! 😉 lol

Perks:

  • Fully customizable View on the go from Xamarin.Forms
  • Overlays on top of your ContentPage / Navigation Stack
  • Service based, full MVVM & testing friendly
  • Fully transparent and controllable dimmer
  • Cancellation & back button disabled

Here’s a sneak peek…

  

TADAAA! That’s what yol gonna build! 😀

The Concept…

So basically if you think about it, when you want to display an Loading/Activity indicator overlay screen, it is something that would indicate,

“Oh there’s some important processing going on that Page and we need you to wait until it finishes…” 😛

“In the meantime we’re going to block the interactivity of that Page with this overlay, but you can still see the progress of it with the transparency…”

So in the language of Xamarin.Forms, on top of your ContentPage, we need something that would block the interactivity of background content but allows us to see what’s going in the background, in other words, it should be a transparent or dimmed View. 😀

A ghost from the past…

So I’m going to revert your attention to the previous blog post I wrote, Build your own Transparent Page from scratch for Xamarin.Forms, which was all about creating a Transparent page for Xamarin.Forms using a bit of native code. And I’ll be using the same concept and the code here as well, but I’m not going to drill down to the technical details of that specific implementation here, so if you’re looking for it, go ahead and give it a read first and come back.

The Recipe time…

So if you’re coming back  from my previous blog post you could probably consider this post as a continuation of it. Today we’re going to create a Transparent Page in Xamarin.Forms using a bit of native magic, that will overlay on top of any Xamarin.Forms ContentPage or the Navigation Stack, and has the capability to customize the Transparent content view on demand. 😀

So to do this, we’re going to implement a native Transparent page in our Platform projects (iOS and Android), then we’re going to create a Service implementation that can display and dismiss our Transparent pages on demand while being able to pass in the desired Content View as we wish to display as parameters. The actual concrete implementation of that service will bed laid down in platform specific projects, along side the native Transparent page rendering implementation. So that we can do the rendering or displaying or dismissing our Loading/Activity indicator overlay on demand as we wish.

So to map the Service interface and its concrete implementations we are going to use Xamarin.Forms Dependency service, but then if you have your own IoC container you could use it as well. 😉

Sounds pretty straight forward eh! 😀 time for coding! 😉

Xamarin.Forms bits…

Alright then let’s hit it with the Service interface implementation. Let’s call it ILodingPageService.

public interface ILodingPageService
{
	void InitLoadingPage
                  (ContentPage loadingIndicatorPage = null);

	void ShowLoadingPage();

	void HideLoadingPage();
}

 

So we will have three interface methods, one to initiate and prepare the Transparent page we’re going to display as our Loading/Activity indicator overlay. Then two more to Show it or Hide it on the app.

Speaking of InitLoadingPage() method, the reason we need is to facilitate the feature of displaying different Loading pages or designs on demand at the run time. So let’s say in Page 1 we want to display one Loading page, then in Page 2 we want to display a different kind of Loading Page, that right there is possible here with this method. You just pass in whatever the Loading Page design you want to show, and you’re done! 😉 How cool is that!

Since this a Xamarin.Forms Transparent Page, let’s first create our usual ContentPage, with usual stuff. Let’s call it the LoadingIndicatorPage1

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="XFLoadingPageService.LoadingIndicatorPage1"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    BackgroundColor="#80000000">
    <ContentPage.Content>
        <StackLayout
            Padding="30"
            BackgroundColor="Black"
            HorizontalOptions="Center"
            VerticalOptions="Center">
            <ActivityIndicator IsRunning="True" Color="White" />
            <Label
                FontAttributes="Bold"
                Text="Loading..."
                TextColor="White" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

 

So you can see we have a very simple ContentPage design, with an ActivityIndicator and a Label to show that, “Oh look it’s a loading screen… boo!” lol 😀

Android bits….

Here come the actual magic, let me begin with Android! So let’s start off with our ILoadingPageService’s concrete implementation for Android and register it with the Xamarin Dependency Service.

[assembly: Xamarin.Forms.Dependency(typeof(LodingPageServiceDroid))]
namespace XFLoadingPageService.Droid
{
    public class LodingPageServiceDroid : ILodingPageService
    {
        private Android.Views.View _nativeView;

        private Dialog _dialog;

        private bool _isInitialized;

        public void InitLoadingPage(ContentPage loadingIndicatorPage)
        {
            // check if the page parameter is available
            if (loadingIndicatorPage != null)
            {
                // build the loading page with native base
                loadingIndicatorPage.Parent = Xamarin.Forms.Application.Current.MainPage;

                loadingIndicatorPage.Layout(new Rectangle(0, 0,
                    Xamarin.Forms.Application.Current.MainPage.Width,
                    Xamarin.Forms.Application.Current.MainPage.Height));

                var renderer = loadingIndicatorPage.GetOrCreateRenderer();

                _nativeView = renderer.View;

                _dialog = new Dialog(CrossCurrentActivity.Current.Activity);
                _dialog.RequestWindowFeature((int)WindowFeatures.NoTitle);
                _dialog.SetCancelable(false);
                _dialog.SetContentView(_nativeView);
                Window window = _dialog.Window;
                window.SetLayout(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
                window.ClearFlags(WindowManagerFlags.DimBehind);
                window.SetBackgroundDrawable(new ColorDrawable(Android.Graphics.Color.Transparent));

                _isInitialized = true;
            }
        }

        public void ShowLoadingPage()
        {
            // check if the user has set the page or not
            if (!_isInitialized)
                InitLoadingPage(new LoadingIndicatorPage1()); // set the default page

            // showing the native loading page
            _dialog.Show();
        }

        public void HideLoadingPage()
        {
            // Hide the page
            _dialog.Hide();
        }
    }
}

 

Most of the above Xamarin Android specific code is already explained in detailed line by line in my previous post. So in short, here we have the concrete implementation of our service for Android, inside the InitLoadingPage() we’re passing in the Xamarin.Forms Page which we want to render as a transparent page which will act as our Activity Indicator.  Then we’re rendering that page and embed into a Android Dialog view with a transparent background, and back button cancelled properties enabled. We’re keeping a reference of the _dialog instance so that we can show or hide the Page upon respective ShowLoadingPage() and HideLoadingPage() executions.

So every time a user wants to display a different Loading page, they will call the InitLoadingPage() which will build the new page instance and keep it in the service memory.

At the same time you may have seen inside ShowLoadingPage() if you haven’t instantiated the transparent page, then we’re using a default page, LoadingIndicatorPage1 as a template ad instantiating it on the go, just to avoid exceptions. This choice of default page is totally up to you.

Also don’t forget at the top of the namespace we’re registering this concrete implementation with Xamarin Dependency service. 😉

iOS bits….

Then let’s move on with our ILoadingPageService’s concrete implementation for iOS and register it with the Xamarin Dependency Service.

[assembly: Xamarin.Forms.Dependency(typeof(LodingPageServiceiOS))]
namespace XFLoadingPageService.iOS
{
    public class LodingPageServiceiOS : ILodingPageService
    {
        private UIView _nativeView;

        private bool _isInitialized;
        
        public void InitLoadingPage(ContentPage loadingIndicatorPage)
        {
            // check if the page parameter is available
            if (loadingIndicatorPage != null)
            {
                // build the loading page with native base
                loadingIndicatorPage.Parent = Xamarin.Forms.Application.Current.MainPage;

                loadingIndicatorPage.Layout(new Rectangle(0, 0,
                    Xamarin.Forms.Application.Current.MainPage.Width,
                    Xamarin.Forms.Application.Current.MainPage.Height));

                var renderer = loadingIndicatorPage.GetOrCreateRenderer();

                _nativeView = renderer.NativeView;

                _isInitialized = true;
            }
        }

        public void ShowLoadingPage()
        {
            // check if the user has set the page or not
            if (!_isInitialized)
                InitLoadingPage(new LoadingIndicatorPage1()); // set the default page

            // showing the native loading page
            UIApplication.SharedApplication.KeyWindow.AddSubview(_nativeView);
        }

        public void HideLoadingPage()
        {
            // Hide the page
            _nativeView.RemoveFromSuperview();
        }
    }
}

 

So the implementation here is also similar to Android code above, except for the native bit. So we’re instantiating the Xamarin.Forms Page instance inside, InitLoadingPage() method we’re initiating the transparent page instance and holding inside the service.

Then showing it or hiding it based on the ShowLoadingPage() or HideLoadingPage() calls.

Pretty straightforward eh! 😀

So what next…

Now one of the best features of this implementation is that your could use any number of Loading Indicator Pages as you wish with various kinds of designs. 😀 So just for the kicks of it here’s another page that we’ll use. let’s call it LoadingIndicatorPage2

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="XFLoadingPageService.LoadingIndicatorPage2"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    BackgroundColor="#80000000">
    <ContentPage.Content>
        <StackLayout
            Padding="30"
            BackgroundColor="#D93463"
            HorizontalOptions="Center"
            VerticalOptions="Center">
            <ActivityIndicator IsRunning="True" Color="White" />
            <Label
                FontAttributes="Bold"
                Text="Yo! Hold on..."
                TextColor="White" />
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

 

If that’s not enough you can add more and more as you go 😀 but just make sure to call the InitLoadingPage() method! 😉

Let’s fire it up…

So to fire this up we need to call this service from your Xamarin.Forms code using the DependencyService.

// show the loading page...
DependencyService.Get<ILodingPageService>()
                 .InitLoadingPage(new LoadingIndicatorPage1());
DependencyService.Get<ILodingPageService>().ShowLoadingPage();

 

There we’re first initiating our page and then show it on the app. Once you initiate the page you don’t have to call it ever again as you saw in the implementation, it is retained in the memory of the service.

// close the loading page...
DependencyService.Get<ILodingPageService>().HideLoadingPage();

 

Once you’re done, you can close our awesome Activity / Loading Indicator Page with the above code.

And here we go on iOS and Android in action…. 😀

That’s our first Loading screen in action…

And click on the second button, there’s our second Loading screen in action, on the go…

Look at that, even during navigation between pages our Loading page stays intact on top of the Xamarin.Forms Pages stack. 😉

The reason why it acts so independently is because we are directly accessing the native elements in the service implementation, therefore even during navigation of Xamarin.Forms Stack or whatever the UI activity our Loading page will not be affected, it will keep on, of its own.

How awesome is that eh! 😀

Github it if yo lazy!

So all of this is hosted on my git repo: https://github.com/XFLoadingPageService

Now your own imagination is the limit for what’s possible or not fellas!

That’s it for today.

Cheers! 😀

Build your own Transparent Page from scratch for Xamarin.Forms…

There was this one time I wanted to build my own Transparent Page in Xamarin Forms, from scratch, all by myself, due to my ego and to challenge myself.

Usually when it comes to Transparent page related situations I would always recommend the awesome Rg.Plugins.Popup  library, which I had praised one of my previous blog posts as well, So I created a Popup with Transparent background in Xamarin Forms… 😉

Backstory…

But for real there was one instance I couldn’t use any 3rd party library for the project and all the code bits should be from scratch. So I had no option but to resort myself to creating my own Transparent Page in that Xamarin.Forms project.

And I did…

Sneak Peak…

So this how it would look like.

And limit of the expansion is all up to your imagination and developer skills.

If not work on it! 😛

Recipe time!

So to create a transparent page in Xamarin.Forms out of the box is impossible, which I’m not going to explain in detail. Obviously in short, for reasons such as Xamarin.Forms abstracts the most common subset of properties of the native platforms, we don’t have much power of customization of the UI.

There is no way to use Xamarin.Forms ContentPage with transparency. (Yes I have tried!) So we need something beyond Xamarin.Forms stuff, Aha! Natively Rendered View, that could overlay on top of a give ContentPage.

But that doesn’t mean Xamarin.Forms would block you from implementing something platform specific, it only empowers you 😉

Also since we’re drilling down in the native levels, we have absolute control over Xamarin.Forms Pages, including the power to push any View on top of Xamarin.Forms ContentPage Navigation stack.

Recipe in-depth!

So to do this we need to have some Native platform level access, so if you’re using a Xamarin.Forms shared project, this should be pretty easy, but for PCL projects, you may have to create a dependency service implementation to invoke this implementation.

So in Android, we’re going to use Dialog View to implement the transparent Page and with the access of the Activity instance, we’ll push it to over any give ContentPage of Xamarin.Forms.

Then in iOS, we’ll be using UIApplication instance’s KeyWindow property to push the transparent Page over any given ContentPage of Xamarin.Forms.

Sounds pretty straight forward eh! 😀

Xamarin.Forms bits…

Alright since this a Xamarin.Forms Transparent Page, let’s first create our usual ContentPage, with usual stuff.

var xamFormsPage = new ContentPage() 
{
  BackgroundColor = new Color(0, 0, 0, 0.5),
  Content =
  new StackLayout() 
  {
    Padding = 30,
    Spacing = 20,
    WidthRequest = 250,
    BackgroundColor = Color.Black,
    Children = 
	{
	 new Xamarin.Forms.Label() {
	  Text =
	   "Welcome to my own Transparent Page!",
	   FontAttributes = FontAttributes.Bold,
	   TextColor = Color.White,
	   FontSize = 20,
	 },
	 new Xamarin.Forms.Label() {
	  Text =
	   "This is from Xamarin.Forms with a " +
	   "bit mix of simple native magic!",
	   TextColor = Color.White,
	   FontSize = 17,
	 },
	 new Xamarin.Forms.Button() {
	  Text = "Close me!",
	   BackgroundColor = Color.Gray,
	   TextColor = Color.White,
	 }
    },
    VerticalOptions = LayoutOptions.Center,
    HorizontalOptions = LayoutOptions.Center,
  }
};

 

So here we have an instance of a simple Xamarin.Forms.Content page, with a bunch of labels and a button. This is the page we’re going to render into a transparent page. 😉

Android Implementation…

So like we discussed before, on Android we’re going to make use of the Android Dialog View to populate our transparent page. In order to do this we need to get access to the current Activity of our Xamarin.Forms Android run time.

In order to do that we’re going to use CrossCurrentActivity plugin by James Montemagno. So before we begin, go ahead and add that plug in to your Xamarin.Forms solution using Nuget.

Now the basic idea here is all about actually rendering our Xamarin.Forms ContentPage instance, and converting it to a native Android View at run time. Then we take that native View instance and attach into a Android Dialog View, making it visible along with the transparent effect. Oh yes the CrossCurrentActivity plugin comes handy when we instantiate our Android Dialog View. 😉

// Assign the Parent hook for our page instance 
xamFormsPage.Parent = Xamarin.Forms.Application.Current.MainPage;

// Run the Layout Rendering Cycle for the page
xamFormsPage.Layout(new Rectangle(0, 0,
 Xamarin.Forms.Application.Current.MainPage.Width,
 Xamarin.Forms.Application.Current.MainPage.Height));

// Get the native renderered instance for our page
var nativePageRendererInstance = xamFormsPage.GetOrCreateRenderer();

// Get the native page for our page
Android.Views.View nativePageView = nativePageRendererInstance.View;

// Create the native transparent Dialog instance to embed our page
Dialog dialog = new Dialog(CrossCurrentActivity.Current.Activity);
dialog.RequestWindowFeature((int) WindowFeatures.NoTitle);
dialog.SetCancelable(false);
dialog.SetContentView(nativePageView);
Window window = dialog.Window;
window.SetLayout(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent);
window.ClearFlags(WindowManagerFlags.DimBehind);
window.SetBackgroundDrawable(new ColorDrawable(Android.Graphics.Color.Transparent));

// Show the page
dialog.Show();

 

There you have the magical code 😉 lol.

You can see how we’re setting the Parent hook to our Xamarin.Forms page instance, then running the Layout() rendering circle allowing the Views to be actually measured and rendered in the memory. Then we convert our Xamarin.Forms page instance into a native Android View using the GetOrCreateRenderer() extension method which I will describe next.

Then as I discussed before we’re attaching the native View into a Dialog View and setting it visible resulting in total awesome transparency of a page, along with the exact Xamarin.Forms content we wanted to display.

Oh before I forget here is the precious Xamarin.Forms.View -> Android.Views.View Converter extension implementation. Special thanks to rotorgames for the below magical code block. 😉

internal static class PlatformExtension
{
	public static IVisualElementRenderer GetOrCreateRenderer(this VisualElement bindable)
	{
		var renderer = XFPlatform.GetRenderer(bindable);
		if (renderer == null)
		{
			renderer = XFPlatform.CreateRendererWithContext(bindable, CrossCurrentActivity.Current.Activity);
			XFPlatform.SetRenderer(bindable, renderer);
		}
		return renderer;
	}
}

Source Credit: Rg.Plugins.Popup.Droid/PlatformExtension.cs

As you can see it’s a simple implementation that takes in the Xamarin.Forms View instance and retrieve the native renderer for that View.

Now when you need to hide the above Transparent page, you simply call Hide() on the Android Dialog instance.

// Hide the page
dialog.Hide();

 

Then we go to the iOS stuff..

iOS Implementation….

Here we’ve come to the iOS implementation, so just like we discussed in the beginning, we’re going to access the global UIApplication singleton to push our transparent page the application view through the KeyWindow property.

So in a nutshell iOS renders every native View with the transparency give the proper background spacing, so we don’t really have to worry about using any placeholder view. The idea here is to get our Xamarin.Forms Page instance, run its Layout rendering cycle, convert that instance to an iOS native View. Then finally push it to the KeyWindow property by adding as a SubView.

Pretty straightforward, almost similar as to what we did in Android but simpler! 😉

// Assign the Parent hook for our page instance 
xamFormsPage.Parent = Xamarin.Forms.Application.Current.MainPage;

// Run the Layout Rendering Cycle for the page
xamFormsPage.Layout(new Rectangle(0, 0,
 Xamarin.Forms.Application.Current.MainPage.Width,
 Xamarin.Forms.Application.Current.MainPage.Height));

// Get the native renderered instance for our page
var nativePageRendererInstance = xamFormsPage.GetOrCreateRenderer();

// Get the native page for our page
UIView nativePageView = nativePageRendererInstance.NativeView;

// Show the page by pushing to the stack
UIApplication.SharedApplication.KeyWindow.AddSubview(nativePageView);

 

I’m not going repeat myself here because I’m too lazy and the explanation is almost same as I did in Android implementation. 😀

But in the context of iOS, you can see we’re getting the iOS native UIView of our Xamarin.Forms ContentPage instance and pushing it directly to the Application UI, by calling AddSubView() on KeyWindow property.

Oh before I forget here is the precious Xamarin.Forms.View -> UIKit.UIView Converter extension implementation. Special thanks to rotorgames for the below magical code block. 😉

internal static class PlatformExtension
{
	public static IVisualElementRenderer GetOrCreateRenderer(this VisualElement bindable)
	{
		var renderer = XFPlatform.GetRenderer(bindable);
		if (renderer == null)
		{
			renderer = XFPlatform.CreateRenderer(bindable);
			XFPlatform.SetRenderer(bindable, renderer);
		}
		return renderer;
	}
}

Source Credit: Rg.Plugins.Popup.IOS/PlatformExtension.cs

Now when you want to hide the above created Transparent Page, then you simple call the RemoveFromSuperview() on our iOS UIView instance, which will result in it removing itself from UIWindow.

// Hide the page
nativePageView.RemoveFromSuperview();

 

bloopity blah! 😀

Alright, so let me address something you might be wondering…

How about Xamarin.Forms to Xamarin Native bridge?

Now you might ask how am I going to bridge the above explained Xamarin.Forms and Xamarin Native implementation counterparts together? Now that’s some easy peasy nibbles I’m gonna leave up to your creativity or requirement.

There’s many ways to call back and forth between Xamarin.Forms or Xamarin Native project levels, or in other words, between the PCL project and the Platform Specific projects. For starters, you could use Xamarin Dependency Service to register a service interface and concrete implementation to communicate between these two layers back and forth. 😉 And many other possibilities, so your creativity is the limit.

However I will probably be writing another blog post regarding this with a full implementation of this with some cool application of it! 😉

Well frankly, that’s it fellas.

Cheers! 😀

So I created a Popup with Transparent background in Xamarin Forms… ;)

Alright so I was supposed to post this few months back, before I got stuck with my day job which led to temporary put my blog on hold. Either way, recently I managed to find some free time off from work, so I would go ahead and post this with some necessary updates! 🙂

So a while back I was asked to create a Transparent popup control in Xamarin Forms, as ordered by my boss (a very cool guy) to be used for instances such as Loading Spinner screens, and Popup Dialog boxes.

Xamarin Forms ContentPage ? Transparency ?

So I tried to derive my custom control from the default ContentPage control of Xamarin Forms, by setting the Background color of the page to Transparent.

Although I’ve failed by pushing the Page to NavigationStack, I managed to get it working as a Modal page by pushing it to the ModalStack but only on Android platform.

Let’s get into coding…

Alright let’s get into some coding, first create the Custom Control by deriving from ContentPage.

    public class TransparentPopup : ContentPage
    {
        public TransparentPopup()
        {
            // set the background to transparent color 
            // (actually darkened-transparency: notice the alpha value at the end)
            this.BackgroundColor = new Color(0,0,0, 0.4);
        }
    }

 

Although this implementation worked out of the box on Android, it didn’t work as expected on iOS, probably due to the differences the page drawing process of Android and iOS, specially as a popup View.

So I played around with iOS and managed to get it working. So let’s create a custom renderer for iOS.

The deal here is to prepare the Popup to draw over the Parent View Controller which is the previous page. So that we could see through the Popup to see the page underneath which is the parent view. Becase in iOS when a new View Controller is introduced the previous View Controller’s View gets removed from the Window.

[assembly: ExportRenderer(typeof(TransparentPopup), typeof(TransparentPopupRenderer))]
namespace WhateverYourNamespace.iOS
{
    public class TransparentPopupRenderer : PageRenderer
    {
        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);
        }

        public override void DidMoveToParentViewController(UIViewController parent)
        {
            base.DidMoveToParentViewController(parent);

            if (ParentViewController != null)
            {
                // Preparing the view to get the presentation of the parent view for the background
                ParentViewController.ModalPresentationStyle = UIModalPresentationStyle.OverCurrentContext;
            }
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            // Setting the background color to transparent when the view is appearing
            View.BackgroundColor = UIColor.Clear;
        }
    }
}

 

DidMoveToParentViewController called when the current view gets added to the parent ViewController, so at that point we will set the ModalPresentationStyle of the parent controller, to OverCurrentContext property which will draw our popup view over the previous view.

Well that’s the iOS Custom Renderer, and like I mentioned before we are not going to be needing a Custom Rendering for Android, hence the Modal Page get’s drawn directly above the previous page view.

So let’s put it to use eh! 😉

 Navigation.PushModalAsync(new TransparentPopup());

 

Yep! that’s pretty much it. 🙂

Thou shalt grab em code up on my github: XFTransparentPopup

Cheers!

Wait for it……..

A journey through time…

*fast forwards time…*

*forwarding through time 4-6 months…*

*passing through them late night work hours at office…*

*days of procrastinating and laziness…*

*till this date (November, 2016)*

So after time travelling to this date I updated my local Xamarin installation and this project solution’s Xamarin references, hoping to refresh everything an finally finish off this article.

BOOM! EVERYTHING BROKEN!

Yep since the upgrade to the latest Xamarin references the above implementation has broken and transparency is working no more for the Modal Pages.

Hence it appears to be a change in the Xamarin Core implementation for ContentPage and the rendering process of Modal Pages with the latest update, there had been some other complaints in the Xamarin Forums regarding this. Although whatever the changes Xamarin Forms team has done, I’m sure they had their reasons. This seems to be occurring from all the new Xamarin versions, since I’ve been trying out few fresh Project solutions as well

Looks like I need to find an alternative (until I find a workaround)….

Alternative?

Very well… lucky enough I stumbled upon this awesome library called, Rg.Plugins.Popup! Which literally saved me tons of time. This is a Xamarin Forms library that allows you to create Transparent Popup pages, allowing you to open any ContentPage control as a popup page with full transparency background.

And this library solves a massive problem xamarin developers have been facing, which is the Transition animation control between pages, where as in default Xamarin Forms navigation stack, we can not modify the Transition animations between pages, but with this library, it’s all possible and we could add our own custom animations for page transitions.

capture

Go ahead visit their Github page for description: https://github.com/rotorgames/Rg.Plugins.Popup

Looks very promising indeed. Alright let’s try it out!

Praising le third party library…

Alright just for basics add the Rg.Plugins.Popup library to your Xamarin Forms project from Nuget.

This library provides us a base control that is called PopupPage, which gives you full Transparency background properties, therefore instead of deriving from ContentPage, now we are going to derive from PopupPage to our Transparent Page.

namespace WhateverYourNamespace
{
    public class TransparentPopup : PopupPage
    {
        public TransparentPopup()
        {
            // set the background to transparent color 
            // (actually darkened-transparency: notice the alpha value at the end)
            this.BackgroundColor = new Color(0, 0, 0, 0.4);
        }
    }
}

 

There you go, now let’s add some decorations to our Transparent Popup Page. 😉

public TransparentPopup()
{
	Button btnClose = new Button() { Text = "Close this" };
	btnClose.Clicked += BtnCloseOnClicked;

	Content = new StackLayout()
	{
		BackgroundColor = Color.Transparent,
		Children =
		{
			new Label()
			{
				Text = "Hello from Transparent Modal Page",
				FontSize = 18,
				TextColor = Color.White,
				HorizontalTextAlignment = TextAlignment.Center
			},
			new ActivityIndicator()
			{
				IsRunning = true
			},
			btnClose,
		},
		VerticalOptions = LayoutOptions.Center,
		Padding = new Thickness(10,0,10,0),
	};

	// set the background to transparent color 
	// (actually darkened-transparency: notice the alpha value at the end)
	this.BackgroundColor = new Color(0, 0, 0, 0.4);
}

private void BtnCloseOnClicked(object sender, EventArgs eventArgs)
{
	// Close the modal page
	PopupNavigation.PopAsync();
}

 

Alright, shotgun! There we have added a welcome Label, Activity indicator and a Button to close the popup.

Something important!

And as you can see on the BtnCloseOnClicked event, we are accessing a property called PopupNavigation, instead of default Xamarin Forms Navigation property, to remove the page from Stack.

Well its because Rg.Plugins.Popup maintains its own Popup-Navigation Stack which keeps references to the Popups of it’s own kind, which derives from the PopupPage. So we need to access that property to remove the page from our Navigation stack.

It also provides a Page background click behavior, which is if the user clicks on the background of the page, we could trigger an event to exit the page. Well in my case I didn’t want that to happen so let’s disable it. 😀

protected override bool OnBackgroundClicked()
{
	return false;
}

 

Alright, let’s consume this fella right now as below,

Navigation.PushPopupAsync(new TransparentPopup());

 

Now you must have expected to use the ordinary Navigation.PushModalAsync() as what we normally do in Xamarin Forms, yes of course you could do the same to open this Transparent Popup page, but you may loose the Transparency and ability to override the Navigation Transition animations.

Therefore we are using the PushPopupAsync() extension method that’s provided by this library, which is pretty cool. Now the reason for this I shall explain later in this post.

Alright! Let’s run this fella and see for ourselves! 🙂

nexus-5-lollipop-screenshot-1  simulator-screen-shot-6-dec-2016-10-46-02-am

WOOT! WOOT!

there you go! 😀

For You lazy people may fetch my code up on my githubXFTransparentPopupUpdate

Enjoy!

Important after-notes to share…

1. Page Transition Animations

In default Xamarin Forms Navigation we do not have the access to Page Transition Animations, hence we have to suck it up with the default boring Transition animations of Xamarin Forms.

But thanks to this library, Rg.Plugins.Popup maintains its own Popup-Navigation Stack which to allow us to control the Page Navigation Transition effects, unlike in default Xamarin Forms Navigation Stack. This is a great feature that is provided by this solution hence a lot of developers were having issues with this restriction of Xamarin Forms since long time back. 🙂

2. PushPopupAsync()

Also it is important to mention that, when using Popup pages of Rg.Plugins.Popup  we should always use the Navigation.PushPopupAsync() extension if we want to preserve the Transparency and Custom Page transition features. Meanwhile using the PopupNavigation.PopAsync() to remove the pages from the stack while maintaining transition effects. 😀

3. PushPopupAsync()

We are all aware of how on Android run time, Xamarin Forms uses a Single Activity to populate the Pages of our app. And usually when we add a Modal Page, it gets populated on top of the Single Activity the app is running on. But in this Library it uses a separate Android Dialog View which doesn’t use the Activity Stack, instead it draws itself over the Activity, (blocking the whole Activity content) such as in AndHUD library. So that’s something to keep in mind if you wonder why you couldn’t Push a Page on top of this popup page. 😉

Finally kudos to the developers of Rg.Plugins.Popup plugin for Xamarin Forms!