Today, I am going to show you how to create a Custom Slide entry in Xamarin.Forms with animation and also using gradient color. here is YT URL
Let's get started!
First, we are going to create a demo project and give the name of our choice. Then, we will create a new folder and give it the name "custom view" for customizing control.
Please read the BorderlessEntry blog or article and watch the video, I have mentioned the URL below.
For the article on BorderlessEntry.
Now, we are creating another class with the name gradient color. In this class, we create two getter setter properties - one for start color and another for end color. If you want to see the custom gradient color demo, just click here.
For the article of GradientColor.
Implementation
First, we create a Xamarin.Forms project on Windows machine.
Open Visual Studio 2017. Select File >> Create Project. A dialog window appears.
This is the new project dialog window and here,
- We can select the cross-platform;
- select Mobile App(Xamarin.Forms);
- give the project name as SlidingImageEntry;
- choose the folder path;
- and finally, click OK.
This is another window in which,
- I choose the blank app;
- select the project (Android, iOS, UWP) in which I want to create the app;
- select the Code Sharing Strategy as .NET Standard;
- and finally, click OK to create the project.
Here, let us check if the Xamarin.Forms NuGet Package updated or not. If not, we will update it. Following are the steps for updating the package.
First, we select the solution and right-click on the solution and then select the NuGet package as shown in this below screen.
Now, appears a new window (Nuget - Solution). This window contains the information of packages used in this project. Here, we can select the Update tab. All the packages are listed here. Here, you can search for package Xamarin Forms and then select the particular package and check all the projects (Android and iOS) and install/update your package.
Now, we are creating a sliding entry with custom renderer borderless entry using gradient stack layout, using this combination.
Now here, we create a XAML with the name ImageSlideEntry.axml and below is its design for the side entry layout.
I created a layout in custom view in the content view and then added animation for sliding left and right side with the image showing left side if unfocused and if focuses the entry so the image is showing on the left side.
ImageSlideEntry.xaml
- <?xml version="1.0" encoding="UTF-8"?>
- <ContentView xmlns="http://xamarin.com/schemas/2014/forms"
- xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
- xmlns:local1="clr-namespace:SlideEntryDemo.CustomRendererCore"
- x:Class="SlideEntryDemo.CustomControls.ImageSlideEntry">
- <ContentView.Content>
- <local1:GradientColorStack StartColor="#DF596C" EndColor="#FFB239" >
- <Grid ColumnSpacing="5" Padding="5,1">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="Auto"/>
- <ColumnDefinition Width="*"/>
- <ColumnDefinition Width="Auto"/>
- </Grid.ColumnDefinitions>
- <Image x:Name="MainImg1" Grid.Column="0" Source="icon" WidthRequest="24" HeightRequest="24" Aspect="AspectFit"/>
- <local1:CustomEntry x:Name="MainEntry" Grid.Column="1" Grid.ColumnSpan="2" HeightRequest="36"
- HorizontalOptions="FillAndExpand" BackgroundColor="White" FontSize="Small" VerticalOptions="Center"
- Placeholder="{Binding Placeholder, Mode=TwoWay}"
- Text="{Binding Text, Mode=TwoWay}"
- IsPassword="{Binding IsPassword,Mode=TwoWay}"
- Keyboard="{Binding Keyboard,Mode=TwoWay}"
- PlaceholderColor="{Binding PlaceholderColor,Mode=TwoWay}"
- TextColor="{Binding TextColor,Mode=TwoWay}"/>
- <Image x:Name="MainImg2" Grid.Column="2" Source="icon" WidthRequest="0" HeightRequest="0" Aspect="AspectFit"/>
- </Grid>
- </local1:GradientColorStack>
- </ContentView.Content>
- </ContentView>
Now, we should implement C# code the animation of the image with sliding Entry.
- using System.Threading.Tasks;
- using Xamarin.Forms;
- using Xamarin.Forms.Xaml;
- namespace SlideEntryDemo.CustomControls
- {
- [XamlCompilation(XamlCompilationOptions.Compile)]
- public partial class ImageSlideEntry : ContentView
- {
- public ImageSlideEntry()
- {
- InitializeComponent();
- MainEntry.BindingContext = this;
- MainEntry.Focused += async (s, a) =>
- {
- if (string.IsNullOrEmpty(MainEntry.Text))
- {
- MainImg2.WidthRequest = MainImg2.HeightRequest = 24;
- await Task.WhenAll(
- MainEntry.TranslateTo(MainEntry.TranslationX - 28, 0, 200, Easing.BounceIn),
- MainImg1.ScaleTo(0, 120),
- MainImg1.FadeTo(0, 100),
- MainImg2.ScaleTo(1, 120),
- MainImg2.FadeTo(1, 100)
- );
- }
- };
- MainEntry.Unfocused += async (s, a) =>
- {
- if (string.IsNullOrEmpty(MainEntry.Text))
- {
- await Task.WhenAll(
- MainImg2.ScaleTo(0, 120),
- MainImg2.FadeTo(0, 100),
- MainImg1.FadeTo(1, 100),
- MainImg1.ScaleTo(1, 120),
- MainEntry.TranslateTo(MainEntry.TranslationX + 28, 0, 200, Easing.BounceIn)
- );
- }
- };
- }
- public static readonly BindableProperty IconSourceProperty = BindableProperty.Create(nameof(Icon), typeof(ImageSource), typeof(ImageSlideEntry),
- defaultBindingMode: BindingMode.TwoWay,
- propertyChanged: (bindable, oldVal, newVal) =>
- {
- var matEntry = (ImageSlideEntry)bindable;
- matEntry.MainImg1.Source = (ImageSource)newVal;
- matEntry.MainImg2.Source = (ImageSource)newVal;
- });
- public static BindableProperty TextProperty = BindableProperty.Create(nameof(Text),
- typeof(string),
- typeof(ImageSlideEntry),
- defaultBindingMode: BindingMode.TwoWay);
- public static BindableProperty PlaceholderProperty = BindableProperty.Create(nameof(Placeholder),
- typeof(string),
- typeof(ImageSlideEntry),
- defaultBindingMode: BindingMode.TwoWay);
- public static BindableProperty IsPasswordProperty = BindableProperty.Create(nameof(IsPassword), typeof(bool),
- typeof(ImageSlideEntry), defaultValue: false);
- public static BindableProperty KeyboardProperty = BindableProperty.Create(nameof(Keyboard), typeof(Keyboard), typeof(ImageSlideEntry), defaultValue: Keyboard.Default);
- public static BindableProperty PlaceholderColorProperty = BindableProperty.Create(nameof(PlaceholderColor), typeof(Color), typeof(ImageSlideEntry), defaultValue: Color.Accent);
- public static BindableProperty TextColorProperty = BindableProperty.Create(nameof(TextColor), typeof(Color), typeof(ImageSlideEntry), defaultValue: Color.Accent);
- public static BindableProperty StartColorProperty = BindableProperty.Create(nameof(StartColor), typeof(Color), typeof(ImageSlideEntry), defaultValue: Color.Accent);
- public static BindableProperty EndColorProperty = BindableProperty.Create(nameof(EndColor), typeof(Color), typeof(ImageSlideEntry), defaultValue: Color.Accent);
- public ImageSource Icon
- {
- get => (ImageSource)GetValue(IconSourceProperty);
- set => SetValue(IconSourceProperty, value);
- }
- public Color PlaceholderColor
- {
- get => (Color)GetValue(PlaceholderColorProperty);
- set => SetValue(PlaceholderColorProperty, value);
- }
- public Color TextColor
- {
- get => (Color)GetValue(TextColorProperty);
- set => SetValue(TextColorProperty, value);
- }
- public Keyboard Keyboard
- {
- get => (Keyboard)GetValue(KeyboardProperty);
- set => SetValue(KeyboardProperty, value);
- }
- public bool IsPassword
- {
- get => (bool)GetValue(IsPasswordProperty);
- set => SetValue(IsPasswordProperty, value);
- }
- public string Text
- {
- get => (string)GetValue(TextProperty);
- set => SetValue(TextProperty, value);
- }
- public string Placeholder
- {
- get => (string)GetValue(PlaceholderProperty);
- set => SetValue(PlaceholderProperty, value);
- }
- public Color StartColor
- {
- get => (Color)GetValue(StartColorProperty);
- set => SetValue(StartColorProperty, value);
- }
- public Color EndColor
- {
- get => (Color)GetValue(EndColorProperty);
- set => SetValue(EndColorProperty, value);
- }
- }
- }
Before running this implementation, please make sure the images are put in the drawable (Android) folder and Recourses(iOS) folder.
In the below code, we are using custom sliding entry in my loginpage xaml.
- <ContentPage.Content>
- <StackLayout Padding="30,20,30,0" VerticalOptions="CenterAndExpand">
- <Image Source="icon" Aspect="AspectFit" HeightRequest="70" WidthRequest="70"/>
- <Label Text="Welcome To Xamarin Buddy !" HorizontalOptions="CenterAndExpand" FontSize="Medium" TextColor="#DF596C" FontAttributes="Bold"/>
- <Label Text="Login now and enjoy the pleasures of demo." HorizontalOptions="CenterAndExpand" FontSize="Small" TextColor="#DF596C"/>
- <BoxView HeightRequest="3" WidthRequest="50" BackgroundColor="#DF596C"/>
- <Label Text="Sign In" HorizontalOptions="End" FontSize="Default" TextColor="#DF596C"/>
- <StackLayout Spacing="10">
- <ctrl:ImageSlideEntry Placeholder="Email" Keyboard="Email" PlaceholderColor="Red" TextColor="Navy" Icon="mail" />
- <ctrl:ImageSlideEntry Placeholder="Password" Keyboard="Default" IsPassword="True" PlaceholderColor="Red" TextColor="Navy" Icon="key" />
- <Label Text="Forgot Password?" VerticalTextAlignment="End" HorizontalOptions="Start" FontSize="Micro" TextColor="White"/>
- </StackLayout>
- <StackLayout HorizontalOptions="FillAndExpand" Padding="0,20,0,0">
- <Button x:Name="btnSignIn" Text="Sign In" HorizontalOptions="FillAndExpand"
- BackgroundColor="White" TextColor="Black" BorderColor="#DF596C" BorderRadius="5" BorderWidth="5" CornerRadius="0"/>
- <StackLayout Padding="10" Orientation="Horizontal" Spacing="45" HorizontalOptions="CenterAndExpand">
- <Image x:Name="GLImage" HeightRequest="45" WidthRequest="45"
- Source="googlep" Aspect="AspectFit" HorizontalOptions="StartAndExpand"/>
- <Image x:Name="FBImage" HeightRequest="45" WidthRequest="45"
- Source="facebook" Aspect="AspectFit" HorizontalOptions="CenterAndExpand"/>
- <Image x:Name="TWImage" HeightRequest="45"
- WidthRequest="45" Source="twitter"
- Aspect="AspectFit" HorizontalOptions="EndAndExpand"/>
- </StackLayout>
- <StackLayout Spacing="5" Orientation="Horizontal" HorizontalOptions="End">
- <Label Text="Don't have an account?" VerticalTextAlignment="End" HorizontalOptions="Start" FontSize="Micro" TextColor="White" FontAttributes="Italic"/>
- <Label Text="Sign Up" HorizontalOptions="End" FontSize="Micro" TextColor="Red" FontAttributes="Bold"/>
- </StackLayout>
- </StackLayout>
- </StackLayout>
- </ContentPage.Content>
Ta-da!!
That’s it. Now, our Sliding Image Entry is ready to use. Happy Coding ☺