{"id":5463,"date":"2013-06-03T14:51:15","date_gmt":"2013-06-03T18:51:15","guid":{"rendered":"http:\/\/blog.xamarin.com\/?p=5463"},"modified":"2013-06-03T14:51:15","modified_gmt":"2013-06-03T18:51:15","slug":"exploring-android-property-animations","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/exploring-android-property-animations\/","title":{"rendered":"Exploring Android Property Animations"},"content":{"rendered":"<p>\t\t\t\tIn the Xaminar about Android animations that we published earlier this year, we discussed how recent versions of Google&#8217;s mobile platform introduce lots of powerful features for animating user interfaces. In that talk, I mentioned the property animation API, which lets you animate any object property&mdash;including non-graphical properties.<\/p>\n<p>The corresponding class to that API is <code>ValueAnimator<\/code>&mdash;and more precisely, in our case, its subclass <code>ObjectAnimator<\/code>. Both let you construct animations over a range of normal scalar types like float or int for any property. Their true power, however, lies in the fact that they can animate properties of any object type with the right configuration (more on that in the next section).<\/p>\n<p>In addition, an often-overlooked fact is that animation timing behavior is not set in stone. Indeed, each of the animation APIs on Android can optionally take an <code>ITimeInterpolator<\/code> which defines the &#8220;time shape&#8221; of the animations. For instance, the following are the respective time shapes of two of the default interpolators used in the framework, <code>LinearInterpolator<\/code> and <code>AccelerateDecelerateInterpolator<\/code>:<\/p>\n<p><a href=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/linear.png\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/linear-300x197.png\" alt=\"Linear interpolation\" width=\"300\" height=\"197\" class=\"aligncenter size-medium wp-image-5469\" \/><\/a><a href=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/acceleratedecelerate.png\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/acceleratedecelerate-300x197.png\" alt=\"Accelerate\/Decelerate interpolation\" width=\"300\" height=\"197\" class=\"aligncenter size-medium wp-image-5465\" \/><\/a><\/p>\n<p>Creating your own time interpolator is also very easy. You simply have to inplement the <code>ITimeInterpolator<\/code> interface which has only one method: <code>GetInterpolation(float)<\/code>. The argument passed to that method is the current step of the animation, which is a value between <strong>0<\/strong> (the start of your animation) and <strong>1.0<\/strong> (its end). You are generally supposed to return a value in that range too, but adjacent values are also supported and are being translated to an overshoot or an undershoot effect.<\/p>\n<p>Additionaly, the formula you are using to compute your final value can be as complex as you want as long as it doesn&#8217;t impede the rendering loop (remember, for animations to be buttery smooth you want to aim for 60 FPS). For instance, imagining I needed a time interpolator to represent the fall of an object (a typical <a href=\"http:\/\/en.wikipedia.org\/wiki\/Quadratic_equation\">quadratic equation<\/a>), I could do it like this:<\/p>\n<pre class=\"lang:csharp decode:true\">\nclass QuadraticTimeInterpolator : Java.Lang.Object, ITimeInterpolator\n{\n\tpublic float GetInterpolation (float input)\n\t{\n\t\treturn input * input; \/\/ or (float)Math.Pow (input, 2)\n\t}\n}\n<\/pre>\n<p>Which corresponds to the following shape:<\/p>\n<p><a href=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/power2.png\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/power2-300x197.png\" alt=\"Quadratic interpolation\" width=\"300\" height=\"197\" class=\"aligncenter size-medium wp-image-5470\" \/><\/a><\/p>\n<p>So why is this useful?<\/p>\n<p>Although you can generally use the default interpolator (<code>AccelerateDecelerateInterpolator<\/code>), if your animations are supposed to model a real-life phenomenon (like my example of an object falling) then you should strive to find the equation that faithfully reproduces <a href=\"http:\/\/en.wikipedia.org\/wiki\/12_basic_principles_of_animation#Timing\">the physical behavior your users expect<\/a>.<\/p>\n<h3>Practical example<\/h3>\n<p>Let&#8217;s now see a practical example of the two features I mentioned about property animation: <strong>customized time interpolator<\/strong> and <strong>animating over non-scalar values<\/strong>. For our experiment we are going to use <a href=\"https:\/\/developers.google.com\/maps\/documentation\/android\/\">Google Maps v2 API<\/a> and try to add a bit of spice to <code>Marker<\/code> objects&mdash;which, by default, can&#8217;t be animated with the existing API.<\/p>\n<p>The idea is to create a dropping effect for the pin:<\/p>\n<p><video width=\"649\" height=\"366\" preload=\"none\" controls=\"\" poster=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/capture.jpg\"><\/video><\/p>\n<p>This effect can be used to inform the user of the result of his location search, for instance. The iOS Map application uses a similar effect for similar reasons. Since the only property available to animate the pin is its latitude\/longitude coordinates on the map, we will have to determine a pair of geo-points respectively for the starting and ending positions of a vertical movement.<\/p>\n<p>Since the ending position is assumed to be known (i.e. we have the coordinates where the pin should be), we simply have to compute the initial offset of the pin when dropped. With the Google Maps API, you can do these kinds of display\/map conversions using the <code>Projection<\/code> class available on your <code>Map<\/code> object. For instance, computing the starting geocoordinates for our pin will be done like this:<\/p>\n<pre class=\"lang:csharp decode:true\">\n\/\/ finalLatLng is known\nvar proj = mapFragment.Map.Projection;\nvar location = proj.ToScreenLocation (finalLatLng);\n\/\/ We will start 35dp above the final position\nlocation.Offset (0, -(35.ToPixels ()));\nvar startLatLng = proj.FromScreenLocation (location);\n<\/pre>\n<p>We now have two geocoordinates between which we want to animate the pin using its <code>SetPosition(LatLng)<\/code> method. The problem is that, by default, the animation subsystem has no idea what a <code>LatLng<\/code> type is and how to create the intermediate values between our starting and ending points. Fortunately, as I explained in the beginning, we can extend the animation framework to accept any type with a bit of help. This is achieved with a subclass of the <code>ITypeEvaluator<\/code> interface.<\/p>\n<p>The implementation of this interface is very similar in spirit to <code>ITimeInterpolator<\/code>, with a single method to implement which gives you three parameters: the desired intermediate value (represented by a <em>fraction<\/em> value between <strong>0.0f<\/strong> and <strong>1.0f<\/strong>), the start object instance, and the end object instance. Your job as an implementer is to provide a linear interpolation based on the fraction&#8217;s value between those two object states (the axiom being that <em>fraction = 0.0f \u21d4 result = startObject<\/em> and <em>fraction = 1.0f \u21d4 result = endObject<\/em>).<\/p>\n<p>Here is the straightforward implementation of your evaluator for a <code>LatLng<\/code> object:<\/p>\n<pre class=\"lang:csharp decode:true\">\nclass LatLngEvaluator : Java.Lang.Object, ITypeEvaluator\n{\n\tpublic Java.Lang.Object Evaluate (float fraction, Java.Lang.Object startValue, Java.Lang.Object endValue)\n\t{\n\t\tvar start = (LatLng)startValue;\n\t\tvar end = (LatLng)endValue;\n\n\t\treturn new LatLng (start.Latitude + fraction * (end.Latitude - start.Latitude),\n\t\t                   start.Longitude + fraction * (end.Longitude - start.Longitude));\n\t}\n}\n<\/pre>\n<p>The last piece is that we want the pin drop to feel as natural as possible. Instinctively, when you think about an object drop you can picture it accelerating until it reaches the ground and then gently bouncing until all its initial inertia is gone. Fortunately, we don&#8217;t have to model that behavior ourselves because it&#8217;s already available in Android through the well-named <code>BounceInterpolator<\/code> class.<\/p>\n<p>You can <a href=\"https:\/\/github.com\/android\/platform_frameworks_base\/blob\/master\/core\/java\/android\/view\/animation\/BounceInterpolator.java#L38\">take a look<\/a> at the formula implementation if you are interested, but for the sake of the explanation I think the shape is a better illustration of the result:<\/p>\n<p><a href=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/bounce.png\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/bounce-300x197.png\" alt=\"bounce\" width=\"300\" height=\"197\" class=\"aligncenter size-medium wp-image-5466\" \/><\/a><\/p>\n<p>Putting those two pieces together with our <code>ObjectAnimator<\/code> friend, we can now implement the solution very concisely like this:<\/p>\n<pre class=\"lang:csharp decode:true\">\nvar opts = new MarkerOptions () {\n\tPosition = startLatLng,\n\tIcon = BitmapDescriptorFactory.DefaultMarker (BitmapDescriptorFactory.HueViolet)\n};\nvar marker = mapFragment.Map.AddMarker (opts);\n\nvar evaluator = new LatLngEvaluator ();\nObjectAnimator.OfObject (marker, &quot;position&quot;, evaluator, startLatLng, finalLatLng)\n\t.SetDuration (1000)\n\t.SetInterpolator (new Android.Views.Animations.BounceInterpolator ())\n\t.Start ();\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In the Xaminar about Android animations that we published earlier this year, we discussed how recent versions of Google&#8217;s mobile platform introduce lots of powerful features for animating user interfaces. In that talk, I mentioned the property animation API, which lets you animate any object property&mdash;including non-graphical properties. The corresponding class to that API is [&hellip;]<\/p>\n","protected":false},"author":1925,"featured_media":39167,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[4],"class_list":["post-5463","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>In the Xaminar about Android animations that we published earlier this year, we discussed how recent versions of Google&#8217;s mobile platform introduce lots of powerful features for animating user interfaces. In that talk, I mentioned the property animation API, which lets you animate any object property&mdash;including non-graphical properties. The corresponding class to that API is [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/5463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/1925"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=5463"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/5463\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=5463"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=5463"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=5463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}