Tag Archives: Xamarin

XFHACKS-005 Button with full control on Text and Icon!

Ever came across an instance where you wished if you had more control or customization over the Text and Icon properties of your Xamarin.Forms Button? even better even without any Custom Renderers or Platform Specific code? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

Uh oh, in Xamarin.Forms?!

The default Xamarin.Forms Button has it’s own limitations for customisation, specially in the Text and Icon, there’s not much control over those properties in terms of,

  • Alignment of Text and Icon
  • Positioning of Text and Icon 
  • Default upper case Text in Android
  • Icon Image Size and Aspect Property
  • Icon Source only limited for Local Images

Talking of the Icon Source, you can only use Platform Specific Local Images for it, you cannot use Embedded Resources for it.

So I thought of making use of my own crazy imagination and hack my way around to fix all those limitations!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Usual approach…

Now as an out of the box solution for this we could avoid using Xamarin.Forms Button totally and switch to a Xamarin.Forms Label or Image control with a Tap gesture recognizer attached to it. But then it wouldn’t actually give that nice look and feel of a button does it, specially in Android that nice ripple effects and on iOS the fade out effect on the button click is something really nice to have on your UI.

So… wait for it….

XFHACKS Receipe!

Here’s my awesome solution, we’re still going to stick to Xamarin.Forms Button button, and we’ll be laying down a Label or an Image on top of our Button view inside a Grid layout. This is actually very common hack of mine if you had gone through previous XFHACKS articles of my blog.

Yep sounds super simple, yet solves all of the issues I just mentioned above. Basically we’re constructing our own Custom Button control right from Xamarin.Forms elements, properties and behaviours without any custom renderers or platform code.

So getting into more details, here’s how we’re going to solve the above talked issues. For Alignment of the Text and Icon in the button, we are going to use the HorizontalOption of both Image and Label element that we’re placing on top of the Button. Then the Position of those elements, we shall resort to the Margin property of each. Since we’re using the Image control itself the Source property issue is automatically solved. Then as an added advantage you could also have the control over the Aspect property of the Image Icon you want to display in your button.

Now on top of all that one might wonder when you place a Label or Image on top of a Button, wouldn’t it obstruct the Clickable touch area of the Button? That’s where InputTransparent comes into rescue, passing down the touch even down to the Button straight away!

To add some cherry on top of the icing, we’re going to use the IsClippedToBounds property to crop out any areas of the inner elements of the Grid being rendered outside the View bounds of the Grid itself, so everything comes together as a single Element on UI.

Now all these comes together solving the issues that I have pointed out at the beginning! 😉

Sneak Peak!

That’s what we gonna be build yol!

Code and Run!

Behold the golden XAML code!

<!--  Button with Text and Icon  -->
<Grid
    Grid.Row="1"
    Grid.Column="0"
    HeightRequest="40"
    HorizontalOptions="Fill"
    IsClippedToBounds="True"
    VerticalOptions="Center">

    <!--  Button Control  -->
    <Button BackgroundColor="#2196F3">
        <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
                <On Platform="Android" Value="-4,-6,-4,-5" />
                <On Platform="iOS" Value="0" />
            </OnPlatform>
        </Button.Margin>
    </Button>

    <!--  Text Label  -->
    <Label
        Margin="10,0,0,0"
        FontAttributes="Bold"
        FontSize="Small"
        HorizontalOptions="Start"
        HorizontalTextAlignment="Center"
        InputTransparent="True"
        Text="go next"
        TextColor="White"
        VerticalOptions="Center"
        VerticalTextAlignment="Center" />

    <!--  Icon Image  -->
    <Image
        Margin="0,0,5,0"
        HeightRequest="30"
        HorizontalOptions="End"
        InputTransparent="True"
        Source="{extensions:ImageResource XFHacks.Resources.rightarrowicon.png}"
        VerticalOptions="Center"
        WidthRequest="30" />
</Grid>

 

There you have it as we discussed earlier, our empty Button and on top of that the Label and the Image elements inside a Grid. As you can see the Button has some Margin value added for Android run time of, “-4,-6,-4,-5” which is to get rid of the default empty space that’s rendered around the Button at Android run time. The button will be spread across the whole Grid in background with its default HorizontalOptions=”Fill” property.

The Grid’s IsClippedToBounds=”True” property value makes sure it will cut off any inner elements that will render themselves out of the bounds of Grid. You can set whatever the HeightRequest or WidthRequest as you wish if you want to customize this even further.

Now speaking of the Label and Image you can see how I’m using the advantage of HorizontalOptions to align the elements as whatever the way I wish along with the Margin property of them, adding space wherever I wish. In here we have pushed the Label to the beginning of the Button and the Icon to the End of the Button horizontally.

Next the  InputTransparent=”True” comes in solving the touch issue, which will pass the touch action down to the Button element when the user clicks on it, giving the exact effect of a Button. The use of Image element we can now set whatever the size we wish for our Icon inside the button and adjust its Aspect property and so on.

And let’s try something else as well! Lets have a Button which has its Text and Icons aligned to the Right most corner.

<!--  Button with Text and Icon  -->
<Grid
    Grid.Row="0"
    Grid.Column="1"
    HeightRequest="40"
    HorizontalOptions="Fill"
    IsClippedToBounds="True"
    VerticalOptions="Center">

    <!--  Button Control  -->
    <Button Grid.ColumnSpan="2" BackgroundColor="#2196F3">
        <Button.Margin>
            <OnPlatform x:TypeArguments="Thickness">
                <On Platform="Android" Value="-4,-6,-4,-5" />
                <On Platform="iOS" Value="0" />
            </OnPlatform>
        </Button.Margin>
    </Button>

    <!--  Text Label  -->
    <Label
        Grid.Column="0"
        Margin="0,0,5,0"
        FontAttributes="Bold"
        FontSize="Small"
        HorizontalOptions="End"
        HorizontalTextAlignment="End"
        InputTransparent="True"
        Text="favs"
        TextColor="White"
        VerticalOptions="Center"
        VerticalTextAlignment="Center" />

    <!--  Icon Image  -->
    <Image
        Grid.Column="1"
        Margin="0,0,10,0"
        HeightRequest="30"
        HorizontalOptions="End"
        InputTransparent="True"
        Source="{extensions:ImageResource XFHacks.Resources.staricon.png}"
        VerticalOptions="Center"
        WidthRequest="30" />

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
</Grid>

 

Here’s another example where I have pushed the Image Icon to the End of the Button and the Label to be following it horizontally.

You can follow the same implementation and have our Button’s Text and Icon aligned t other Left most corner.

Now just like that you can customize all the aspects of a Button using this hack I just shared, just set up the Label and Icon with whatever the properties and customization as you wish on top of a Button. That’s it!

Fire it up!

Let me share some examples I’ve built using this awesomeness!

There you go our awesome Custom Button control running on Android, as you can see with all the preserved Button click effect! 😀

 

Since its completely out of the box Xamarin.Forms, you can run it across all the native platforms and expect the same results! 😉

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Advertisements

XFHACKS-004 Editor with a Placeholder!

Ever wanted to have a Placeholder property for your Xamarin.Forms.Editor control? Welcome to another lightening short post of me hacking around Xamarin.Forms elements to build cool stuff and get sh*t done! 😉

By Default Xamarin.Forms.Editor is a pretty boring control with not much room for customization, but is a very useful control. So I had always wondered why it didn’t have a Placeholder property like we have to the Entry control.

So I thought of build an Editor with a Placeholder by myself, without any custom renderers or native code or third party libraries. 😉

Sneak Peak!

That’s what we gonna be build yol!

XFHACKS Recipe!

So this recipe is going to be a bit advanced one, although the basic here is also going to be what we’ve been using last few XFHACK articles, the stacking of Elements on top of each other! my favorite! 😀 lol

Let me begin with the concept of Placeholder, which is a text display that is visible in any Text Editable element until the user starts typing their input, and if the user clears his input the Placeholder comes back to visibility.

In simple terms we are going to stack a Label underneath our Editor control which will act as the “Placeholder” element and then we’re going to do some external handling to make that given Label to be set visible or invisible based on users text input typing event. The first part is pretty straightforward but the second part needs more explaining I assume. To do that we’re going to make use of the awesome Triggers in Xamarin.Forms, we’re going to implement a simple TriggerAction which will react to the event of Text field change of our Editor control. So inside the trigger execution we will set the Placeholder Label to be visible or invisible.

The Golden Triggers: So we’re going to use DataTriggers of Xamarin.Forms that allows us to listen to changes in a Data Field and react up on it, in this case the changes of the Text property of our Editor control. We’ll attach the DataTriggers to the Label and bind them to the Editor.Text property, then reacting on that our TriggerAction will hide or visible the Placeholder Label.

How easy is that eh!

Code!

Let’s start off by implementing our awesomely simple TriggerAction which will be handling the event of Editor’s text field change.

/// <summary>
/// A simple trigger to change a
/// View's visibility dynamically
/// </summary>
public class VisibilityTriggerAction
			: TriggerAction<View>
{
	public bool IsViewVisible { get; set; }

	protected override void Invoke(View sender)
	{
		sender.IsVisible = IsViewVisible;
	}
}

 

So we have a TriggerAction which can be reused anywhere to set a given View’s Visibility on demand, the reason I made it as a “View” type is exactly for the reason of reusability. So inside our Trigger we will be changing the value of IsViewVisible property to change the visibility of the Placeholder Label.

Behold the golden XAML code!

<!--  Editor with a Placeholder  -->
<Grid
      BackgroundColor="#b3ddff"
      HeightRequest="100"
      HorizontalOptions="Center"
      WidthRequest="250">

      <Label
            InputTransparent="True"
            Text="Type anything here..."
            TextColor="Gray">
            <Label.FontSize>
                  <OnPlatform x:TypeArguments="x:Double">
                        <On Platform="Android" Value="17" />
                        <On Platform="iOS" Value="17" />
                        <On Platform="UWP" Value="15" />
                  </OnPlatform>
            </Label.FontSize>
            <Label.Margin>
                  <OnPlatform x:TypeArguments="Thickness">
                        <On Platform="Android" Value="5,11,0,0" />
                        <On Platform="iOS" Value="4,9,0,0" />
                        <On Platform="UWP" Value="11,5,0,0" />
                  </OnPlatform>
            </Label.Margin>
            <Label.Triggers>
                  <!-- the DataTriggers 
                           reacts to Editor.Text changes -->
            </Label.Triggers>
      </Label>
      <Editor
            x:Name="editor"
            BackgroundColor="Transparent"
            TextColor="Black" />

</Grid>

 

There you have the Editor and the Label stacked on top of each other acting like a Placeholder for the Editor. Something important to note here is that, you can see the Margin property being set up in a bunch precise values, this was to align the Label’s text field with the text field of the Editor, so that they superpose each other nicely, which in returns gives the exact look and feel of a Placeholder property. 😉 In addition to that I have very carefully adjusted the default FontSize of the Label to match to the Editor’s! Smart eh!

So with that note, if you want to customize the Editor’s FontSize or Font itself, you need to make sure to do the similar changes accordingly to the underlying Label’s property to match the same appearance.

Now here’s the important bit, the golden Trigger. So we’re going to attach two DataTriggers, one for listening to the Editor.Text property’s null value instance (this is to be safe of null values in certain different platforms) and the other is for Editor.Text.Length property value changes. Based on those two instances we’re activating our Triggers accordingly with passing in the IsViewVisible value to it.

So here are the XAML of the DataTriggers we just spoke about, which you should plug into the above code!

<!--  the DataTriggers reacts to Editor.Text changes  -->
<DataTrigger
      Binding="{Binding Source={x:Reference editor}, Path=Text.Length}"
      TargetType="Label"
      Value="0">
      <DataTrigger.EnterActions>
          <triggers:VisibilityTriggerAction IsViewVisible="True" />
      </DataTrigger.EnterActions>
      <DataTrigger.ExitActions>
          <triggers:VisibilityTriggerAction IsViewVisible="False" />
      </DataTrigger.ExitActions>
</DataTrigger>
<DataTrigger
      Binding="{Binding Source={x:Reference editor}, Path=Text}"
      TargetType="Label"
      Value="{x:Null}">
      <DataTrigger.EnterActions>
          <triggers:VisibilityTriggerAction IsViewVisible="True" />
      </DataTrigger.EnterActions>
      <DataTrigger.ExitActions>
          <triggers:VisibilityTriggerAction IsViewVisible="False" />
      </DataTrigger.ExitActions>
</DataTrigger>

 

There you have it, we’re binding our DataTriggers to the Editor’s Text property according to the two instances we discussed of, and setting the VisibilityTriggerAction‘s value to hide or visible our Placeholder Label.

Now as usualy could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Pretty straight forward eh!

Fire it up!

 

There you have it running on Android, iOS and UWP like a charm! 😀

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

XFHACKS-003 Editor with a Border!

Ever wanted to have a Border around your Xamarin.Forms.Editor control? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

Sneak Peak!

That’s what we gonna be build yol!

XFHACKS Recipe!

The default Xamarin.Forms.Editor control is a very dull and simple control which doesn’t have much of customization properties of its own. In this case the Editor doesn’t even have a proper border around it that explicitly shows the edge of the element. So here we’re going to look into how to add a nice Border around Editor in Xamarin.Forms without any custom renderers or 3rd party libraries!

We all know the Frame control, which has a nice Border property, and also CornerRadius property allowing us to control the curves of the corner edges of it. This is the simple magic we’re going to use here. We’re going to wrap our Editor inside this Frame control. 😀

How simple and easy is that eh!

Code!

Behold the golden XAML code!

<!--  Editor with a Border Control  -->
<Frame
	Padding="5"
	CornerRadius="8"
	HasShadow="True"
	OutlineColor="#2196F3">
	<Editor BackgroundColor="Transparent" TextColor="Black" />
</Frame>

 

So there we go as we discussed the Frame is wrapping around the Editor control. So the Frame has been configured with CornerRadius property so we can have some nice round corners. Then the Padding has been reduced to 5 so we have less space between the border and the Editor view, this you may change as you wish. 😉

HasShadow property is something you could change as you wish, which you should keep in mind, behaves differently on iOS and Android.

Now just to add something extra, imagine if you wanted to have the whole background with a certain color for the given Editor, this is how simple it is!

<!--  Editor with a Border Control  -->
<Frame
	Grid.Row="4"
	Padding="5"
	BackgroundColor="#7fc5ff"
	CornerRadius="8"
	HasShadow="False">
	<Editor BackgroundColor="Transparent" TextColor="Black" />
</Frame>

 

We simply add the BackgroundColor property of the Frame and then you set the HasShadow to false so it doesn’t show up Border Color just for the kicks of it. 😀 So just like that you could easily customize this as you wish!

 Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Fire it up!

There you have it running on Android and iOS like a charm!

Let me type something inside our “cool” Editor…

 

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

XFHACKS-002 Button with an Icon!

Ever wanted to have an Icon element attached to a Xamarin.Forms.Button control? Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

No custom renderers, no platform specific code and no third party libraries! Just by using pure out of the box Xamarin.Forms! 😉

Sneak Peak!

That’s what we gonna be build yol!

Now for something like that you’re going to assume we need some custom renderers or platform specific code or third party library use, but no no no! not on my watch! 😀

XFHACKS Recipe!

In this recipe we’re going to use the same concept that we used in the XFHACKS-001 article, stacking Elements on top of each other using Xamarin.Forms Grid Layout. So here we’re placing an Image on top of a Button.

Now you might wonder wouldn’t that void the touch event of the Button, since the Image will be covering a part of the Button touch area? Now that’s where the magic property called InputTransparent comes into play. Using this property we can disable the touch input interaction for any given View and pass it down to the next child underneath. 😀

Code!

Behold the golden XAML code!

<!--  Button with an Icon Control  -->
<Grid
	Grid.Row="1"
	HorizontalOptions="FillAndExpand"
	WidthRequest="200">

	<!--  Button Control  -->
	<Button
		Grid.Column="0"
		Grid.ColumnSpan="2"
		BackgroundColor="#2196F3"
		HorizontalOptions="FillAndExpand"
		Text="Click me!"
		TextColor="White" />

	<!--  Icon Image  -->
	<Image
		Grid.Column="1"
		Margin="0,0,10,0"
		HeightRequest="25"
		HorizontalOptions="End"
		InputTransparent="True"
		Source="{local:ImageResource
			XFHacks.Resources.dropdownicon.png}"
		VerticalOptions="Center"
		WidthRequest="25" />

        <Grid.RowDefinitions>
          <RowDefinition>
               <RowDefinition.Height>
                    <OnPlatform x:TypeArguments="GridLength">
                         <On Platform="Android" Value="50" />
                         <On Platform="iOS" Value="40" />
                         <On Platform="UWP" Value="40" />
                    </OnPlatform>
               </RowDefinition.Height>
          </RowDefinition>
        </Grid.RowDefinitions>
	<Grid.ColumnDefinitions>
		<ColumnDefinition Width="*" />
		<ColumnDefinition Width="35" />
	</Grid.ColumnDefinitions>
</Grid>

There you have it just like we discussed, inside the Grid we have a Button, and on top of that we have an Image, with our magical property InputTransparent set to true, which disables the touch events of the Image redirecting them on to the Button itself. So by this the whole Image and Button works as a single Button control.

I have given a little padding to the Image, so that the icon doesn’t corner itself in the Button. The Image has a fixed width and height of 25 units, and its set to the second column of the Grid, whereas the Button spreads across two columns filling up the entire space of the Grid. Thereby you can set any fixed size to the Grid itself or let it Fill up whatever the parent container its holding.

 Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Pretty straight forward eh!

Fire it up!

  

There you have it running on Android, iOS and UWP like a charm!

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

XFHACKS-001 Picker with an Icon!

Ever wanted to have an Icon element attached to a Xamarin.Forms.Picker control? Then you’re at the right place. Welcome to another lightening short post of me hacking around Xamarin.Forms elements!

Sneak Peak!

That’s what we gonna be build yol!

XFHACKS Recipe!

Usually you would think you need to implement a Custom Renderer to get this done or use a third party control! I say NO! NO! NO!

You can easily do this right from Xamarin.Forms without any native coding or 3rd party library, let me explain.

In a Xamarin.Forms Grid layout we could place Elements on top of each other, using this simple advantage, we’re going to place an Image as an icon under a Picker control, and of course we’ll be setting the Background color of the Picker to Transparent! 😉 Simple right?!

Code!

Behold the golden XAML code!

<!--  Picker with an Icon Control  -->
<Grid
     Grid.Row="1"
     HorizontalOptions="Center"
     WidthRequest="200">

     <!--  Icon Image  -->
     <Image
          Grid.Column="1"
          HeightRequest="25"
          HorizontalOptions="End"
          Source="{local:ImageResource XFHacks.Resources.dropdownicon.png}"
          VerticalOptions="Center"
          WidthRequest="25" />

     <!--  Picker Control  -->
     <Picker
          Title="Select a Monkey"
          Grid.Column="0"
          Grid.ColumnSpan="2"
          BackgroundColor="Transparent">
          <Picker.ItemsSource>
               <x:Array Type="{x:Type x:String}">
                    <x:String>Baboon</x:String>
                    <x:String>Capuchin Monkey</x:String>
                    <x:String>Blue Monkey</x:String>
                    <x:String>Squirrel Monkey</x:String>
                    <x:String>Golden Lion Tamarin</x:String>
                    <x:String>Howler Monkey</x:String>
                    <x:String>Japanese Macaque</x:String>
               </x:Array>
          </Picker.ItemsSource>
     </Picker>

     <Grid.RowDefinitions>
          <RowDefinition>
               <RowDefinition.Height>
                    <OnPlatform x:TypeArguments="GridLength">
                         <On Platform="Android" Value="50" />
                         <On Platform="iOS" Value="35" />
                    </OnPlatform>
               </RowDefinition.Height>
          </RowDefinition>
     </Grid.RowDefinitions>
     <Grid.ColumnDefinitions>
          <ColumnDefinition Width="*" />
          <ColumnDefinition Width="25" />
     </Grid.ColumnDefinitions>
</Grid>

 

There you have it just like we discussed in the recipe, we have placed our Picker control on top of the Image control, and we’re using a Grid to bring all of this together. If you look closely, we are using two columns, the Picker is spread across both columns, and the Icon Image is only added to the last column, with a fixed width of 25 units, thereby aligning the Icon to the right most corner of the Picker from underneath it. 😀

You can set the WidthRequest to whatever the value you prefer. And as of Platform specific values we’re setting the Grid Height accordingly to the best appearance of Android and iOS separately, you’re in full liberty to change them as you wish. 

Important: You could also move that whole piece of XAML to a separate XAML file, so that you could set it up as a reusable Control in your project! 😉

Pretty straight forward eh!

Fire it up!

 

There you have it running on Android and iOS!

Grab it on Github!

https://github.com/UdaraAlwis/XFHacks

Well then, that’s it for now. More awesome stuff on the way!

Cheers! 😀 share the love!

Welcome to XFHACKS Series!

Hello humans, welcome to my XFHACKS series, where I share my experience on hacking around the Xamarin.Forms environment and pushing the limits of it to get sh*t done, in all kinds of unexpected and creative ways! 😀

Specially I’m going to share my experience on implementing beautiful UI elements right from Xamarin.Forms, without any native implementations. The majority misconception is that in order to implement complex or highly customized UI elements with Xamarin.Forms, you often need to use a third party library or create custom renderers and do native customization, every single time!

I’m here to prove them wrong! There’s so many ways to implement complex and beautiful UI elements right from Xamarin.Forms out of the box without the need of any native renderers or third party libraries! 😀

Stay tuned fellas! Awesome stuff on the way!

Although I’m thinking of renaming the series name to HACKXAMFORMS though instead of XFHACKS!

Meh! I’ll think about it later! 😛

Cool Animating Dots Control from Xamarin.Forms Animations!

Three dots, blinking and pulsating sequentially made with pure Xamarin.Forms Animations! (no third party elements, heck not even any images used)

A little fun experimental-implementation I did a while back, actually based on something I did long time ago for an office project, but then figured out I could make it much better in a later time, so thought of working on it and putting it out there.

So basically we needed to have a Loading screen or Activity indicator screen with cool three dots animating sequentially, instead of using a GIF, I wanted to do this purely from Xamarin.Forms without any use of a 3rd party component, not even any image or icon.

Yes, I ended up hacking my way to get this done!

Here’s that interesting journey unfolding…

Xamarin.Forms.Animations is awesome!

This is something I need to get out of my chest. No one would actual believe this, but there’s so many awesome stuff you could do with the built in Animations of Xamarin.Forms right out of the box.

Surprisingly it’s super simple as well!

Sneak Peak!

So here’s what I’ve built and what you’re gonna get! 😉

TADAAA! pretty cool eh!

Let’s get started…

So before I get started, the requirement here is to build a reusable “Control” that we can embed into a ContentPage that we would be using as a “Loading Screen” or an Activity Indicator screen as some might call it. So this is going to be a separate reusable View which you can embed anywhere you want to and use it right away, which will be independent of it own, yes even the whole Animation sequence is self sustained by itself. 😉 Oh yeah! Cool stuff ahead! 😀

Building the UI..

First of all let’s go on create a ContentView control, let’s name it, AnimatingDotsControl!

What we need here is just simple “three dots”, but like I said in the beginning I don’t want to use any third party components or even external Image to emulate “a dot” element.

So what am I going to use for “a dot”? Xamarin.Forms.Frame! MIND BLOWN!

Let the Hack-be-unfolded!

Right on fellas, just another Xamarin.Forms hack of my own, Frame View has this awesome property called CornerRadius, which we are going to use for our advantage here, when its sufficiently set properly to the proportion of the width and height of it, voila! you render a circle or a dot in this case.

So let’s go on add three Frame elements horizontally inside a Grid view. And also to emulate the blinking, “on” and “off” state of a dot, we need to maintain two Frame elements to represent one dot each. We’re going stack them on top of each other, so when the first one goes to off state the second one in the background will come to visibility and emulate the off state. So for the ease of use let’s call our tiny little Frame elements, Dot1, Dot2 and Dot3 and lay them out nicely as we discussed.

<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
    x:Class="XFAnimatingDotsControl.AnimatingDotsControl"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
    <ContentView.Resources>
        <ResourceDictionary>
            <Style x:Key="AnimatingDotsStyle" TargetType="Frame">
                <Setter Property="Padding" Value="5" />
                <Setter Property="BackgroundColor" Value="White" />
                <Setter Property="CornerRadius" Value="6" />
                <Setter Property="HasShadow" Value="False" />
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="Center" />
                <Setter Property="HeightRequest" Value="4" />
                <Setter Property="WidthRequest" Value="4" />
            </Style>

            <Style
                x:Key="BackgroundDotsStyle"
                BasedOn="{StaticResource AnimatingDotsStyle}"
                TargetType="Frame">
                <Setter Property="BackgroundColor" Value="DimGray" />
            </Style>
        </ResourceDictionary>
    </ContentView.Resources>
    <ContentView.Content>
        <Grid ColumnSpacing="2" HorizontalOptions="Center">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="25" />
                <ColumnDefinition Width="25" />
                <ColumnDefinition Width="25" />
            </Grid.ColumnDefinitions>

            <!--  Background Dots  -->
            <Frame Grid.Column="0" Style="{StaticResource BackgroundDotsStyle}" />
            <Frame Grid.Column="1" Style="{StaticResource BackgroundDotsStyle}" />
            <Frame Grid.Column="2" Style="{StaticResource BackgroundDotsStyle}" />

            <!--  Animating Dots  -->
            <Frame
                x:Name="Dot1"
                Grid.Column="0"
                Style="{StaticResource AnimatingDotsStyle}" />
            <Frame
                x:Name="Dot2"
                Grid.Column="1"
                Style="{StaticResource AnimatingDotsStyle}" />
            <Frame
                x:Name="Dot3"
                Grid.Column="2"
                Style="{StaticResource AnimatingDotsStyle}" />
        </Grid>
    </ContentView.Content>
</ContentView>

 

There you go. Just like we discussed we have our UI set up in a reusable ContentView control, just like we discussed above. Oh and don’t be worried by the use of Styles, I just like to make my XAML look neat and clean. 😉

Building the Animation!

Here’s the golden part of the whole post, the actual Animation magic brewed purely with Xamarin.Forms! Most people are aware only of the Xamarin.Forms Animation Extension methods, the typical FadeTo(), ScaleTo(), etc whatnot. But that’s just the tip of the ice berg I tell you! 😀

Here’s a little heads up if you’re not aware: Xamarin.Forms.Animation!
The whole Xamarin.Forms.Animation class itself has many more awesomeness possibilities, it allows us to create our own Animation sequences. Oh yeah! how cool is that eh!

These custom Animation objects can be attached to any Xamain.Forms.View and make them dance like whatever the ways we want, as in to animate any of its properties as we wish. They can sequentially change value of any property for any given period of time, even repeatedly. That is the whole bread and butter of this implementation. The Animation object constructor allows us to execute a sequential loop of an action with any given value, incremented or decremented, with the Easing properties, and finishing it with another action. Let’s use this for our advantage…

new Animation(alpha => Dot1.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot1.FadeTo(1))

 

So we’re going to using the Opacity property of our Frame view, and change its value from 1 to 0 in a loop, with an CubitOut Easing behavior, and reversing it back in the end of the execution, thus creating the blinking effect! 😀

And here’s the coolest part, you can actually attach an Animation object into another Animation object, and so on, so that you can execute a bunch animations sequentially across multiple views. Animation.Add() method gives you this awesomeness, where as you can define a starting point of the timeline and ending point for that specific animation object, in the whole animation sequence. So given our three animating elements, let’s break our timeline into 3 time chunks, giving each element a time span of 0.33 milliseconds.

var pulseAnimation1 = new Animation();

pulseAnimation1.Add(0, 0.33, new Animation(alpha => Dot1.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot1.FadeTo(1)));

 

So using that we’re going to animate three of our “dot views”, Dot1, Dot2 and Dot3, by attaching their own animation objects to a single Animation. We’re going to repeat the same above Add() call to Dot2 and Dot3 in the next step.

Before I get into the full animation code, the way we actually run this animation sequence is by calling the Animation.Commit() method, passing the parent View and some useful bits we could use to customize the animation sequence altogether.

private void RunAnimations()
{
	var pulseAnimation1 = new Animation();

	pulseAnimation1.Add(0, 0.33, new Animation(alpha => Dot1.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot1.FadeTo(1)));
	pulseAnimation1.Add(0.33, 0.66, new Animation(alpha => Dot2.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot2.FadeTo(1)));
	pulseAnimation1.Add(0.66, 0.99, new Animation(alpha => Dot3.Opacity = alpha, 1, 0, Easing.CubicOut, () => Dot3.FadeTo(1)));
	
	pulseAnimation1.Commit(this, 
		"loadingIndicatorPulseAnimation",
				10, 1100, null, null, () => true);            
}

 

So you can see how we have allocated each animation chunk 0.33 milliseconds and most importantly at the end the Commit() call, passing in the current view we’re attaching this animation to, the time in milliseconds between frames, the allocated time in milliseconds  for the whole animation sequence, and the null for easing and finishing action, since I’ve already defined them in the child animations themselves, and the last parameter, enabling the repeating functionality. So the animation will keep running forever as long as its active.

Now we have a self sustaining animation that runs repeatedly, but what if we want to stop it and discard it, in the case of the disposing or removing the View? that’s where AbortAnimation() call comes in.

// abort the animation on element disposing
this.AbortAnimation("loadingIndicatorPulseAnimation");

 

Remember we gave a little name to our animation? yeah that’s what we’re going to use and such a simple call the animation will stop and discard itself.

A true self sustaining Animation Control!

Alright! So now we have our full Animation implemented, the next thing we need to do is to make sure its self sustaining, since we’re going to use it inside an independent control.

So whenever the Control is attached to the UI or made visible, we need to make sure to start the Animation and when the Control is removed from UI or disposed, then we should stop the animation and dispose itself.

In order to do this we need to look into the life cycle of a Xamarin.Forms.View!

Let the Hack-be-unfolded!

So this is a little hacking around I came up with myself after overriding a bunch of methods and debugging the run time of Xamarin.Forms, where as when any given View gets attached to a parent or becomes visible, there’s an internal property that gets fired, which is called “Renderer”, even at the time of View goes out of visibility or removed from parent, the same property will get fired. I’m presuming this to a call to the native renderer of the View itself back and forth at runtime. I’m going to use this as Entry and Exit points for managing our Animation.

We shall override the OnPropertyChanged event of our ContentView and watch out for the “Renderer” property change, maintain a little flag to mark down our Animation started and ended state.

public partial class AnimatingDotsControl : ContentView
{
     public AnimatingDotsControl()
     {
          InitializeComponent();
     }

     private bool _animationStarted;
     
     protected override void 
          OnPropertyChanged(
               [CallerMemberName] string propertyName = null)
     {
          base.OnPropertyChanged(propertyName);

          if (propertyName == "Renderer")
          {
               if (!_animationStarted)
               {
                    // start the animation on element rendering
                    _animationStarted = true;

                    RunAnimations();
               }
               else
               {
                    // abort the animation on element disposing
                    this.AbortAnimation(
                            "loadingIndicatorPulseAnimation");
               }
          }
     }

     private void RunAnimations()
     {
          ...    
     }
}

 

There you go, now we have a fully self sustaining animation which will start on its own when the Control is attached to a parent or made visible, and then dispose itself when the Control is removed from parent or made out of visibility! 😀

Let’s consume it!

No more waiting, let’s consume this bad boy!

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
    x:Class="XFAnimatingDotsControl.LoadingScreen"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:xfAnimatingDotsControl="clr-namespace:XFAnimatingDotsControl;assembly=XFAnimatingDotsControl"
    BackgroundColor="Gray">

    <Frame
        BackgroundColor="Transparent"
        HasShadow="False"
        HorizontalOptions="Center"
        OutlineColor="Transparent"
        VerticalOptions="Center">
        <StackLayout
           BackgroundColor="Transparent"
           Orientation="Vertical">
            <Label
                FontAttributes="Bold"
                FontSize="23"
                HorizontalOptions="Center"
                HorizontalTextAlignment="Center"
                Text="Loading"
                TextColor="White" />
            <!--  Embedding our Animating Dots Control  -->
            <xfAnimatingDotsControl:
                 AnimatingDotsControl HorizontalOptions="Center" />
        </StackLayout>
    </Frame>

</ContentPage>

 

There we have embeded our own AnimatingDotsControl into a ContentPage that we would be using as a “Loading Screen” or an Activity Indicator screen as some might call it. Then you could use that page as a Modal Page and make it visible or discard whenever you wish so. 😉

You can attach our little awesome Animation dots control anywhere as you wish and it will work out nicely like a charm, while behaving and maintaining itself.

 

That’s our bad boy in action on iOS and Android! 😀

Github it if yo lazy!

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

Feel free to grab your copy if you’re too lazy to DIY! 😛

Imagination and creativity is your weapon against the odds, keep on pushing the limits and hacking your way through my fellow developer! That’s what makes us the “Developers”, we build cool stuff yol!

That’s it for today.

Cheers all! 😀 Share the love!

Advanced Prism Tab Navigation with MVVM & Test friendly manner in Xamarin.Forms!

If you’re looking for how to navigate inside a Xamarin.Forms Tab Page programatically in a MVVM friendly and Test-able manner, without having any XAML-Code-Behind garbage. Welcome to my post!

Keep in mind, since this is an advanced topic, there’s not going to be any step by step intro’s to Prism or MVVM or whatnot ;)!

Sneak Peak!

Here’s a little sneak peak of the outcome of it.

PERKS:

  • Switch between Child-Tabs when you are,
    • Coming into the TabbedPage
    • Already in the TabbedPage
    • Coming back to the TabbedPage
  • Fully MVVM compatible
  • Fully Test-able, yaay!
  • Binding, Commands and Interfaces FTW!
  • Almost no XAML-code-behind garbage
  • Coming back to the TabbedPage, the Child-Tab switching occurs only when the TabbedPage is actually visible

How cool is that eh! 😉

 

Woot! Let’s get started then…

My MVVM addiction…

You know me, I’m all about that MVVM & Test-able Software Architecture life forever yol! xD

Being hustling with one of the best dot net application craftsman, has made a massive impact on my perspective of software engineering, rather than just writing some code, putting some shit together and make it work. I’m extremely obsessed with architecture of any given application I develop now, long last extendability, and fully test driven approach. High quality, clean code with all of dot net standards and complete separation of Views and ViewModels.

Backstory…

So recently, I was working on this Xamarin.Forms application which was using Prism as the MVVM framework with a fully test driven architecture. There we had all of our Views and ViewModels separately implemented with a clean architecture, whereas we didn’t have a single line of extra XAML-code-behind garbage. 😛

So the requirement was to implement a TabbedPage and which should be able to switch between its Child-Tabs programatically at runtime, to be more specific, we should be able switch the selected Child-Tab when the user is:

  • Coming into the TabbedPage
  • Already in the TabbedPage
  • Coming back to the TabbedPage after navigating forward.

And the most interesting part was this we had to handle this in a fully MVVM and Testable manner. 😮

Now this would have been much easier, if you had taken out the whole MVVM and Test-first aspect out of the equation, with some dirty XAML-code-behind garbage you can easily handle this. But in this situation, I was backed against the wall, How on earth could anyone achieve this?

but as usual, I figured it out!

The Recipe time…

So here’s how I implemented it, in conclusion we’re going to use an Interface that will allow us to bridge the View-ViewModel separation and a Bindable property inside the TabbedPage, that will react to the changes of the ViewModel’s “SelectedTab” property.

That interface is going to be implemented into the ViewModel. Then through the ViewModel we’re going to register that whole instance in our IoC container, when the user navigates into the TabbedPage. The bindable-property of the TabbedPage will be bound to the property in ViewModel. 😀

Which will allow us to access the interface instance from the IoC container from anywhere in our code and change the Selected Child-Tab.

Oh also I forgot to mention that with Prism, by default we can set the selected Tab-Child when we ‘first navigate into the Tab Page’, so handling that scenario is going to be a no-brainer, thus I will not focus on it in this post.

We shall work on navigating inside the TabbedPage when we’re already inside it, and when we’re coming back to the TabbedPage from another page after navigating forward. Which is going to be a piece of cake with our interface implementation approach.

Just to add something extra, we will maintain a flag property inside the TabbedPage, to make sure to allow the Selected Child-Tab switching happens only when the TabbedPage is visible to the user. Just to make it look nicer!

Since all of this is a simple combination of Bindable-Properties, Interfaces and Commands, this whole implementation is fully test-able. Yeah fine, I’ll show you how to write some tests for it as well! 😛

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

Implementation time…

So just a heads up, my project configuration is as follows.

I’m using a Xamarin.Forms project (dot net Standard 2.0) created with Prism Templates for Visual Studio. And the IoC container is the default Unity container comes with Prism.Forms setup. As of the Tests I’m using a xUnit Dot net project, which I will get into details later.

So before you begin make sure you have the above setting in place.

1. interface to save the day…

First, the simple Interface which is going to save the day like we discussed above…

public interface IMyTabbedPageSelectedTab
{
	int SelectedTab { get; set; }

	void SetSelectedTab(int tabIndex);
}

 

There we have a SelectedTab property, and a separate setter method for it, just in case for backup scenario. If you don’t need both then stick to one of them. 😀

2. the TabbedPage…

Alright then let’s get started with our TabbedPage implementation, let’s call it MyTabbedPage.

<TabbedPage
    x:Class="AdvPrismTabNavigation.Views.MyTabbedPage"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:local="clr-namespace:AdvPrismTabNavigation.Views;assembly=AdvPrismTabNavigation"
    xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
    Title="{Binding Title}"
    prism:ViewModelLocator.AutowireViewModel="True"
    SelectedTabIndex="{Binding SelectedTab}">
    <TabbedPage.Children>
        <local:TabChild1Page />
        <local:TabChild2Page />
        <local:TabChild3Page />
    </TabbedPage.Children>
</TabbedPage>

 

There’s the XAML code for our MyTabbedPage, notice how we’re binding the SelectedTabIndex property to the ViewModel’s property which I’ll show later in this post. Meanwhile let’s have add some child pages to our MyTabbedPage as well.

Alright next take a look at the MyTabbedPage‘s code behind stuff, which is very minimal.

public partial class MyTabbedPage : TabbedPage
{
	private bool _isTabPageVisible;

	...
        // SelectedTabIndex 
	// bindable property goes here...
	...

	public MyTabbedPage()
	{
		InitializeComponent();
	}
	
	protected override void OnAppearing()
	{
		base.OnAppearing();

		// the tabbed page is now visible...
		_isTabPageVisible = true;

		// go ahead and update the Selected Child-Tab page..
		this.CurrentPage = this.Children[SelectedTabIndex];
	}

	protected override void OnDisappearing()
	{
		base.OnDisappearing();

		// the Tabbed Page is not visible anymore...
		_isTabPageVisible = false;
	}

	protected override void OnCurrentPageChanged()
	{
		base.OnCurrentPageChanged();

		// when the user manually changes the Tab,
		// we need to update it back to the ViewModel...
		SelectedTabIndex
			= this.Children.IndexOf(this.CurrentPage);
	}
}

 

As I mentioned in the recipe, there’s the flag _isTabPageVisible, we’re going to use to keep track of the Visibility of the TabbedPage. There when we’re coming back to the TabbedPage from a backward navigation, we’re executing the selected Child-Tab according to the SelectedTabIndex bindable property.

Important Note: You can even make the above little chunks of code go away from the XAML-Code-behind, by using triggers and attached properties, which I’m not going to get into here, to maintain the simplicity of the implementation. Come on, use your own creativity people! 😉

Next we’re creating the Bindable Property inside the TabbedPage which will handle the View-ViewModel communication. Let’s call it SelectedTabIndex property.

public static readonly BindableProperty SelectedTabIndexProperty =
	BindableProperty.Create(
		nameof(SelectedTabIndex), 
		typeof(int),
		typeof(MyTabbedPage), 0,
		BindingMode.TwoWay, null,
		propertyChanged: OnSelectedTabIndexChanged);
static void OnSelectedTabIndexChanged
	(BindableObject bindable, object oldValue, object newValue)
{
	if (((MyTabbedPage)bindable)._isTabPageVisible)
	{
		// update the Selected Child-Tab page 
		// only if Tabbed Page is visible..
		((MyTabbedPage)bindable).CurrentPage 
		= ((MyTabbedPage)bindable).Children[(int)newValue];
	}
}
public int SelectedTabIndex
{
	get { return (int)GetValue(SelectedTabIndexProperty); }
	set { SetValue(SelectedTabIndexProperty, value); }
}

 

Looks neat eh, so its a simple Bindable property as you can see, but however we’re handling it’s OnSelectedTabIndexChanged event ourselves because when the value changes from ViewModel’s end we need to update it on our UI’s end, as you can see we’re having a little flag property inside our MyTabbedPage 

3. the ViewModel…

Now is the time for MyTabbedPageViewModel stuff to come along. Nothing fancy just a standard ViewModel, but we need a reference to the IoC container (whichever it is you’re using) because we need to register our interface instance in it. This ViewModel as we discussed before is going to implement our IMyTabbedPageSelectedTab interface and its method and property.

public class MyTabbedPageViewModel 
          : ViewModelBase, IMyTabbedPageSelectedTab
{
     private readonly IUnityContainer _unityContainer;

     private int _selectedTab;
     /// <summary>
     /// Binds to the View's property
     /// View-ViewModel communcation
     /// </summary>
     public int SelectedTab
     {
          get { return _selectedTab; }
          set
          {
             SetProperty(ref _selectedTab, value);
             Title = $"My Tabbed Page - Tab [{SelectedTab + 1}]";
          }
     }
     
     public MyTabbedPageViewModel
          (INavigationService navigationService,
                         IUnityContainer unityContainer)
          : base(navigationService)
     {
          Title = $"My Tabbed Page - Tab [{SelectedTab + 1}]";

          this._unityContainer = unityContainer;

          // register this instance so we can access 
          // IMyTabbedPageSelectedTab anywhere in the code
          _unityContainer.RegisterInstance<IMyTabbedPageSelectedTab>
                    (this, new ContainerControlledLifetimeManager());
     }

     public void SetSelectedTab(int tabIndex)
     {
          SelectedTab = tabIndex;
     }
}

 

The SelectedTab property in the ViewModel is the one that’s binding to the SelectedTabIndex property in the MyTabbedPage, now you can see the bridge between the View-ViewModel.

Here we’re registering this ViewModel instance by the type of IMyTabbedPageSelectedTab so that we can access it from anywhere using the same type and also we’re passing in ContainerControlledLifetimeManager() parameter because we need to make sure that instance is properly managed by the container and garbage collected later when not in use.

4. finally Consume it…

So here is the little Magic code snippet you need to execute, wherever you wish to have access to programatically switching the Selected Child-Tab of our MyTabbedPage.

_unityContainer.Resolve<IMyTabbedPageSelectedTab>().SetSelectedTab(tabIndex);

 

You simply access the registered service interface and call on the SetSelectedTab() or simply you could also call the IMyTabbedPageSelectedTab.SelectedTab property directly as well. 😉

Just a little note, well this may not be the best of all approaches but this is what I believe is a better solution given my experience and expertise. But if you have a better alternative, please feel free to share!

Let’s fire it up!

So here’s this bad boy in action…

 

That’s the Child-Tab being switched programatically while inside the TabbedPage!

 

And here’s how nicely the Child-Tabs are switching programatically while outside the TabbedPage! As you can see when coming back to the TabbedPage, it nicely moves to the Selected Child-Tab…

Eyyy look at that! 😀

How about UnitTest-ing…

Uh fine, let me show you. 😛

In my case I used xUnit.net for my Test project, along side Prism.Forms and Xamarin.Forms.Mocks for mocking Xamarin.Forms run time.

Switching between Child-Tabs inside the TabbedPage:

//  Let's Tab-Navigate to TabChild2Page
_appInstance.Container.Resolve<TabChild1PageViewModel>()
			.GoToNextTabCommand.Execute("1");

//  Am I in the MyTabbedPage-> TabChild2Page?
Assert.IsType<TabChild2PageViewModel>
			(myTabbedPage.CurrentPage.BindingContext);

//  Let's Tab-Navigate to TabChild3Page
_appInstance.Container.Resolve<TabChild2PageViewModel>()
			.GoToNextTabCommand.Execute("2");

//  Am I in the MyTabbedPage-> TabChild2Page?
Assert.IsType<TabChild3PageViewModel>
			(myTabbedPage.CurrentPage.BindingContext);

 

I’m calling the Commands through my child page’s ViewModel and switching the Selected Child-Tab and then asserting to make sure the myTabbedPage instance has updated accordingly.

Switching between Child-Tabs outside the TabbedPage:

//  Am I inside the DetailPage?
Assert.IsType<DetailPageViewModel>
		    (navigationStack.Last().BindingContext);

// Let's go back to Tabbed Page -> TabChild3Page
_appInstance.Container.Resolve<DetailPageViewModel>()
		    .GoBackToTabChild3PageCommand.Execute();

//  Am I inside the MyTabbedPage?
Assert.IsType<MyTabbedPageViewModel>
		    (navigationStack.Last().BindingContext);

//  Am I in the MyTabbedPage-> TabChild3Page?
Assert.IsType<TabChild3PageViewModel>
		    (myTabbedPage.CurrentPage.BindingContext);

 

Here you can clearly see I’m calling the GoBackToTabChild3PageCommand in an page(DetailPage) which Ihave navigated to after the TabbedPage, and what happens in that command is I’m changing the Selected Child-Tab in the MyTabbedPage and immediately going back to it by exiting the DetailPage. Then I’m coming back to the MyTabbedPage, and the Child-Tab 3 is selected in the TabbedPage.

Here’s where you could take a look at the full test implementation : https://github.com/AdvPrismTabNavigation.xUnitTest

Voila! 😀 UnitTest-ing Done!

Github it if yo lazy!

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

Feel free to grab your copy if you’re too lazy to DIY! 😛

That’s it for today.

Cheers all! 😀 Share the love!

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! 😀