Saturday, 18 November 2017

Xamarin.Forms Custom Entry With Image and Password

Hello Xamarin Friends,
Today, I am going to create a custom ImageEntry. Whenever we are creating a login page, we can not understand which control we have to use for the username and password. I am creating a custom control today to solve this problem. We don't need to write more code with its use and page design will also looks good.
So let's start.

Firstly we create a ContentView and set the image and entry. 
<ContentView.Content>
<StackLayout Spacing="2">
<StackLayout Orientation="Horizontal" Spacing="0">
<local:CustomImage x:Name="LIcon" Source="{Binding LImageSource,Mode=TwoWay}" IsVisible="False"
HorizontalOptions="Start" HeightRequest="25" WidthRequest="25"/>
<local:MyEntry x:Name="imgEntry" PlaceholderColor="Red" Text="{Binding Text, Mode=TwoWay}"
HorizontalOptions="FillAndExpand"/>
<local:CustomImage x:Name="RIcon" Source="{Binding RImageSourceProperty,Mode=TwoWay}" IsVisible="False"
HorizontalOptions="End" HeightRequest="25" WidthRequest="25"/>
</StackLayout>
<BoxView x:Name="BottomBorder" BackgroundColor="Gray" HeightRequest="1" Margin="0" HorizontalOptions="FillAndExpand"/>
<BoxView x:Name="HiddenBottomBorder" BackgroundColor="Gray" HeightRequest="5" Margin="0" WidthRequest="0" HorizontalOptions="Center"/>
</StackLayout>
</ContentView.Content>
then we are using the  BindableProperty to create this custom control.
public partial class ImageEntry : ContentView
{
public static BindableProperty TextProperty =
BindableProperty.Create(nameof(Text),typeof(string),
typeof(ImageEntry),defaultBindingMode: BindingMode.TwoWay);
public static BindableProperty PlaceholderProperty =
BindableProperty.Create(nameof(Placeholder),
typeof(string), typeof(ImageEntry),
defaultBindingMode: BindingMode.TwoWay,
propertyChanged: (bindable, oldVal, newval) =>
{
var matEntry = (ImageEntry)bindable;
matEntry.imgEntry.Placeholder = (string)newval;
});
public static BindableProperty IsPasswordProperty =
BindableProperty.Create(nameof(IsPassword),typeof(bool),
typeof(ImageEntry),defaultValue: false,
propertyChanged: (bindable, oldVal, newVal) =>
{
var matEntry = (ImageEntry)bindable;
matEntry.imgEntry.IsPassword = (bool)newVal;
});
public static BindableProperty KeyboardProperty =
BindableProperty.Create(nameof(Keyboard),typeof(Keyboard),
typeof(ImageEntry),defaultValue: Keyboard.Default,
propertyChanged: (bindable, oldVal, newVal) =>
{
var matEntry = (ImageEntry)bindable;
matEntry.imgEntry.Keyboard = (Keyboard)newVal;
});
public static BindableProperty AccentColorProperty =
BindableProperty.Create(nameof(AccentColor),typeof(Color),
typeof(ImageEntry),defaultValue: Color.Accent);
public static readonly BindableProperty LImageSourceProperty =
BindableProperty.Create(nameof(LImageSource),typeof(ImageSource),
typeof(ImageEntry),defaultBindingMode: BindingMode.TwoWay,
propertyChanged: (bindable, oldVal, newVal) =>
{
var matEntry = (ImageEntry)bindable;
matEntry.LIcon.Source = (ImageSource)newVal;
});
public static readonly BindableProperty RImageSourceProperty =
BindableProperty.Create(nameof(RImageSource),typeof(ImageSource),
typeof(ImageEntry),defaultBindingMode: BindingMode.TwoWay,
propertyChanged: (bindable, oldVal, newVal) =>
{
var matEntry = (ImageEntry)bindable;
matEntry.RIcon.Source = (ImageSource)newVal;
});
public static readonly BindableProperty ImageAlignmentProperty =
BindableProperty.Create(nameof(ImageAlignment),
typeof(eImageAlignment),typeof(ImageEntry),
defaultValue: eImageAlignment.None,propertyChanged: OnImageAlignmentChanged);
public ImageSource RImageSource
{
get { return (ImageSource)GetValue(RImageSourceProperty); }
set { SetValue(RImageSourceProperty, value); }
}
public ImageSource LImageSource
{
get { return (ImageSource)GetValue(LImageSourceProperty); }
set { SetValue(LImageSourceProperty, value); }
}
public Color AccentColor
{
get{return (Color)GetValue(AccentColorProperty);}
set{SetValue(AccentColorProperty, value);}
}
public Keyboard Keyboard
{
get{return (Keyboard)GetValue(KeyboardProperty);}
set{SetValue(KeyboardProperty, value);}
}
public bool IsPassword
{
get{return (bool)GetValue(IsPasswordProperty);}
set{SetValue(IsPasswordProperty, value);}
}
public string Text
{
get{return (string)GetValue(TextProperty);}
set{SetValue(TextProperty, value);}
}
public string Placeholder
{
get{return (string)GetValue(PlaceholderProperty);}
set{SetValue(PlaceholderProperty, value);}
}
public eImageAlignment ImageAlignment
{
get => (eImageAlignment)GetValue(ImageAlignmentProperty);
set => SetValue(ImageAlignmentProperty, value);
}
public event EventHandler LeftImageClicked;
public virtual void LeftImageOn_Clicked(object sender, EventArgs e)
{
LeftImageClicked?.Invoke(sender, e);
}
public event EventHandler RightImageClicked;
public virtual void RightImageOn_Clicked(object sender, EventArgs e)
{
RightImageClicked?.Invoke(sender, e);
}
public ImageEntry()
{
InitializeComponent();
imgEntry.BindingContext = this;
RIcon.ImageClicked += RightImageOn_Clicked;
LIcon.ImageClicked += LeftImageOn_Clicked;
imgEntry.Focused += async (s, a) =>
{
BottomBorder.HeightRequest = 2.5;
BottomBorder.BackgroundColor = AccentColor;
HiddenBottomBorder.BackgroundColor = AccentColor;
if (string.IsNullOrEmpty(imgEntry.Text))
{
await Task.WhenAll(
HiddenBottomBorder.LayoutTo(new Rectangle(BottomBorder.X, BottomBorder.Y, BottomBorder.Width, BottomBorder.Height), 200));
imgEntry.Placeholder = null;
}
else
{
await HiddenBottomBorder.LayoutTo(new Rectangle(BottomBorder.X, BottomBorder.Y, BottomBorder.Width, BottomBorder.Height), 200);
}
};
imgEntry.Unfocused += async (s, a) =>
{
BottomBorder.HeightRequest = 1;
BottomBorder.BackgroundColor = Color.Gray;
if (string.IsNullOrEmpty(imgEntry.Text))
{
await Task.WhenAll(
HiddenBottomBorder.LayoutTo(new Rectangle(BottomBorder.X, BottomBorder.Y, 0, BottomBorder.Height), 200));
imgEntry.Placeholder = Placeholder;
}
else
{
await HiddenBottomBorder.LayoutTo(new Rectangle(BottomBorder.X, BottomBorder.Y, 0, BottomBorder.Height), 200);
}
};
}
private static void OnImageAlignmentChanged(BindableObject bindable, object oldvalue, object newvalue)
{
var control = bindable as ImageEntry;
switch (control.ImageAlignment)
{
case eImageAlignment.None:
control.LIcon.IsVisible = false;
control.RIcon.IsVisible = false;
break;
case eImageAlignment.Left:
control.LIcon.IsVisible = true;
control.RIcon.IsVisible = false;
break;
case eImageAlignment.Right:
control.LIcon.IsVisible = false;
control.RIcon.IsVisible = true;
break;
case eImageAlignment.Password:
control.LIcon.IsVisible = true;
control.RIcon.IsVisible = true;
break;
}
}
public enum eImageAlignment
{
Left,
Right,
Password,
None
}
Please make sure to add view reference.....
xmlns:controls="clr-namespace:CustomImageEntry.CustomControls"
<StackLayout Padding="10">
<controls:ImageEntry Text="Left Image" Placeholder="Xamarin Skills" AccentColor="Red"
ImageAlignment="Left" LImageSource="email"/>
<controls:ImageEntry Text="Right Image" Placeholder="Xamarin Skills"
AccentColor="Green" ImageAlignment="Right" RImageSource="user"/>
<controls:ImageEntry Text="Both Side Image" AccentColor="Yellow" LImageSource="email"
RImageSource="eyeshow" ImageAlignment="Password" />
<controls:ImageEntry Placeholder="Xamarin Skills" Text="None Image" AccentColor="Black" LImageSource="email"
RImageSource="eyeshow" ImageAlignment="None" />
<controls:ImageEntry Placeholder="Xamarin Skills" Text="Left Image Entry Clicked" AccentColor="White"
LImageSource="email" RImageSource="eyeshow" ImageAlignment="Password"
LeftImageClicked="ImageEntry_LeftImageClicked" />
<controls:ImageEntry Placeholder="Xamarin Skills" Text="Right Image Entry Clicked" AccentColor="Blue"
LImageSource="email" RImageSource="eyeshow" ImageAlignment="Password"
RightImageClicked="ImageEntry_RightImageClicked"/>
<controls:ImageEntry Placeholder="Xamarin Skills" Text="Left and Right Image Entry Clicked" AccentColor="BlueViolet"
LImageSource="email" RImageSource="eyeshow" ImageAlignment="Password"
LeftImageClicked="ImageEntry_LeftImageClicked_1" RightImageClicked="ImageEntry_RightImageClicked_1"/>
<Entry x:Name="DefaultEntry" Placeholder="Default Entry"/>
</StackLayout>
</ContentPage>
view raw MainPage.xaml hosted with ❤ by GitHub
 
TADAA!,

I have not yet told about the Borderless entry and CustomImage in this blog that I will tell in the next post.

All this  my original code.


Features of Image Entry controls:-
  1. Accent Color = ( AccentColor="BlueViolet")
  2. Text Property = (Text="Xamarin Skills")
  3. Keyboard Property = (Keyboard="Default")
  4. Placeholder Property = (Placeholder="Xamarin Skills")
  5. IsPassword Property = (IsPassword="False")
  6. Left ImageSource Property = (LImageSource="email")
  7. Right ImageSource Property = (RImageSource="eyeshow")
  8. ImageEntry RightImage = Clicked Property(RightImageClicked="ImageEntry_RightImageClicked")
  9. ImageEntry LeftImage Clicked Property = (LeftImageClicked="ImageEntry_LeftImageClicked")
  10. ImageAlignment Property = (ImageAlignment="Password")


You want to full source code Click Here
If you want to watch this video Click Here

Tuesday, 7 November 2017

Xamarin.Forms Animation With Triggers

Hi All,

In this post I have created  an example of animation with triggers, This time we are talking about the triggers.



Xamarin Forms have a powerful class  named Trigger.  I want to show you stacklayout flipping with animation which I have created with Trigger.

Firstly we create a folder whose name is Triggers,  then create a class with name SwitchLayout.
Then write this code......
public class SwitchLayout : TriggerAction<Button>
{
public enum AnimationDirection
{ Left, Right }
protected override async void Invoke(Button sender)
{
View Viewhide = null;
View Viewshow = null;
if (TargetElement != null)
{
// This is For Finding TargetView
Viewshow = ((View)sender.Parent.Parent).FindByName<View>(TargetElement);
if (Viewshow != null)
{
// This is For Finding SourceView
if (SourceElement != null)
{
Viewhide = ((View)sender.Parent.Parent).FindByName<View>(SourceElement);
if (Viewhide != null)
{
await PerformAnimation(Viewhide, Viewshow);
}
}
}
}
}
public string SourceElement { get; set; }
public string TargetElement { get; set; }
public AnimationDirection Direction { get; set; }
private async Task PerformAnimation(View ViewElementHide, View ViewElementShow)
{
int hideStart = 0;
int hideStop = 0;//if you want to use another rotate animation So you Comment Out and remove 0//(Direction == AnimationDirection.Left ? -90 : 90);
int showStart = 0;//if you want to use another rotate animation So you Comment Out and remove 0//(Direction == AnimationDirection.Left ? 90 : 270);
int showStop = 0;//if you want to use another rotate animation So you Comment Out and remove 0//(Direction == AnimationDirection.Left ? 0 : 360);
await ViewElementHide.RotateYTo(hideStart, 0);
await ViewElementShow.RotateYTo(showStart, 0);
await ViewElementShow.ScaleTo(0.2, 0);
ViewElementShow.IsVisible = true; // This is rotated at 90 or 270 degrees
// Animate
ViewElementHide.FadeTo(0.5, 100, Easing.SinOut);
ViewElementHide.ScaleTo(0.2, 100, Easing.Linear);
await ViewElementHide.RotateYTo(hideStop, 150, Easing.Linear);
ViewElementShow.FadeTo(1, 100, Easing.SinIn);
ViewElementShow.ScaleTo(1, 150, Easing.Linear);
await ViewElementShow.RotateYTo(showStop, 150, Easing.Linear);
ViewElementHide.IsVisible = false;
}
}
view raw SwitchLayout.cs hosted with ❤ by GitHub


Here is the  XAML code......

You need  to add the reference like this.
xmlns:triggers="clr-namespace:FlipAnimation.Triggers"
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Opacity="1"
Source="icon.png"
Aspect="AspectFill"/>
<Grid>
<Grid.Padding>
<OnPlatform x:TypeArguments="Thickness">
<OnPlatform.iOS>
0, 20, 0, 0
</OnPlatform.iOS>
<OnPlatform.Android>
0, 0, 0, 0
</OnPlatform.Android>
</OnPlatform>
</Grid.Padding>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout Grid.Row="0">
<Label Text="Login"
TextColor="White"
HorizontalTextAlignment="Center" />
</StackLayout>
<StackLayout Grid.Row="1">
<!--If you want to use Loader and Error Message so you can comment out this-->
<!--<ActivityIndicator x:Name="actInd" IsRunning="False" IsVisible="False" Color="Blue" />
<Label x:Name="lblBusyMsg" IsVisible="False" Text="My Message" >
<Label.Font>
<OnPlatform x:TypeArguments="Font">
<OnPlatform.iOS>Small</OnPlatform.iOS>
</OnPlatform>
</Label.Font>
</Label>
<Label x:Name="labelErrorMessage" IsVisible="False" Text="MY Message" TextColor="Red">
<Label.Font>
<OnPlatform x:TypeArguments="Font">
<OnPlatform.iOS>Small</OnPlatform.iOS>
</OnPlatform>
</Label.Font>
</Label>-->
</StackLayout>
<StackLayout x:Name="stLog"
Grid.Row="1" Grid.Column="0"
IsVisible="True"
Padding="20,20,20,20"
>
<Entry Placeholder="Email" Text="" />
<Entry Placeholder="Password" Text=""
IsPassword="True" />
<Button Text="Login" Clicked="Login_Clicked" />
<Button Text="Register" >
<Button.Triggers>
<EventTrigger Event="Clicked">
<triggers:SwitchLayout SourceElement="stLog" TargetElement="stReg" Direction="Right" />
</EventTrigger>
</Button.Triggers>
</Button>
<Button Text="Forgot Password">
<Button.Triggers>
<EventTrigger Event="Clicked">
<triggers:SwitchLayout SourceElement="stLog" TargetElement="stForgotPass" Direction="Right" />
</EventTrigger>
</Button.Triggers>
</Button>
<Button Text="Change Password">
<Button.Triggers>
<EventTrigger Event="Clicked">
<triggers:SwitchLayout SourceElement="stLog" TargetElement="stChangePass" Direction="Right" />
</EventTrigger>
</Button.Triggers>
</Button>
</StackLayout>
<StackLayout x:Name="stReg" Grid.Row="1" Grid.Column="0" IsVisible="False" Padding="20" >
<Entry Placeholder="Email" Text="" />
<Entry Placeholder="First name" Text="" />
<Entry Placeholder="Last name" Text="" />
<Button Text="Register" Clicked="Register_Clicked" />
<Button Text="Cancel">
<Button.Triggers>
<EventTrigger Event="Clicked">
<triggers:SwitchLayout SourceElement="stReg" TargetElement="stLog" Direction="Left" />
</EventTrigger>
</Button.Triggers>
</Button>
</StackLayout>
<StackLayout x:Name="stForgotPass" Grid.Row="1" Grid.Column="0" IsVisible="False" Padding="20" >
<Entry Placeholder="Email"
Text="" />
<Button Text="Send email" Clicked="ForgetPass_Clicked"/>
<Button Text="Cancel">
<Button.Triggers>
<EventTrigger Event="Clicked">
<triggers:SwitchLayout SourceElement="stForgotPass" TargetElement="stLog" Direction="Left" />
</EventTrigger>
</Button.Triggers>
</Button>
</StackLayout>
<StackLayout x:Name="stChangePass" Grid.Row="1" Grid.Column="0" IsVisible="False" Padding="20" >
<Entry Placeholder="Old password"
IsPassword="True" />
<Entry Placeholder="New password" IsPassword="True" />
<Entry Placeholder="Confirm password" IsPassword="True" />
<Button Text="OK" Clicked="ChangePass_Clicked"/>
<Button Text="Cancel">
<Button.Triggers>
<EventTrigger Event="Clicked">
<triggers:SwitchLayout SourceElement="stChangePass" TargetElement="stLog" Direction="Left" />
</EventTrigger>
</Button.Triggers>
</Button>
</StackLayout>
</Grid>
</Grid>
</ContentPage.Content>

if you want watch this demo video click here
TADDA !


you want to full source code click Here
If you want to watch this video Click Here

Featured Post

Sliding Entry In Xamarin.Forms

  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 Y...