Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin.Forms Animation on click Button (Flash background)

Tags:

I want to implement a dialpad on my form. Now, in my XAML I am testing a button: XAML

<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms"           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"           x:Class="MyXFDemo001.Views.NewItemPage"          Title="New Item"> <ContentPage.ToolbarItems>     <ToolbarItem Text="Save" Clicked="Save_Clicked" /> </ContentPage.ToolbarItems> <ContentPage.Content>     <StackLayout Spacing="20" Padding="15">         <Button             x:Name="buttonSelectContact"             Clicked="buttonSelectContact_Clicked"             Text="CLICK" BackgroundColor="#0080ff" />     </StackLayout> </ContentPage.Content> 

And in my code behind I have a method buttonSelectContact_Clicked:

private async void buttonSelectContact_Clicked(object sender, EventArgs e) {     Button btn = (Button)sender;     btn.BackgroundColor = Color.FromHex("#22ac38");     await Task.Delay(500);     btn.BackgroundColor = Color.FromHex("#0080ff"); } 

It works, but not quietly as smooth as I want. Can you suggest me to add animation instead of this BackgroundColor?

like image 713
Stefan0309 Avatar asked May 16 '18 09:05

Stefan0309


1 Answers

I guess the better choice is to create a reusable feature to do that. You may take advantage of the animation resources from xamarin.forms.

For example, you can create an extension method that provides you a nice and easy way to reuse anywhere, like FadeTo or TranslateTo...

It is pretty easy, except for the logic that smoothly changes the color in this particular case. Here is the code:

public static class AnimationExtensions {     public static Task<bool> ChangeBackgroundColorTo(this Button self, Color newColor, uint length = 250, Easing easing = null)     {         Task<bool> ret = new Task<bool>(() => false);          if (!self.AnimationIsRunning(nameof(ChangeBackgroundColorTo)))         {             Color fromColor = self.BackgroundColor;              try             {                 Func<double, Color> transform = (t) =>                   Color.FromRgba(fromColor.R + t * (newColor.R - fromColor.R),                                  fromColor.G + t * (newColor.G - fromColor.G),                                  fromColor.B + t * (newColor.B - fromColor.B),                                  fromColor.A + t * (newColor.A - fromColor.A));                  ret = TransmuteColorAnimation(self, nameof(ChangeBackgroundColorTo), transform, length, easing);             }             catch (Exception ex)             {                 // to supress animation overlapping errors                  self.BackgroundColor = fromColor;             }         }          return ret;     }      private static Task<bool> TransmuteColorAnimation(Button button, string name, Func<double, Color> transform, uint length, Easing easing)     {         easing = easing ?? Easing.Linear;         var taskCompletionSource = new TaskCompletionSource<bool>();          button.Animate(name, transform, (color) => { button.BackgroundColor = color; }, 16, length, easing, (v, c) => taskCompletionSource.SetResult(c));         return taskCompletionSource.Task;     } } 

Importing this class (by the using namespace reference) you will be able to use it like bellow.

Declaring an XAML button:

<Button Text="Nice button ;)"         BackgroundColor="Gray"         x:Name="btnTeste"         Clicked="btnTest_Click"/> 

Handling click in the code-behind:

private async void btnTest_Click(object sender, EventArgs args) {     #region You will not need this block, it is just to choose a random color for change to     var colors = new[] { Color.Red, Color.Pink, Color.Silver, Color.Yellow, Color.Black, Color.Green };     var rnd = new Random();      var actualColor = btnTeste.BackgroundColor;     var randomColor = colors.Where(c => c != actualColor).ToArray()[rnd.Next(0, colors.Length - 2)];     #endregion      // Here is the effective use of the smooth background color change animation     await btnTeste.ChangeBackgroundColorTo(randomColor, 150, Easing.CubicOut);     await btnTeste.ChangeBackgroundColorTo(actualColor, 100, Easing.SinOut); } 

EDIT:

Here is the result (the gif shows clicks and double-clicks, so you can see a lot of smoothy changes):

effect example

like image 153
GKMoreira Avatar answered Sep 28 '22 04:09

GKMoreira