<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Yet Another [à compléter]]]></title>
  <link href="http://blog.neteril.org/atom.xml" rel="self"/>
  <link href="http://blog.neteril.org/"/>
  <updated>2015-09-22T23:39:01-04:00</updated>
  <id>http://blog.neteril.org/</id>
  <author>
    <name><![CDATA[Jérémie Laval]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Custom Interactions with the Design Support Library]]></title>
    <link href="http://blog.neteril.org/blog/2015/07/12/custom-interactions-with-the-design-support-library/"/>
    <updated>2015-07-12T18:32:21-04:00</updated>
    <id>http://blog.neteril.org/blog/2015/07/12/custom-interactions-with-the-design-support-library</id>
    <content type="html"><![CDATA[<p>During this year Google I/O, a new entry in the support library family was added <a href="http://android-developers.blogspot.com/2015/05/android-design-support-library.html">in the form of support-design</a>.</p>

<p>The goal of this new library is to brige the gap between the theory of the <a href="http://www.google.com/design/spec/material-design/introduction.html">Material Design specification</a> and having actual 	available code to implement it.</p>

<p>The new library sits on top of the existing support-v7-appcompat package (which provides the base Material theming ability) and offers a bunch of new UI components and interactions from the specification.</p>

<p>Today I want to focus on two of those new elements that we will be using together: the infamous FAB (Floating Action Button) and <code>CoordinatorLayout</code>.</p>

<h3 id="the-fab-strikes-back">The FAB strikes back</h3>

<p><img src="http://blog.neteril.org/wp-content/uploads/support-design/materialdesign_principles_bold.png" height="180" width="180" class="center" /></p>

<p>If I had to pick one of the most iconic aspect of material design it would be the floating action button (henceforth known as FAB). It’s actually deemed important enough that the specification was expanded recently to have <a href="http://www.google.com/design/spec/components/buttons-floating-action-button.html">a dedicated section for it</a>.</p>

<p>FAB are circular buttons containing a single icon (usually white or black) with a bright background (the color accent of your app for instance) and generally elevated above content (thus casting a shadow).</p>

<p>These FABs showcase the main actions that your app has to offer. As such, they are ones of the most important part of your UI and you should always pay special attention to get their interactions right.</p>

<p>Because FABs are so proeminent visually, they also offer a good opportunity to add pleasant touches to your app. In the word of the specification: “Take advantage of [FAB’s] visibility to create delightful transitions for a primary UI element.”</p>

<p>The support design library offers a default implementation of that UI widget that’s backward compatible with older versions of Android that don’t have elevation/shadow support or round clipping in the form of the <a href="http://developer.android.com/reference/android/support/design/widget/FloatingActionButton.html">FloatingActionButton</a> widget which is a subclass of the classic <code>ImageView</code>.</p>

<p>Here I want to focus on one of the documented FAB transition: morphing. This transition is used to alternate between two main actions for a single FAB depending on the context:</p>

<video width="512" height="304" controls="" loop=""><source src="http://blog.neteril.org/wp-content/uploads/support-design/fab.mp4" type="video/mp4" /></video>

<p>To implement this, you can create a simple subclass of the default FAB that let you also specify a secondary set of icon and background and then create a custom animation to alternate between the two:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
<span class="line-number">34</span>
<span class="line-number">35</span>
<span class="line-number">36</span>
<span class="line-number">37</span>
<span class="line-number">38</span>
<span class="line-number">39</span>
<span class="line-number">40</span>
<span class="line-number">41</span>
<span class="line-number">42</span>
<span class="line-number">43</span>
<span class="line-number">44</span>
<span class="line-number">45</span>
<span class="line-number">46</span>
<span class="line-number">47</span>
<span class="line-number">48</span>
<span class="line-number">49</span>
<span class="line-number">50</span>
<span class="line-number">51</span>
<span class="line-number">52</span>
<span class="line-number">53</span>
<span class="line-number">54</span>
<span class="line-number">55</span>
<span class="line-number">56</span>
<span class="line-number">57</span>
<span class="line-number">58</span>
<span class="line-number">59</span>
<span class="line-number">60</span>
<span class="line-number">61</span>
<span class="line-number">62</span>
<span class="line-number">63</span>
<span class="line-number">64</span>
<span class="line-number">65</span>
<span class="line-number">66</span>
<span class="line-number">67</span>
<span class="line-number">68</span>
<span class="line-number">69</span>
<span class="line-number">70</span>
<span class="line-number">71</span>
<span class="line-number">72</span>
<span class="line-number">73</span>
<span class="line-number">74</span>
<span class="line-number">75</span>
<span class="line-number">76</span>
<span class="line-number">77</span>
<span class="line-number">78</span>
<span class="line-number">79</span>
<span class="line-number">80</span>
<span class="line-number">81</span>
<span class="line-number">82</span>
<span class="line-number">83</span>
<span class="line-number">84</span>
<span class="line-number">85</span>
<span class="line-number">86</span>
<span class="line-number">87</span>
<span class="line-number">88</span>
<span class="line-number">89</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="k">public</span> <span class="k">class</span> <span class="nc">SwitchableFab</span> <span class="p">:</span> <span class="n">FloatingActionButton</span>
</span><span class="line"><span class="p">{</span>
</span><span class="line">	<span class="n">AnimatorSet</span> <span class="n">switchAnimation</span><span class="p">;</span>
</span><span class="line">	<span class="kt">bool</span> <span class="n">state</span><span class="p">;</span>
</span><span class="line">	<span class="n">Drawable</span> <span class="n">srcFirst</span><span class="p">,</span> <span class="n">srcSecond</span><span class="p">;</span>
</span><span class="line">	<span class="n">ColorStateList</span> <span class="n">backgroundTintFirst</span><span class="p">,</span> <span class="n">backgroundTintSecond</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">	<span class="c1">// ctors.</span>
</span><span class="line">
</span><span class="line">	<span class="k">void</span> <span class="nf">Initialize</span> <span class="p">(</span><span class="n">Context</span> <span class="n">context</span><span class="p">,</span> <span class="n">IAttributeSet</span> <span class="n">attrs</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="n">srcFirst</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">Drawable</span><span class="p">;</span>
</span><span class="line">		<span class="n">backgroundTintFirst</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">BackgroundTintList</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="k">if</span> <span class="p">(</span><span class="n">attrs</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
</span><span class="line">			<span class="k">return</span><span class="p">;</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">array</span> <span class="p">=</span> <span class="n">context</span><span class="p">.</span><span class="n">ObtainStyledAttributes</span> <span class="p">(</span><span class="n">attrs</span><span class="p">,</span> <span class="n">Resource</span><span class="p">.</span><span class="n">Styleable</span><span class="p">.</span><span class="n">SwitchableFab</span><span class="p">);</span>
</span><span class="line">		<span class="n">srcSecond</span> <span class="p">=</span> <span class="n">array</span><span class="p">.</span><span class="n">GetDrawable</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Styleable</span><span class="p">.</span><span class="n">SwitchableFab_srcSecond</span><span class="p">);</span>
</span><span class="line">		<span class="n">backgroundTintSecond</span> <span class="p">=</span> <span class="n">array</span><span class="p">.</span><span class="n">GetColorStateList</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Styleable</span><span class="p">.</span><span class="n">SwitchableFab_backgroundTintSecond</span><span class="p">);</span>
</span><span class="line">		<span class="n">array</span><span class="p">.</span><span class="n">Recycle</span> <span class="p">();</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="k">void</span> <span class="nf">Switch</span> <span class="p">()</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="k">if</span> <span class="p">(</span><span class="n">state</span><span class="p">)</span>
</span><span class="line">			<span class="n">Switch</span> <span class="p">(</span><span class="n">srcFirst</span><span class="p">,</span> <span class="n">backgroundTintFirst</span><span class="p">);</span>
</span><span class="line">		<span class="k">else</span>
</span><span class="line">			<span class="nf">Switch</span> <span class="p">(</span><span class="n">srcSecond</span><span class="p">,</span> <span class="n">backgroundTintSecond</span><span class="p">);</span>
</span><span class="line">		<span class="n">state</span> <span class="p">=</span> <span class="p">!</span><span class="n">state</span><span class="p">;</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">void</span> <span class="nf">Switch</span> <span class="p">(</span><span class="n">Drawable</span> <span class="n">src</span><span class="p">,</span> <span class="n">ColorStateList</span> <span class="n">tint</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="k">const</span> <span class="kt">int</span> <span class="n">ScaleDuration</span> <span class="p">=</span> <span class="m">200</span><span class="p">;</span>
</span><span class="line">		<span class="k">const</span> <span class="kt">int</span> <span class="n">AlphaDuration</span> <span class="p">=</span> <span class="m">150</span><span class="p">;</span>
</span><span class="line">		<span class="k">const</span> <span class="kt">int</span> <span class="n">AlphaInDelay</span> <span class="p">=</span> <span class="m">50</span><span class="p">;</span>
</span><span class="line">		<span class="k">const</span> <span class="kt">int</span> <span class="n">InitialDelay</span> <span class="p">=</span> <span class="m">100</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="k">if</span> <span class="p">(</span><span class="n">switchAnimation</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">			<span class="n">switchAnimation</span><span class="p">.</span><span class="n">Cancel</span> <span class="p">();</span>
</span><span class="line">			<span class="n">switchAnimation</span> <span class="p">=</span> <span class="k">null</span><span class="p">;</span>
</span><span class="line">		<span class="p">}</span>
</span><span class="line">
</span><span class="line">		<span class="kt">var</span> <span class="n">currentSrc</span> <span class="p">=</span> <span class="k">this</span><span class="p">.</span><span class="n">Drawable</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="c1">// Scaling down animation</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">circleAnimOutX</span> <span class="p">=</span> <span class="n">ObjectAnimator</span><span class="p">.</span><span class="n">OfFloat</span> <span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s">&quot;scaleX&quot;</span><span class="p">,</span> <span class="m">1</span><span class="p">,</span> <span class="m">0.1f</span><span class="p">);</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">circleAnimOutY</span> <span class="p">=</span> <span class="n">ObjectAnimator</span><span class="p">.</span><span class="n">OfFloat</span> <span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s">&quot;scaleY&quot;</span><span class="p">,</span> <span class="m">1</span><span class="p">,</span> <span class="m">0.1f</span><span class="p">);</span>
</span><span class="line">		<span class="n">circleAnimOutX</span><span class="p">.</span><span class="n">SetDuration</span> <span class="p">(</span><span class="n">ScaleDuration</span><span class="p">);</span>
</span><span class="line">		<span class="n">circleAnimOutY</span><span class="p">.</span><span class="n">SetDuration</span> <span class="p">(</span><span class="n">ScaleDuration</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">		<span class="c1">// Alpha out of the icon</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">iconAnimOut</span> <span class="p">=</span> <span class="n">ObjectAnimator</span><span class="p">.</span><span class="n">OfInt</span> <span class="p">(</span><span class="n">currentSrc</span><span class="p">,</span> <span class="s">&quot;alpha&quot;</span><span class="p">,</span> <span class="m">255</span><span class="p">,</span> <span class="m">0</span><span class="p">);</span>
</span><span class="line">		<span class="n">iconAnimOut</span><span class="p">.</span><span class="n">SetDuration</span> <span class="p">(</span><span class="n">AlphaDuration</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">		<span class="kt">var</span> <span class="n">outSet</span> <span class="p">=</span> <span class="k">new</span> <span class="n">AnimatorSet</span> <span class="p">();</span>
</span><span class="line">		<span class="n">outSet</span><span class="p">.</span><span class="n">PlayTogether</span> <span class="p">(</span><span class="n">circleAnimOutX</span><span class="p">,</span> <span class="n">circleAnimOutY</span><span class="p">,</span> <span class="n">iconAnimOut</span><span class="p">);</span>
</span><span class="line">		<span class="n">outSet</span><span class="p">.</span><span class="n">SetInterpolator</span> <span class="p">(</span><span class="n">AnimationUtils</span><span class="p">.</span><span class="n">LoadInterpolator</span> <span class="p">(</span><span class="n">Context</span><span class="p">,</span>
</span><span class="line">		                                                         <span class="n">Android</span><span class="p">.</span><span class="n">Resource</span><span class="p">.</span><span class="n">Animation</span><span class="p">.</span><span class="n">AccelerateInterpolator</span><span class="p">));</span>
</span><span class="line">		<span class="n">outSet</span><span class="p">.</span><span class="n">StartDelay</span> <span class="p">=</span> <span class="n">InitialDelay</span><span class="p">;</span>
</span><span class="line">		<span class="n">outSet</span><span class="p">.</span><span class="n">AnimationEnd</span> <span class="p">+=</span> <span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span><span class="line">			<span class="n">BackgroundTintList</span> <span class="p">=</span> <span class="n">tint</span><span class="p">;</span>
</span><span class="line">			<span class="n">SetImageDrawable</span> <span class="p">(</span><span class="n">src</span><span class="p">);</span>
</span><span class="line">			<span class="n">JumpDrawablesToCurrentState</span> <span class="p">();</span>
</span><span class="line">			<span class="p">((</span><span class="n">Animator</span><span class="p">)</span><span class="n">sender</span><span class="p">).</span><span class="n">RemoveAllListeners</span> <span class="p">();</span>
</span><span class="line">		<span class="p">};</span>
</span><span class="line">
</span><span class="line">		<span class="c1">// Scaling up animation</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">circleAnimInX</span> <span class="p">=</span> <span class="n">ObjectAnimator</span><span class="p">.</span><span class="n">OfFloat</span> <span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s">&quot;scaleX&quot;</span><span class="p">,</span> <span class="m">0.1f</span><span class="p">,</span> <span class="m">1</span><span class="p">);</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">circleAnimInY</span> <span class="p">=</span> <span class="n">ObjectAnimator</span><span class="p">.</span><span class="n">OfFloat</span> <span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s">&quot;scaleY&quot;</span><span class="p">,</span> <span class="m">0.1f</span><span class="p">,</span> <span class="m">1</span><span class="p">);</span>
</span><span class="line">		<span class="n">circleAnimInX</span><span class="p">.</span><span class="n">SetDuration</span> <span class="p">(</span><span class="n">ScaleDuration</span><span class="p">);</span>
</span><span class="line">		<span class="n">circleAnimInY</span><span class="p">.</span><span class="n">SetDuration</span> <span class="p">(</span><span class="n">ScaleDuration</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">		<span class="c1">// Alpha in of the icon</span>
</span><span class="line">		<span class="n">src</span><span class="p">.</span><span class="n">Alpha</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">iconAnimIn</span> <span class="p">=</span> <span class="n">ObjectAnimator</span><span class="p">.</span><span class="n">OfInt</span> <span class="p">(</span><span class="n">src</span><span class="p">,</span> <span class="s">&quot;alpha&quot;</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">255</span><span class="p">);</span>
</span><span class="line">		<span class="n">iconAnimIn</span><span class="p">.</span><span class="n">SetDuration</span> <span class="p">(</span><span class="n">AlphaDuration</span><span class="p">);</span>
</span><span class="line">		<span class="n">iconAnimIn</span><span class="p">.</span><span class="n">StartDelay</span> <span class="p">=</span> <span class="n">AlphaInDelay</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="kt">var</span> <span class="n">inSet</span> <span class="p">=</span> <span class="k">new</span> <span class="n">AnimatorSet</span> <span class="p">();</span>
</span><span class="line">		<span class="n">inSet</span><span class="p">.</span><span class="n">PlayTogether</span> <span class="p">(</span><span class="n">circleAnimInX</span><span class="p">,</span> <span class="n">circleAnimInY</span><span class="p">,</span> <span class="n">iconAnimIn</span><span class="p">);</span>
</span><span class="line">		<span class="n">inSet</span><span class="p">.</span><span class="n">SetInterpolator</span> <span class="p">(</span><span class="n">AnimationUtils</span><span class="p">.</span><span class="n">LoadInterpolator</span> <span class="p">(</span><span class="n">Context</span><span class="p">,</span>
</span><span class="line">		                                                        <span class="n">Android</span><span class="p">.</span><span class="n">Resource</span><span class="p">.</span><span class="n">Animation</span><span class="p">.</span><span class="n">DecelerateInterpolator</span><span class="p">));</span>
</span><span class="line">
</span><span class="line">		<span class="n">switchAnimation</span> <span class="p">=</span> <span class="k">new</span> <span class="n">AnimatorSet</span> <span class="p">();</span>
</span><span class="line">		<span class="n">switchAnimation</span><span class="p">.</span><span class="n">PlaySequentially</span> <span class="p">(</span><span class="n">outSet</span><span class="p">,</span> <span class="n">inSet</span><span class="p">);</span>
</span><span class="line">		<span class="n">switchAnimation</span><span class="p">.</span><span class="n">Start</span> <span class="p">();</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>You can then instantiate this new class directly in your XML layout:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="nt">&lt;myApp.SwitchableFab</span>
</span><span class="line">    <span class="na">android:id=</span><span class="s">&quot;@+id/fabButton&quot;</span>
</span><span class="line">    <span class="na">android:layout_width=</span><span class="s">&quot;wrap_content&quot;</span>
</span><span class="line">    <span class="na">android:layout_height=</span><span class="s">&quot;wrap_content&quot;</span>
</span><span class="line">    <span class="na">android:layout_gravity=</span><span class="s">&quot;end|bottom&quot;</span>
</span><span class="line">    <span class="na">android:layout_marginRight=</span><span class="s">&quot;16dp&quot;</span>
</span><span class="line">    <span class="na">android:layout_marginBottom=</span><span class="s">&quot;16dp&quot;</span>
</span><span class="line">    <span class="na">android:src=</span><span class="s">&quot;@drawable/ic_action_mylocation&quot;</span>
</span><span class="line">    <span class="na">app:srcSecond=</span><span class="s">&quot;@drawable/ic_favorite_selector&quot;</span>
</span><span class="line">    <span class="na">app:backgroundTintSecond=</span><span class="s">&quot;@color/favorite_background&quot;</span> <span class="nt">/&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>For that interaction, the icon itself is normally not supposed to scale but since the widget is based on <code>ImageView</code> it’s impractical right now to separate the two layers to animate a counter-scale for the icon.</p>

<p>I imagine that a default implementation of the documented FAB interactions will likely find its way into the library at some stage but in the meantime it’s very easy to cook them up yourself like above.</p>

<p>You may also have noticed in the video that the second state of my FAB uses an animated selector. This is done by augmenting the <code>SwitchableFab</code> class to track the checkable state (as I have <a href="http://blog.neteril.org/blog/2014/11/13/transitioning-to-infinity/">already demonstrated</a>).</p>

<p>In any case, you can find the full implementation of that selector and checkable changes <a href="https://github.com/garuma/Moyeu/tree/master/Moyeu">in Moyeu repository</a>.</p>

<h3 id="coordinatorlayout-the-missing-orchestra-conductor">CoordinatorLayout, the missing orchestra conductor</h3>

<p>Another interesting type that support-design brings is <a href="http://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.html">CoordinatorLayout</a>.</p>

<p>On the surface it doesn’t seem to do much, it’s intended as a wrapper around your existing UI that behaves like a <code>FrameLayout</code> from a layout perspective. The true value of <code>CoordinatorLayout</code> is found on its child views.</p>

<p>Just like its name imply, <code>CoordinatorLayout</code> serves as a central conductor for more complex transitions that your app UI may be doing especially when involving several floating views like the aformentioned FAB or snackbars.</p>

<p>The core working of the class relies on so-called <a href="http://developer.android.com/reference/android/support/design/widget/CoordinatorLayout.Behavior.html">Behaviors</a> that can be set on any child views of the <code>CoordinatorLayout</code>. In a behavior implementation, views can define if they want to be dependent on some other views and get a callback when that other view state (position, size, etc…) changes.</p>

<p>Behaviors can be attached to views in a multitude of ways but here is how you can declare it directly in your layout XML:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="c">&lt;!-- Based on the same FAB definition than above --&gt;</span>
</span><span class="line"><span class="nt">&lt;moyeu.SwitchableFab</span>
</span><span class="line">    <span class="na">app:layout_behavior=</span><span class="s">&quot;md55d31ab91effba0f9ed7ec79c59c38391.InfoPaneFabBehavior&quot;</span> <span class="nt">/&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Here I made a custom behavior that allows me to automatically track the state of my application bottom pane as it appears/disappears and is dragged by the user so that the FAB automatically stick to it and change its state when the pane is initially expanded (using the transition animation we saw earlier):</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="k">public</span> <span class="k">class</span> <span class="nc">InfoPaneFabBehavior</span> <span class="p">:</span> <span class="n">CoordinatorLayout</span><span class="p">.</span><span class="n">Behavior</span>
</span><span class="line"><span class="p">{</span>
</span><span class="line">	<span class="kt">int</span> <span class="n">minMarginBottom</span><span class="p">;</span>
</span><span class="line">	<span class="kt">bool</span> <span class="n">wasOpened</span> <span class="p">=</span> <span class="k">false</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="nf">InfoPaneFabBehavior</span> <span class="p">(</span><span class="n">Context</span> <span class="n">context</span><span class="p">,</span> <span class="n">IAttributeSet</span> <span class="n">attrs</span><span class="p">)</span> <span class="p">:</span> <span class="k">base</span> <span class="p">(</span><span class="n">context</span><span class="p">,</span> <span class="n">attrs</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="n">minMarginBottom</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">TypedValue</span><span class="p">.</span><span class="n">ApplyDimension</span> <span class="p">(</span><span class="n">ComplexUnitType</span><span class="p">.</span><span class="n">Dip</span><span class="p">,</span> <span class="m">16</span><span class="p">,</span> <span class="n">context</span><span class="p">.</span><span class="n">Resources</span><span class="p">.</span><span class="n">DisplayMetrics</span><span class="p">);</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="k">override</span> <span class="kt">bool</span> <span class="nf">LayoutDependsOn</span> <span class="p">(</span><span class="n">CoordinatorLayout</span> <span class="n">parent</span><span class="p">,</span> <span class="n">Java</span><span class="p">.</span><span class="n">Lang</span><span class="p">.</span><span class="n">Object</span> <span class="n">child</span><span class="p">,</span> <span class="n">View</span> <span class="n">dependency</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="k">return</span> <span class="n">dependency</span> <span class="k">is</span> <span class="n">InfoPane</span><span class="p">;</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="k">override</span> <span class="kt">bool</span> <span class="nf">OnDependentViewChanged</span> <span class="p">(</span><span class="n">CoordinatorLayout</span> <span class="n">parent</span><span class="p">,</span> <span class="n">Java</span><span class="p">.</span><span class="n">Lang</span><span class="p">.</span><span class="n">Object</span> <span class="n">child</span><span class="p">,</span> <span class="n">View</span> <span class="n">dependency</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="c1">// Move the fab vertically to place correctly wrt the info pane</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">fab</span> <span class="p">=</span> <span class="n">child</span><span class="p">.</span><span class="n">JavaCast</span><span class="p">&lt;</span><span class="n">SwitchableFab</span><span class="p">&gt;</span> <span class="p">();</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">currentInfoPaneY</span> <span class="p">=</span> <span class="n">ViewCompat</span><span class="p">.</span><span class="n">GetTranslationY</span> <span class="p">(</span><span class="n">dependency</span><span class="p">);</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">newTransY</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">Math</span><span class="p">.</span><span class="n">Max</span> <span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">dependency</span><span class="p">.</span><span class="n">Height</span> <span class="p">-</span> <span class="n">currentInfoPaneY</span> <span class="p">-</span> <span class="n">minMarginBottom</span> <span class="p">-</span> <span class="n">fab</span><span class="p">.</span><span class="n">Height</span> <span class="p">/</span> <span class="m">2</span><span class="p">);</span>
</span><span class="line">		<span class="n">ViewCompat</span><span class="p">.</span><span class="n">SetTranslationY</span> <span class="p">(</span><span class="n">fab</span><span class="p">,</span> <span class="p">-</span><span class="n">newTransY</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">		<span class="c1">// If alternating between open/closed state, change the FAB face</span>
</span><span class="line">		<span class="k">if</span> <span class="p">(</span><span class="n">wasOpened</span> <span class="p">^</span> <span class="p">((</span><span class="n">InfoPane</span><span class="p">)</span><span class="n">dependency</span><span class="p">).</span><span class="n">Opened</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">			<span class="n">fab</span><span class="p">.</span><span class="n">Switch</span> <span class="p">();</span>
</span><span class="line">			<span class="n">wasOpened</span> <span class="p">=</span> <span class="p">!</span><span class="n">wasOpened</span><span class="p">;</span>
</span><span class="line">		<span class="p">}</span>
</span><span class="line">
</span><span class="line">		<span class="k">return</span> <span class="k">true</span><span class="p">;</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Dead simple right?</p>

<p><code>CoordinatorLayout</code> can also be used to implement other user interactions like swipe-to-dismiss or other scrolling techniques (like collapsing toolbars). Checkout the provided <a href="http://developer.android.com/reference/android/support/design/widget/SwipeDismissBehavior.html">SwipeDismissBehavior</a> and <a href="http://developer.android.com/reference/android/support/design/widget/AppBarLayout.Behavior.html">AppBarLayout.Behavior</a> for more information on those scenarios.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Advanced transitions with vector drawable]]></title>
    <link href="http://blog.neteril.org/blog/2015/04/09/advanced-transitions-with-vector-drawable/"/>
    <updated>2015-04-09T07:46:31-04:00</updated>
    <id>http://blog.neteril.org/blog/2015/04/09/advanced-transitions-with-vector-drawable</id>
    <content type="html"><![CDATA[<p>As I described in a <a href="http://blog.neteril.org/blog/2014/11/09/scaling-to-infinity/">previous</a> <a href="http://blog.neteril.org/blog/2014/11/12/animating-to-infinity/">serie</a> of <a href="http://blog.neteril.org/blog/2014/11/13/transitioning-to-infinity/">post</a>, vector drawables (and their animated counterparts) are one of the most powerful new visual elements introduced with Lollipop (and soon as a support lib <a href="https://github.com/android/platform_frameworks_support/tree/master/v7/vectordrawable">it seems</a>).</p>

<p>In this post, I’m gonna show you how we can achieve the following transition animation by solely using vector drawables and Android’s built-in widget state tracking mechanism:</p>

<video width="422" height="196" controls=""><source src="http://blog.neteril.org/wp-content/uploads/time-switcher-vector.mp4" type="video/mp4" /></video>

<h3 id="staging">Staging</h3>

<p>To build an animation like this, you have to prepare the adequate stage. Afterwards, it’s just a matter of moving each individual pieces of that stage when needed.</p>

<p>In the above video, we can split the final visual in a couple of different parts.</p>

<p>Some like the center dot and the upper-half donut are static pieces, they never move. The two white thin rectangles, symbolizing the hands on a watch, are individual moving parts. The sun, moon and exclamation mark symbols are the varying state of the visual depending on the input.</p>

<p>Now, that’s only the visible part of the puzzle. If you look closely at the animation you can notice that everytime there is a state transition the right hand seems to be erasing the visible time symbol before the new one fade in.</p>

<p>This is where things get interesting because to be able to achieve this effect you have to get creative with the Z-ordering of your stage.</p>

<p>To understand this better, below is a rendering of all the layers of the visual:</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/time-switcher-vector.png" width="306" height="282" class="center" /></p>

<p>The rectangle you see covering the half-bottom part of the picture is not an artifact. It’s painted with the same color than the overall window background thus acting as a cheap but effective hiding mask.</p>

<p>If I conceal this rectangle, here is what’s lurking behind: the other half of the visible top donut</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/time-switcher-vector2.png" width="306" height="282" class="center" /></p>

<p>To create the aformentioned effect, we will be moving that half-bottom donut to cover the top one, synchronizing it with the right clock hand. When not in use, it will be safely tucked behind our hiding rectangle.</p>

<p>Because vector drawables have a simple bottom to top drawing hierarchy, for this to work correctly we have declare pieces in a specific order:</p>

<ul>
  <li>top half donut</li>
  <li>the 3 time symbols</li>
  <li>bottom half donut</li>
  <li>hiding rectangle</li>
  <li>the 2 hands white rectangle</li>
</ul>

<p>Based on our animation needs, we then split this further into actual vector drawable <code>&lt;group /&gt;</code> elements to arrive at the following shape (path data removed for brevity, you can download all the XML pack at the end of the article):</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
<span class="line-number">34</span>
<span class="line-number">35</span>
<span class="line-number">36</span>
<span class="line-number">37</span>
<span class="line-number">38</span>
<span class="line-number">39</span>
<span class="line-number">40</span>
<span class="line-number">41</span>
<span class="line-number">42</span>
<span class="line-number">43</span>
<span class="line-number">44</span>
<span class="line-number">45</span>
<span class="line-number">46</span>
<span class="line-number">47</span>
<span class="line-number">48</span>
<span class="line-number">49</span>
<span class="line-number">50</span>
<span class="line-number">51</span>
<span class="line-number">52</span>
<span class="line-number">53</span>
<span class="line-number">54</span>
<span class="line-number">55</span>
<span class="line-number">56</span>
<span class="line-number">57</span>
<span class="line-number">58</span>
<span class="line-number">59</span>
<span class="line-number">60</span>
<span class="line-number">61</span>
<span class="line-number">62</span>
<span class="line-number">63</span>
<span class="line-number">64</span>
<span class="line-number">65</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;</span>
</span><span class="line"><span class="nt">&lt;vector</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:height=</span><span class="s">&quot;385dp&quot;</span>
</span><span class="line">	<span class="na">android:width=</span><span class="s">&quot;416dp&quot;</span>
</span><span class="line">	<span class="na">android:viewportHeight=</span><span class="s">&quot;385&quot;</span>
</span><span class="line">	<span class="na">android:viewportWidth=</span><span class="s">&quot;416&quot;</span><span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;group</span> <span class="na">android:name=</span><span class="s">&quot;background&quot;</span><span class="nt">&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:name=</span><span class="s">&quot;topPie&quot;</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#454D58&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line">	<span class="nt">&lt;group</span> <span class="na">android:name=</span><span class="s">&quot;timeItems&quot;</span><span class="nt">&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:name=</span><span class="s">&quot;moon&quot;</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#DAE2ED&quot;</span>
</span><span class="line">			<span class="na">android:fillAlpha=</span><span class="s">&quot;0&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:name=</span><span class="s">&quot;sun&quot;</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#E39300&quot;</span>
</span><span class="line">			<span class="na">android:fillAlpha=</span><span class="s">&quot;0&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:name=</span><span class="s">&quot;now&quot;</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#C52E26&quot;</span>
</span><span class="line">			<span class="na">android:fillAlpha=</span><span class="s">&quot;1&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line">	<span class="nt">&lt;group</span>
</span><span class="line">		<span class="na">android:name=</span><span class="s">&quot;hidingPie&quot;</span>
</span><span class="line">		<span class="na">android:pivotX=</span><span class="s">&quot;208&quot;</span>
</span><span class="line">		<span class="na">android:pivotY=</span><span class="s">&quot;192.5&quot;</span><span class="nt">&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:name=</span><span class="s">&quot;hidingPiePath&quot;</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#454D58&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line">	<span class="nt">&lt;group</span> <span class="na">android:name=</span><span class="s">&quot;coverBackground&quot;</span><span class="nt">&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:name=</span><span class="s">&quot;blueCover&quot;</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#343A42&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:name=</span><span class="s">&quot;middleRing&quot;</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#D8D8D8&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line">	<span class="nt">&lt;group</span>
</span><span class="line">		<span class="na">android:name=</span><span class="s">&quot;leftHand&quot;</span>
</span><span class="line">		<span class="na">android:pivotX=</span><span class="s">&quot;208&quot;</span>
</span><span class="line">		<span class="na">android:pivotY=</span><span class="s">&quot;192.5&quot;</span><span class="nt">&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#D8D8D8&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line">	<span class="nt">&lt;group</span>
</span><span class="line">		<span class="na">android:name=</span><span class="s">&quot;rightHand&quot;</span>
</span><span class="line">		<span class="na">android:pivotX=</span><span class="s">&quot;208&quot;</span>
</span><span class="line">		<span class="na">android:pivotY=</span><span class="s">&quot;192.5&quot;</span><span class="nt">&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;#D8D8D8&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;...&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line"><span class="nt">&lt;/vector&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<h3 id="state-tracking-widget">State tracking widget</h3>

<p>Before we dwelve into some more animation tricks, we first need to investigate how to make widget to represent our triple state because there is nothing in the default framework that allow this.</p>

<p>The good news is that, as I showed in <a href="http://blog.neteril.org/blog/2014/11/13/transitioning-to-infinity/">a previous blog</a>, it’s very easy to create a custom, state-aware widget which is what we are going to do with this:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="k">public</span> <span class="k">class</span> <span class="nc">TriStateView</span> <span class="p">:</span> <span class="n">View</span>
</span><span class="line"><span class="p">{</span>
</span><span class="line">	<span class="kt">int</span> <span class="n">selectedIndex</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="kt">int</span> <span class="n">SelectedIndex</span> <span class="p">{</span>
</span><span class="line">		<span class="k">get</span> <span class="p">{</span>
</span><span class="line">			<span class="k">return</span> <span class="n">selectedIndex</span><span class="p">;</span>
</span><span class="line">		<span class="p">}</span>
</span><span class="line">		<span class="k">set</span> <span class="p">{</span>
</span><span class="line">			<span class="k">if</span> <span class="p">(</span><span class="k">value</span> <span class="p">&lt;</span> <span class="m">0</span> <span class="p">||</span> <span class="k">value</span> <span class="p">&gt;</span> <span class="m">2</span><span class="p">)</span>
</span><span class="line">				<span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentOutOfRangeException</span> <span class="p">(</span><span class="s">&quot;value&quot;</span><span class="p">);</span>
</span><span class="line">			<span class="n">JumpDrawablesToCurrentState</span> <span class="p">();</span>
</span><span class="line">			<span class="n">selectedIndex</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span>
</span><span class="line">			<span class="n">RefreshDrawableState</span> <span class="p">();</span>
</span><span class="line">			<span class="n">Invalidate</span> <span class="p">();</span>
</span><span class="line">		<span class="p">}</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">protected</span> <span class="k">override</span> <span class="kt">int</span><span class="p">[]</span> <span class="nf">OnCreateDrawableState</span> <span class="p">(</span><span class="kt">int</span> <span class="n">extraSpace</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="k">switch</span> <span class="p">(</span><span class="n">selectedIndex</span><span class="p">)</span> <span class="p">{</span>
</span><span class="line">		<span class="k">case</span> <span class="m">0</span><span class="p">:</span>
</span><span class="line">			<span class="k">return</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="m">0</span><span class="p">];</span>
</span><span class="line">		<span class="k">case</span> <span class="m">1</span><span class="p">:</span>
</span><span class="line">			<span class="k">return</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[]</span> <span class="p">{</span> <span class="n">Android</span><span class="p">.</span><span class="n">Resource</span><span class="p">.</span><span class="n">Attribute</span><span class="p">.</span><span class="n">StateFirst</span> <span class="p">};</span>
</span><span class="line">		<span class="k">case</span> <span class="m">2</span><span class="p">:</span>
</span><span class="line">			<span class="k">return</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[]</span> <span class="p">{</span> <span class="n">Android</span><span class="p">.</span><span class="n">Resource</span><span class="p">.</span><span class="n">Attribute</span><span class="p">.</span><span class="n">StateLast</span> <span class="p">};</span>
</span><span class="line">		<span class="k">default</span><span class="p">:</span>
</span><span class="line">			<span class="k">return</span> <span class="k">base</span><span class="p">.</span><span class="n">OnCreateDrawableState</span> <span class="p">(</span><span class="n">extraSpace</span><span class="p">);</span>
</span><span class="line">		<span class="p">}</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>By setting our state transition drawable as the background of this view, it will automatically react to state changes and animate accordingly. Using the normal state tracking mechanism also means that interruption mid-animations are gracefully handled for us.</p>

<h3 id="one-more-trick">One more trick</h3>

<p>At this stage, I won’t go over every details of the individual animation definitions, they all tweak standard things like alpha and rotation on each piece of our stage. Nonetheless, you can read <a href="http://blog.neteril.org/blog/2014/11/11/animating-to-infinity/">my animated vector drawable entry</a> for more details on how they work.</p>

<p>I will only show a little trick that is useful when setting up more complex stages like this: zero-duration animators.</p>

<p>Take the following example that animates the bottom-half donut (to create the progressive hiding effect):</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;</span>
</span><span class="line"><span class="nt">&lt;set</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:ordering=</span><span class="s">&quot;sequentially&quot;</span><span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;objectAnimator</span>
</span><span class="line">		<span class="na">android:duration=</span><span class="s">&quot;850&quot;</span>
</span><span class="line">		<span class="na">android:propertyName=</span><span class="s">&quot;rotation&quot;</span>
</span><span class="line">		<span class="na">android:valueFrom=</span><span class="s">&quot;0&quot;</span>
</span><span class="line">		<span class="na">android:valueTo=</span><span class="s">&quot;180&quot;</span>
</span><span class="line">		<span class="na">android:valueType=</span><span class="s">&quot;floatType&quot;</span>
</span><span class="line">		<span class="na">android:interpolator=</span><span class="s">&quot;@android:interpolator/decelerate_quad&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;objectAnimator</span>
</span><span class="line">		<span class="na">android:duration=</span><span class="s">&quot;0&quot;</span>
</span><span class="line">		<span class="na">android:propertyName=</span><span class="s">&quot;rotation&quot;</span>
</span><span class="line">		<span class="na">android:valueFrom=</span><span class="s">&quot;-180&quot;</span>
</span><span class="line">		<span class="na">android:valueTo=</span><span class="s">&quot;0&quot;</span>
</span><span class="line">		<span class="na">android:valueType=</span><span class="s">&quot;floatType&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line"><span class="nt">&lt;/set&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>The idea is that right after we have covered the entire upper-half, we want to immediately tuck it back under our hiding rectangle. This is because we then fade-in the new time symbol which would be hidden too otherwise.</p>

<p>Using zero-duration animators allow you to do just that by applying direct values to animated properties. The fact that there is a from attribute doesn’t matter much but since those properties are write only it will prevent object animator from complaining about missing accessors.</p>

<p>I use this in a couple of places to reset the stage state (since vector drawable instances are reused across transitions), quickly move away elements or hide them from view when they are not useful anymore.</p>

<h3 id="source">Source</h3>

<p>You can download the XML definitions and widget source <a href="http://blog.neteril.org/wp-content/uploads/ts-transition-animation.zip">here</a>.</p>

<p><strong>Bug alert</strong>: <a href="https://code.google.com/p/android/issues/detail?id=164361">there is currently a parsing bug</a> where the animated vector drawable inflater will greedily read the entire document given to it. This causes an issue if you declare them inline in your animated state transition XML file because it will corrupt your entire state by reading everything instead of stopping at its corresponding end tag. The workaround is to always declare them in their own XML files like I did.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Android Material Image Loading]]></title>
    <link href="http://blog.neteril.org/blog/2014/11/23/android-material-image-loading/"/>
    <updated>2014-11-23T20:34:14-05:00</updated>
    <id>http://blog.neteril.org/blog/2014/11/23/android-material-image-loading</id>
    <content type="html"><![CDATA[<p>Among the plethora of seemingly impossible things in the <a href="http://www.google.com/design/spec/">Material Design specification</a>, there is one that piqued my curiosity this morning.</p>

<p>It’s something everybody does at least once, if not everywhere, in his app which is loading and transitioning images.</p>

<p>Now to make this more glamour we generally all went with the classical, battle-tested approach of shifting the opacity of our image container to announce the change (that was even one of my <a href="http://blog.neteril.org/blog/2012/12/19/mfa-tricks-number-1-fadeimageview/">first Android tip</a>).</p>

<p>But the new approach taken by Material and detailed in the <a href="http://www.google.com/design/spec/patterns/loading-images.html#loading-images-loading-images">“Loading Images” section</a> goes a lot further than this by also throwing some image levels manipulation in the mix.</p>

<p>The process is summarized in the following graph:</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/patternsloadingimages.png" class="center" /></p>

<p>It outlines a 3-steps process where a combination of opacity, contrast/luminosity and saturation is used in concert to help salvage our poor users eyesight. </p>

<p>Android has always supported image manipulation through the <code>ColorFilter</code> class that can be set on any drawable and on some view classes (<code>ImageView</code> for instance).</p>

<p>When used with its 4x5 <a href="http://developer.android.com/reference/android/graphics/ColorMatrix.html">ColorMatrix</a>-based implementation <code>ColorMatrixColorFilter</code>, you can virtually implement any kind of image transformation provided you grok the way vector/matrix multiplication work (head to the <code>ColorMatrix</code> documentation for the resulting equations).</p>

<p>The only thing that was a limiting factor is that a filter is initialized once and for all. If you want to change the effect you need to create a new instance of the filter (which initialize a native counterpart) and replace the old version with the new one.</p>

<p>Obviously this is a complete downer when you do animations because you don’t want to stress out the GC and GPU during those phases by creating a new instance of the filter at every refresh step.</p>

<p>But thanks to Lollipop and the fact <a href="https://twitter.com/jeremie_laval/status/536679366441586689">that @hide can’t stop us</a>, there is actually <a href="https://github.com/android/platform_frameworks_base/blob/master/graphics/java/android/graphics/ColorMatrixColorFilter.java#L81">a new public method</a> allowing us to update a filter after the fact.</p>

<p>Armed with this knowledge, we can now set out to create a custom <code>ITypeEvaluator</code> to tweak our filter:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
<span class="line-number">34</span>
<span class="line-number">35</span>
<span class="line-number">36</span>
<span class="line-number">37</span>
<span class="line-number">38</span>
<span class="line-number">39</span>
<span class="line-number">40</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="c1">// Refer to http://developer.android.com/reference/android/graphics/ColorMatrix.html</span>
</span><span class="line"><span class="c1">// for a list of the matrix indexes</span>
</span><span class="line"><span class="k">class</span> <span class="nc">AlphaSatColorMatrixEvaluator</span> <span class="p">:</span> <span class="n">Java</span><span class="p">.</span><span class="n">Lang</span><span class="p">.</span><span class="n">Object</span><span class="p">,</span> <span class="n">ITypeEvaluator</span>
</span><span class="line"><span class="p">{</span>
</span><span class="line">	<span class="n">ColorMatrix</span> <span class="n">colorMatrix</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ColorMatrix</span> <span class="p">();</span>
</span><span class="line">	<span class="kt">float</span><span class="p">[]</span> <span class="n">elements</span> <span class="p">=</span> <span class="k">new</span> <span class="kt">float</span><span class="p">[</span><span class="m">20</span><span class="p">];</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="n">ColorMatrix</span> <span class="n">ColorMatrix</span> <span class="p">{</span>
</span><span class="line">		<span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">colorMatrix</span><span class="p">;</span> <span class="p">}</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="n">Java</span><span class="p">.</span><span class="n">Lang</span><span class="p">.</span><span class="n">Object</span> <span class="n">Evaluate</span> <span class="p">(</span><span class="kt">float</span> <span class="n">fraction</span><span class="p">,</span> <span class="n">Java</span><span class="p">.</span><span class="n">Lang</span><span class="p">.</span><span class="n">Object</span> <span class="n">startValue</span><span class="p">,</span> <span class="n">Java</span><span class="p">.</span><span class="n">Lang</span><span class="p">.</span><span class="n">Object</span> <span class="n">endValue</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="c1">// There are 3 phases so we multiply fraction by that amount</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">phase</span> <span class="p">=</span> <span class="n">fraction</span> <span class="p">*</span> <span class="m">3</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="c1">// Compute the alpha change over period [0, 2]</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">alpha</span> <span class="p">=</span> <span class="n">Math</span><span class="p">.</span><span class="n">Min</span> <span class="p">(</span><span class="n">phase</span><span class="p">,</span> <span class="m">2f</span><span class="p">)</span> <span class="p">/</span> <span class="m">2f</span><span class="p">;</span>
</span><span class="line">		<span class="n">elements</span> <span class="p">[</span><span class="m">19</span><span class="p">]</span> <span class="p">=</span> <span class="p">(</span><span class="kt">float</span><span class="p">)</span><span class="n">Math</span><span class="p">.</span><span class="n">Round</span> <span class="p">(</span><span class="n">alpha</span> <span class="p">*</span> <span class="m">255</span><span class="p">);</span>
</span><span class="line">
</span><span class="line">		<span class="c1">// We substract to make the picture look darker, it will automatically clamp</span>
</span><span class="line">		<span class="c1">// This is spread over period [0, 2.5]</span>
</span><span class="line">		<span class="k">const</span> <span class="kt">int</span> <span class="n">MaxBlacker</span> <span class="p">=</span> <span class="m">100</span><span class="p">;</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">blackening</span> <span class="p">=</span> <span class="p">(</span><span class="kt">float</span><span class="p">)</span><span class="n">Math</span><span class="p">.</span><span class="n">Round</span> <span class="p">((</span><span class="m">1</span> <span class="p">-</span> <span class="n">Math</span><span class="p">.</span><span class="n">Min</span> <span class="p">(</span><span class="n">phase</span><span class="p">,</span> <span class="m">2.5f</span><span class="p">)</span> <span class="p">/</span> <span class="m">2.5f</span><span class="p">)</span> <span class="p">*</span> <span class="n">MaxBlacker</span><span class="p">);</span>
</span><span class="line">		<span class="n">elements</span> <span class="p">[</span><span class="m">4</span><span class="p">]</span> <span class="p">=</span> <span class="n">elements</span> <span class="p">[</span><span class="m">9</span><span class="p">]</span> <span class="p">=</span> <span class="n">elements</span> <span class="p">[</span><span class="m">14</span><span class="p">]</span> <span class="p">=</span> <span class="p">-</span><span class="n">blackening</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="c1">// Finally we desaturate over [0, 3], taken from ColorMatrix.SetSaturation</span>
</span><span class="line">		<span class="kt">float</span> <span class="n">invSat</span> <span class="p">=</span> <span class="m">1</span> <span class="p">-</span> <span class="n">Math</span><span class="p">.</span><span class="n">Max</span> <span class="p">(</span><span class="m">0.2f</span><span class="p">,</span> <span class="n">fraction</span><span class="p">);</span>
</span><span class="line">		<span class="kt">float</span> <span class="n">R</span> <span class="p">=</span> <span class="m">0.213f</span> <span class="p">*</span> <span class="n">invSat</span><span class="p">;</span>
</span><span class="line">		<span class="kt">float</span> <span class="n">G</span> <span class="p">=</span> <span class="m">0.715f</span> <span class="p">*</span> <span class="n">invSat</span><span class="p">;</span>
</span><span class="line">		<span class="kt">float</span> <span class="n">B</span> <span class="p">=</span> <span class="m">0.072f</span> <span class="p">*</span> <span class="n">invSat</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="n">elements</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="p">=</span> <span class="n">R</span> <span class="p">+</span> <span class="n">fraction</span><span class="p">;</span> <span class="n">elements</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="p">=</span> <span class="n">G</span><span class="p">;</span>            <span class="n">elements</span><span class="p">[</span><span class="m">2</span><span class="p">]</span> <span class="p">=</span> <span class="n">B</span><span class="p">;</span>
</span><span class="line">		<span class="n">elements</span><span class="p">[</span><span class="m">5</span><span class="p">]</span> <span class="p">=</span> <span class="n">R</span><span class="p">;</span>            <span class="n">elements</span><span class="p">[</span><span class="m">6</span><span class="p">]</span> <span class="p">=</span> <span class="n">G</span> <span class="p">+</span> <span class="n">fraction</span><span class="p">;</span> <span class="n">elements</span><span class="p">[</span><span class="m">7</span><span class="p">]</span> <span class="p">=</span> <span class="n">B</span><span class="p">;</span>
</span><span class="line">		<span class="n">elements</span><span class="p">[</span><span class="m">10</span><span class="p">]</span> <span class="p">=</span> <span class="n">R</span><span class="p">;</span>           <span class="n">elements</span><span class="p">[</span><span class="m">11</span><span class="p">]</span> <span class="p">=</span> <span class="n">G</span><span class="p">;</span>           <span class="n">elements</span><span class="p">[</span><span class="m">12</span><span class="p">]</span> <span class="p">=</span> <span class="n">B</span> <span class="p">+</span> <span class="n">fraction</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">		<span class="n">colorMatrix</span><span class="p">.</span><span class="n">Set</span> <span class="p">(</span><span class="n">elements</span><span class="p">);</span>
</span><span class="line">		<span class="k">return</span> <span class="n">colorMatrix</span><span class="p">;</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Here is how you can set it up:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="kt">var</span> <span class="n">imageView</span> <span class="p">=</span> <span class="n">FindViewById</span><span class="p">&lt;</span><span class="n">ImageView</span><span class="p">&gt;</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Id</span><span class="p">.</span><span class="n">image</span><span class="p">);</span>
</span><span class="line"><span class="kt">var</span> <span class="n">drawable</span> <span class="p">=</span> <span class="p">(</span><span class="n">BitmapDrawable</span><span class="p">)</span><span class="n">Resources</span><span class="p">.</span><span class="n">GetDrawable</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Drawable</span><span class="p">.</span><span class="n">monkey</span><span class="p">);</span>
</span><span class="line"><span class="kt">var</span> <span class="n">evaluator</span> <span class="p">=</span> <span class="k">new</span> <span class="n">AlphaSatColorMatrixEvaluator</span> <span class="p">();</span>
</span><span class="line"><span class="kt">var</span> <span class="n">filter</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ColorMatrixColorFilter</span> <span class="p">(</span><span class="n">evaluator</span><span class="p">.</span><span class="n">ColorMatrix</span><span class="p">);</span>
</span><span class="line"><span class="n">drawable</span><span class="p">.</span><span class="n">SetColorFilter</span> <span class="p">(</span><span class="n">filter</span><span class="p">);</span>
</span><span class="line">
</span><span class="line"><span class="kt">var</span> <span class="n">animator</span> <span class="p">=</span> <span class="n">ObjectAnimator</span><span class="p">.</span><span class="n">OfObject</span> <span class="p">(</span><span class="n">filter</span><span class="p">,</span> <span class="s">&quot;colorMatrix&quot;</span><span class="p">,</span> <span class="n">evaluator</span><span class="p">,</span>
</span><span class="line">                                        <span class="n">evaluator</span><span class="p">.</span><span class="n">ColorMatrix</span><span class="p">,</span>
</span><span class="line">                                        <span class="n">evaluator</span><span class="p">.</span><span class="n">ColorMatrix</span><span class="p">);</span>
</span><span class="line"><span class="n">animator</span><span class="p">.</span><span class="n">Update</span> <span class="p">+=</span> <span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="n">drawable</span><span class="p">.</span><span class="n">SetColorFilter</span> <span class="p">(</span><span class="n">filter</span><span class="p">);</span>
</span><span class="line"><span class="n">animator</span><span class="p">.</span><span class="n">SetDuration</span> <span class="p">(</span><span class="m">2500</span><span class="p">);</span>
</span><span class="line"><span class="n">animator</span><span class="p">.</span><span class="n">Start</span> <span class="p">();</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>And here is the result:</p>

<video width="500" height="300" controls="" src="http://blog.neteril.org/wp-content/uploads/materialimageloading.mp4"></video>

<p>It’s probably safe to assume Google will come out with an official way for this pattern e.g. in a subsequent support library update. In the meantime, you can get cracking with this version.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Transitioning to Infinity]]></title>
    <link href="http://blog.neteril.org/blog/2014/11/13/transitioning-to-infinity/"/>
    <updated>2014-11-13T10:00:20-05:00</updated>
    <id>http://blog.neteril.org/blog/2014/11/13/transitioning-to-infinity</id>
    <content type="html"><![CDATA[<p>I remember clearly when I sat down at I/O this year, watching the introduction of Material design in the keynote unfold and how, at the time, I told myself there was no way we could implement all of this in Android.</p>

<p>One such aspect that I was highly skeptical of until very recently was the concept of animated transition.</p>

<p>We actually talked about this during our <a href="https://www.youtube.com/watch?v=_q9lorDZn0Y#t=23m26">Material Design Evolve session</a> with James and at the time of that talk, the only facility we had been given to do it was by keyframe animations which is incredibly clunky to maintain.</p>

<p>Meet our new private implementation friend, <a href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/animation/AnimatorInflater.java#L208">PathDataEvaluator</a>.</p>

<p>This evaluator is able to understand the <a href="http://blog.neteril.org/blog/2014/11/09/scaling-to-infinity/">path definition used by vector drawable</a> and create intermediary versions of it.</p>

<p>This means that given two specific path of a vector drawable, we can use an object animator to, not only animate transformation or style like <a href="http://blog.neteril.org/blog/2014/11/11/animating-to-infinity/">we have seen before</a>, but also the actual <code>pathData</code> of the vector itself.</p>

<p>Now before you get too excited, it’s not a miracle evaluator. There are two very strong requirements for it to work properly:</p>

<ul>
  <li>The path command list needs to be of the same size</li>
  <li>Each command in that list needs to be of the same type</li>
</ul>

<p>Basically, the evaluator treats the path data as an array of float extracted from each command parameters and use that to interpolate inbetweeners.</p>

<p>This essentially mean that when crafting your paths, you may need to get a bit creative in the amount of nodes you use in order to make those requirements fit.</p>

<p>As an example, this is what we are going to make:</p>

<video width="500" height="300" autoplay="" loop="" controls=""><source src="http://blog.neteril.org/wp-content/uploads/transition-vector/transition.mp4" type="video/mp4" /></video>

<p>Intuitively, based on our previously mentioned requirements, we can see there is already fundamental problem when we think of alternating between a standard play icon and a standard pause icon: they don’t have the same amounts of subparts (2 rectangles for pause, 1 triangle for play).</p>

<p>In addition, the pause icon rectangles necessitate 4 control points for each subpart whereas the triangle of the play icon only requires 3.</p>

<p>That’s where the tweaking part comes in, following are how I created those shapes in my editor to solve both issues (nodes handles are highlighted):</p>

<div style="text-align: center"><img src="http://blog.neteril.org/wp-content/uploads/transition-vector/play_points.png" style="height: 256px" /> <img src="http://blog.neteril.org/wp-content/uploads/transition-vector/pause_points.png" style="height: 256px" /></div>

<p>The work was actually focused on the play icon by first separating the triangle shape in two right sub-triangles and then adding a (normally unnecessary) extra node onto its hypotenuse.</p>

<p>Each node is also numbered as the order in which the path is drawn has an impact on the look and feel of the animation. With those numbers, you can visualize in your head how the nodes are going to move across the canvas to alternate between the two shapes.</p>

<p>Without further ado, here are the vector drawables we are using:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="c">&lt;!-- In your strings.xml file --&gt;</span>
</span><span class="line"><span class="nt">&lt;resources&gt;</span>
</span><span class="line">	<span class="nt">&lt;string</span> <span class="na">name=</span><span class="s">&quot;pause_vector_path&quot;</span><span class="nt">&gt;</span>M12,10L20,10L20,38L12,38ZM28,10L36,10L36,38L28,38Z<span class="nt">&lt;/string&gt;</span>
</span><span class="line">	<span class="nt">&lt;string</span> <span class="na">name=</span><span class="s">&quot;play_vector_path&quot;</span><span class="nt">&gt;</span>M16,24L38,24L27.3,30.8L16,38ZM16,10L27.3,17.2L38,24L16,24Z<span class="nt">&lt;/string&gt;</span>
</span><span class="line"><span class="nt">&lt;/resources&gt;</span>
</span><span class="line">
</span><span class="line"><span class="c">&lt;!-- Resources\drawable\ic_play.xml --&gt;</span>
</span><span class="line"><span class="nt">&lt;vector</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:height=</span><span class="s">&quot;48dp&quot;</span>
</span><span class="line">	<span class="na">android:width=</span><span class="s">&quot;48dp&quot;</span>
</span><span class="line">	<span class="na">android:viewportHeight=</span><span class="s">&quot;48&quot;</span>
</span><span class="line">	<span class="na">android:viewportWidth=</span><span class="s">&quot;48&quot;</span><span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;group&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span> <span class="na">android:name=</span><span class="s">&quot;d&quot;</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;@color/white_primary&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;@string/play_vector_path&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line"><span class="nt">&lt;/vector&gt;</span>
</span><span class="line">
</span><span class="line"><span class="c">&lt;!-- Resources\drawable\ic_play.xml is identical except</span>
</span><span class="line"><span class="c">     replace pathData with the second string resource --&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>The path data themselves are stored as a string resources. This makes it easier to use them in different places without having to copy and paste the entire thing.</p>

<p>Notice also how my commands are ordered (M stands for <strong>moveto</strong> and L for <strong>lineto</strong>) to reflect what the editor diagram showed and also how each command type maps to the same command type between the two definitions.</p>

<p>Since we want to create a transition we need a container for this that handle state using the Android standard state tracking mechanism. This type of container is called a state-list and, as we already covered in the Evolve video above, we now also have an equivalent version that supports animated transition between state: <a href="http://developer.android.com/reference/android/graphics/drawable/AnimatedStateListDrawable.html">AnimatedStateListDrawable</a>.</p>

<p>Here is my definition for the play/pause button state (based on the <code>state_checked</code> presence):</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="nt">&lt;animated-selector</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">    <span class="na">android:constantSize=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>
</span><span class="line">    <span class="nt">&lt;item</span>
</span><span class="line">        <span class="na">android:drawable=</span><span class="s">&quot;@drawable/ic_pause&quot;</span>
</span><span class="line">        <span class="na">android:state_checked=</span><span class="s">&quot;true&quot;</span>
</span><span class="line">        <span class="na">android:id=</span><span class="s">&quot;@+id/pause_state&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">    <span class="nt">&lt;item</span>
</span><span class="line">        <span class="na">android:drawable=</span><span class="s">&quot;@drawable/ic_play&quot;</span>
</span><span class="line">        <span class="na">android:id=</span><span class="s">&quot;@+id/play_state&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;transition</span> <span class="na">android:fromId=</span><span class="s">&quot;@id/play_state&quot;</span> <span class="na">android:toId=</span><span class="s">&quot;@id/pause_state&quot;</span> <span class="na">android:reversible=</span><span class="s">&quot;true&quot;</span><span class="nt">&gt;</span>
</span><span class="line">		<span class="nt">&lt;animated-vector</span> <span class="na">android:drawable=</span><span class="s">&quot;@drawable/ic_play&quot;</span><span class="nt">&gt;</span>
</span><span class="line">			<span class="nt">&lt;target</span> <span class="na">android:name=</span><span class="s">&quot;d&quot;</span> <span class="na">android:animation=</span><span class="s">&quot;@anim/play_pause&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">		<span class="nt">&lt;/animated-vector&gt;</span>
</span><span class="line">	<span class="nt">&lt;/transition&gt;</span>
</span><span class="line"><span class="nt">&lt;/animated-selector&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>You can watch the <a href="https://www.youtube.com/watch?v=_q9lorDZn0Y#t=23m26">Evolve video</a> again for a longer explaination of how this works but essentially we are now naming our various <code>&lt;item /&gt;</code> elements with an id so that we can reference them for animation in <code>&lt;transition /&gt;</code> blocks.</p>

<p>Inside the transition, you’ll find our <a href="http://blog.neteril.org/blog/2014/11/11/animating-to-infinity/">known companion</a> <code>AnimatedVectorDrawable</code> referencing this object animator definition:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="c">&lt;!-- Resource\anim\play_pause.xml --&gt;</span>
</span><span class="line"><span class="nt">&lt;objectAnimator</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:duration=</span><span class="s">&quot;250&quot;</span>
</span><span class="line">	<span class="na">android:propertyName=</span><span class="s">&quot;pathData&quot;</span>
</span><span class="line">	<span class="na">android:valueFrom=</span><span class="s">&quot;@string/play_vector_path&quot;</span>
</span><span class="line">	<span class="na">android:valueTo=</span><span class="s">&quot;@string/pause_vector_path&quot;</span>
</span><span class="line">	<span class="na">android:valueType=</span><span class="s">&quot;pathType&quot;</span> <span class="nt">/&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Key aspect is the <code>valueType</code> attribute that is set to <code>pathType</code> (the only actual way to can reference the non-public <code>PathDataEvaluator</code> class) and the property name set to <code>pathData</code> to change the corresponding member in the vector drawable. For the rest, you can tweak this like any other animator.</p>

<p>Last piece is to show this transition in something. The default Android framework offers a <code>CheckedTextView</code> for those cases but no <code>CheckedImageButton</code> (because using <code>Checkbox</code> can in some occasions result int a bit of pain with positioning). It’s easy to implement though:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
<span class="line-number">34</span>
<span class="line-number">35</span>
<span class="line-number">36</span>
<span class="line-number">37</span>
<span class="line-number">38</span>
<span class="line-number">39</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="k">public</span> <span class="k">class</span> <span class="nc">CheckedImageButton</span> <span class="p">:</span> <span class="n">ImageButton</span><span class="p">,</span> <span class="n">ICheckable</span>
</span><span class="line"><span class="p">{</span>
</span><span class="line">	<span class="k">static</span> <span class="k">readonly</span> <span class="kt">int</span><span class="p">[]</span> <span class="n">CheckedStateSet</span> <span class="p">=</span> <span class="p">{</span>
</span><span class="line">		<span class="n">Android</span><span class="p">.</span><span class="n">Resource</span><span class="p">.</span><span class="n">Attribute</span><span class="p">.</span><span class="n">StateChecked</span>
</span><span class="line">	<span class="p">};</span>
</span><span class="line">	<span class="kt">bool</span> <span class="n">chked</span><span class="p">;</span>
</span><span class="line">
</span><span class="line">	<span class="c1">// Add standard constructors</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="k">override</span> <span class="kt">bool</span> <span class="nf">PerformClick</span> <span class="p">()</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="n">Toggle</span> <span class="p">();</span>
</span><span class="line">		<span class="k">return</span> <span class="k">base</span><span class="p">.</span><span class="n">PerformClick</span> <span class="p">();</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="k">void</span> <span class="nf">Toggle</span> <span class="p">()</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="n">Checked</span> <span class="p">=</span> <span class="p">!</span><span class="n">Checked</span><span class="p">;</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="kt">bool</span> <span class="n">Checked</span> <span class="p">{</span>
</span><span class="line">		<span class="k">get</span> <span class="p">{</span>
</span><span class="line">			<span class="k">return</span> <span class="n">chked</span><span class="p">;</span>
</span><span class="line">		<span class="p">}</span>
</span><span class="line">		<span class="k">set</span> <span class="p">{</span>
</span><span class="line">			<span class="n">chked</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span>
</span><span class="line">			<span class="n">RefreshDrawableState</span> <span class="p">();</span>
</span><span class="line">			<span class="n">Invalidate</span> <span class="p">();</span>
</span><span class="line">		<span class="p">}</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line">
</span><span class="line">	<span class="k">public</span> <span class="k">override</span> <span class="kt">int</span><span class="p">[]</span> <span class="nf">OnCreateDrawableState</span> <span class="p">(</span><span class="kt">int</span> <span class="n">extraSpace</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">drawableState</span> <span class="p">=</span> <span class="k">base</span><span class="p">.</span><span class="n">OnCreateDrawableState</span> <span class="p">(</span><span class="n">extraSpace</span> <span class="p">+</span> <span class="m">1</span><span class="p">);</span>
</span><span class="line">		<span class="k">if</span> <span class="p">(</span><span class="n">Checked</span><span class="p">)</span>
</span><span class="line">			<span class="n">MergeDrawableStates</span> <span class="p">(</span><span class="n">drawableState</span><span class="p">,</span> <span class="n">CheckedStateSet</span><span class="p">);</span>
</span><span class="line">		<span class="k">return</span> <span class="n">drawableState</span><span class="p">;</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>You can use this class and simply set the <code>android:src</code> attribute to the animated state-list drawable.</p>

<p>Also don’t forget to set the <code>android:background</code> of the button to use the theme value <code>?android:selectableItemBackgroundBorderless</code> to get the nice ripple effect on touch.</p>

<p>To conclude, you can still use the keyframe approach when doing animated state-list transition if you actually want to invest the time crafting each intermediary state maybe because it does a complex movement that can’t be naively interpolated.</p>

<p>But if you don’t need to, we now have an easy, fast and cumberless way to create beautiful state transitions using vector drawables.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Animating to Infinity]]></title>
    <link href="http://blog.neteril.org/blog/2014/11/11/animating-to-infinity/"/>
    <updated>2014-11-11T19:07:12-05:00</updated>
    <id>http://blog.neteril.org/blog/2014/11/11/animating-to-infinity</id>
    <content type="html"><![CDATA[<p><a href="http://blog.neteril.org/blog/2014/11/09/scaling-to-infinity/">In my previous post</a>, I covered the basics of a new type of Android drawable introduced in Lollipop for scalable graphics.</p>

<p>In and by itself this is already a very powerful new addition. But to see what else we can do with this, let’s reuse the vector drawable example from the previous post:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="nt">&lt;vector</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:height=</span><span class="s">&quot;96dp&quot;</span>
</span><span class="line">	<span class="na">android:width=</span><span class="s">&quot;96dp&quot;</span>
</span><span class="line">	<span class="na">android:viewportHeight=</span><span class="s">&quot;48&quot;</span>
</span><span class="line">	<span class="na">android:viewportWidth=</span><span class="s">&quot;48&quot;</span> <span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;group&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;@color/black_primary&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;M12 36l17-12-17-12v24zm20-24v24h4V12h-4z&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line"><span class="nt">&lt;/vector&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>I didn’t touch on it at the time but you may have noticed that our <code>path</code> element is actually contained inside another element called a <code>group</code>.</p>

<p>For the sake of displaying vector drawable, this is not a very interesting element. Now if I paste below the list of other attributes you can set on <code>&lt;group/&gt;</code>, you should see something emerging:</p>

<dl>
	<dt>Extra group attributes</dt>
	<dd>rotation, scaleX, scaleY, translateX, translateY.</dd>
</dl>

<p>You will have surely recognized those are the same attributes we use to manipulate our <code>View</code> instances when animating them.</p>

<p>Enter, <a href="http://developer.android.com/reference/android/graphics/drawable/AnimatedVectorDrawable.html">Animated Vector Drawable</a>.</p>

<p>Animated Vector Drawables are actually more of a meta-type bridging several other pieces together much like a State List Drawable (and like the later, they also are drawables themselves).</p>

<p>Here is an example of an animated vector drawable that we will use later on (also stored in your <code>drawable</code> resource folder):</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="nt">&lt;animated-vector</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:drawable=</span><span class="s">&quot;@drawable/bluetooth_loading_vector&quot;</span> <span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;target</span>
</span><span class="line">		<span class="na">android:name=</span><span class="s">&quot;circleGroup&quot;</span>
</span><span class="line">		<span class="na">android:animation=</span><span class="s">&quot;@anim/circle_expand&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;target</span>
</span><span class="line">		<span class="na">android:name=</span><span class="s">&quot;circlePath&quot;</span>
</span><span class="line">		<span class="na">android:animation=</span><span class="s">&quot;@anim/circle_path&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line"><span class="nt">&lt;/animated-vector&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Animated Vector Drawables are declared using the <code>&lt;animated-vector/&gt;</code> element. The first thing you need to tie in is which vector drawable the animated version is going to use as a base, this is set in the <code>android:drawable</code> attribute at the top level.</p>

<p>The rest of the file contains a bunch of different <code>&lt;target/&gt;</code> elements, those are where we are going to set up which animations are ran and on what <em>part</em> of the vector drawable they will be ran.</p>

<p>But first, here is the definition of the <code>bluetooth_loading_vector</code> referenced in the animated vector:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
<span class="line-number">34</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;</span>
</span><span class="line"><span class="nt">&lt;vector</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:height=</span><span class="s">&quot;64dp&quot;</span>
</span><span class="line">	<span class="na">android:width=</span><span class="s">&quot;64dp&quot;</span>
</span><span class="line">	<span class="na">android:viewportHeight=</span><span class="s">&quot;192&quot;</span>
</span><span class="line">	<span class="na">android:viewportWidth=</span><span class="s">&quot;192&quot;</span> <span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;group&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;@color/vector_foreground_color&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;M87.3996,113.161L85.3665,112.191L85.3665,23.517L87.3996,22.5479L143.293,67.8542L87.3996,113.161ZM99.9498,84.2151L120.134,67.8542L99.9498,51.4934L99.9498,84.2151Z&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;@color/vector_foreground_color&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;M87.4147,169.459L85.3665,168.484L85.3665,79.6589L87.4147,78.684L143.277,124.071L87.4147,169.459ZM99.9498,140.484L120.15,124.071L99.9498,107.659L99.9498,140.484Z&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;@color/vector_foreground_color&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;M43.8495,129.345L103.262,81.2217L112.186,92.2392L52.7734,140.362L43.8495,129.345Z&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;@color/vector_foreground_color&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;M43.8495,62.2562L103.262,110.379L112.186,99.3616L52.7734,51.2387L43.8495,62.2562Z&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line">	<span class="nt">&lt;group</span>
</span><span class="line">		<span class="na">android:name=</span><span class="s">&quot;circleGroup&quot;</span>
</span><span class="line">		<span class="na">android:pivotX=</span><span class="s">&quot;96.0&quot;</span>
</span><span class="line">		<span class="na">android:pivotY=</span><span class="s">&quot;96.0&quot;</span>
</span><span class="line">		<span class="na">android:rotation=</span><span class="s">&quot;0&quot;</span><span class="nt">&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:name=</span><span class="s">&quot;circlePath&quot;</span>
</span><span class="line">			<span class="na">android:strokeColor=</span><span class="s">&quot;@color/vector_foreground_color&quot;</span>
</span><span class="line">			<span class="na">android:strokeWidth=</span><span class="s">&quot;16&quot;</span>
</span><span class="line">			<span class="na">android:strokeAlpha=</span><span class="s">&quot;1&quot;</span>
</span><span class="line">			<span class="na">android:trimPathEnd=</span><span class="s">&quot;0.7&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;M96,5.56405C145.946,5.56405 186.436,46.0536 186.436,96C186.436,145.946 145.946,186.436 96,186.436C46.0536,186.436 5.56405,145.946 5.56405,96C5.56405,46.0536 46.0536,5.56405 96,5.56405Z&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line"><span class="nt">&lt;/vector&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>And what it looks like when rasterized:</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/animated-vector/bluetooth_vector.png" class="center" style="width: 256px" /></p>

<p>This vector drawble is a bit longer than the previous one, but there are two main things to notice:</p>

<ul>
  <li>The drawable is arranged in two distinct groups</li>
  <li>One group and one path have a name attached, mapping back to the animated vector’s target elements</li>
</ul>

<p>The way we have layed-out and named our vector drawable means we can now directly reference the relevant parts we want to manipulate.</p>

<p>For instance in our case, we are only interested in the ring around the Bluetooth logo which is why only this piece is actually named in our vector drawable.</p>

<p>To close the loop (so to speak), here are the two animation definition files referenced by the animated vector drawable (placed each in your <code>anim</code> resource folder):</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
<span class="line-number">15</span>
<span class="line-number">16</span>
<span class="line-number">17</span>
<span class="line-number">18</span>
<span class="line-number">19</span>
<span class="line-number">20</span>
<span class="line-number">21</span>
<span class="line-number">22</span>
<span class="line-number">23</span>
<span class="line-number">24</span>
<span class="line-number">25</span>
<span class="line-number">26</span>
<span class="line-number">27</span>
<span class="line-number">28</span>
<span class="line-number">29</span>
<span class="line-number">30</span>
<span class="line-number">31</span>
<span class="line-number">32</span>
<span class="line-number">33</span>
<span class="line-number">34</span>
<span class="line-number">35</span>
<span class="line-number">36</span>
<span class="line-number">37</span>
<span class="line-number">38</span>
<span class="line-number">39</span>
<span class="line-number">40</span>
<span class="line-number">41</span>
<span class="line-number">42</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="c">&lt;!-- Resources\anim\circle_expand.xml --&gt;</span>
</span><span class="line"><span class="nt">&lt;set</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span><span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;objectAnimator</span>
</span><span class="line">		<span class="na">android:duration=</span><span class="s">&quot;@integer/loading_anim_time&quot;</span>
</span><span class="line">		<span class="na">android:propertyName=</span><span class="s">&quot;scaleX&quot;</span>
</span><span class="line">		<span class="na">android:valueFrom=</span><span class="s">&quot;1.0&quot;</span>
</span><span class="line">		<span class="na">android:valueTo=</span><span class="s">&quot;2.5&quot;</span>
</span><span class="line">		<span class="na">android:valueType=</span><span class="s">&quot;floatType&quot;</span>
</span><span class="line">		<span class="na">android:repeatCount=</span><span class="s">&quot;-1&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;objectAnimator</span>
</span><span class="line">		<span class="na">android:duration=</span><span class="s">&quot;@integer/loading_anim_time&quot;</span>
</span><span class="line">		<span class="na">android:propertyName=</span><span class="s">&quot;scaleY&quot;</span>
</span><span class="line">		<span class="na">android:valueFrom=</span><span class="s">&quot;1.0&quot;</span>
</span><span class="line">		<span class="na">android:valueTo=</span><span class="s">&quot;2.5&quot;</span>
</span><span class="line">		<span class="na">android:valueType=</span><span class="s">&quot;floatType&quot;</span>
</span><span class="line">		<span class="na">android:repeatCount=</span><span class="s">&quot;-1&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;objectAnimator</span>
</span><span class="line">		<span class="na">android:duration=</span><span class="s">&quot;@integer/loading_anim_time&quot;</span>
</span><span class="line">		<span class="na">android:propertyName=</span><span class="s">&quot;rotation&quot;</span>
</span><span class="line">		<span class="na">android:valueFrom=</span><span class="s">&quot;0&quot;</span>
</span><span class="line">		<span class="na">android:valueTo=</span><span class="s">&quot;360&quot;</span>
</span><span class="line">		<span class="na">android:valueType=</span><span class="s">&quot;floatType&quot;</span>
</span><span class="line">		<span class="na">android:repeatCount=</span><span class="s">&quot;-1&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line"><span class="nt">&lt;/set&gt;</span>
</span><span class="line">
</span><span class="line"><span class="c">&lt;!-- Resources\anim\circle_path.xml --&gt;</span>
</span><span class="line"><span class="nt">&lt;set</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span><span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;objectAnimator</span>
</span><span class="line">		<span class="na">android:duration=</span><span class="s">&quot;@integer/loading_anim_time&quot;</span>
</span><span class="line">		<span class="na">android:propertyName=</span><span class="s">&quot;trimPathEnd&quot;</span>
</span><span class="line">		<span class="na">android:valueFrom=</span><span class="s">&quot;0&quot;</span>
</span><span class="line">		<span class="na">android:valueTo=</span><span class="s">&quot;1&quot;</span>
</span><span class="line">		<span class="na">android:valueType=</span><span class="s">&quot;floatType&quot;</span>
</span><span class="line">		<span class="na">android:repeatCount=</span><span class="s">&quot;-1&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;objectAnimator</span>
</span><span class="line">		<span class="na">android:duration=</span><span class="s">&quot;@integer/loading_anim_time&quot;</span>
</span><span class="line">		<span class="na">android:propertyName=</span><span class="s">&quot;strokeAlpha&quot;</span>
</span><span class="line">		<span class="na">android:valueFrom=</span><span class="s">&quot;1&quot;</span>
</span><span class="line">		<span class="na">android:valueTo=</span><span class="s">&quot;0&quot;</span>
</span><span class="line">		<span class="na">android:valueType=</span><span class="s">&quot;floatType&quot;</span>
</span><span class="line">		<span class="na">android:repeatCount=</span><span class="s">&quot;-1&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line"><span class="nt">&lt;/set&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Since this is meant as a continous animation, we must ensure that the repeat count of each animator is <code>-1</code> (a synonym for ‘infinite’) so that the process runs forever.</p>

<p>In the remaning bits, we are simply animating a bunch of property on both the group (for transformations) and on the path (for the stroke style) like we would on a normal view.</p>

<p>The last thing to do is load the animated vector drawable into a continuously animating View, typically a <code>ProgressBar</code>:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
<span class="line-number">14</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="nt">&lt;FrameLayout</span>
</span><span class="line">    <span class="na">android:layout_width=</span><span class="s">&quot;match_parent&quot;</span>
</span><span class="line">    <span class="na">android:layout_height=</span><span class="s">&quot;wrap_content&quot;</span>
</span><span class="line">    <span class="na">android:background=</span><span class="s">&quot;?android:attr/colorPrimary&quot;</span>
</span><span class="line">    <span class="na">android:padding=</span><span class="s">&quot;48dp&quot;</span>
</span><span class="line">    <span class="na">android:clipChildren=</span><span class="s">&quot;false&quot;</span>
</span><span class="line">    <span class="na">android:clipToPadding=</span><span class="s">&quot;false&quot;</span><span class="nt">&gt;</span>
</span><span class="line">    <span class="nt">&lt;ProgressBar</span>
</span><span class="line">        <span class="na">android:indeterminate=</span><span class="s">&quot;true&quot;</span>
</span><span class="line">        <span class="na">android:indeterminateDrawable=</span><span class="s">&quot;@drawable/animated_bluetooth_loading&quot;</span>
</span><span class="line">        <span class="na">android:layout_width=</span><span class="s">&quot;wrap_content&quot;</span>
</span><span class="line">        <span class="na">android:layout_height=</span><span class="s">&quot;wrap_content&quot;</span>
</span><span class="line">        <span class="na">android:layout_gravity=</span><span class="s">&quot;center&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line"><span class="nt">&lt;/FrameLayout&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>And we arrive at this result:</p>

<video width="340" height="240" autoplay="" loop="" controls="" poster="/wp-content/uploads/animated-vector/bt_animation.png"><source src="http://blog.neteril.org/wp-content/uploads/animated-vector/bt_animation.mp4" type="video/mp4" /></video>

<p>Next up, we will see how we can apply some of this to make terrific transitions.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Scaling to Infinity]]></title>
    <link href="http://blog.neteril.org/blog/2014/11/09/scaling-to-infinity/"/>
    <updated>2014-11-09T17:54:59-05:00</updated>
    <id>http://blog.neteril.org/blog/2014/11/09/scaling-to-infinity</id>
    <content type="html"><![CDATA[<p>When I make an app, I spend my time between two worlds.</p>

<p>In the first, I produce sequences of meaningul characters for a virtual machine in your favorite IDE, <a href="http://xamarin.com/studio">Xamarin Studio</a>. In the second, I use my best friend <a href="https://inkscape.org">Inkscape</a> (and lately also <a href="https://affinity.serif.com">Affinity</a>) to help me think, iterate and produce the front face of my app.</p>

<p>The main challenge of this form of development is to find the best way to ease the content transition between both worlds.</p>

<p>In Android, what’s essentially the apocalypse of screen form-factor makes it particularily painful to work with that visual assets part of your app.</p>

<p>Where the world was happily spread between <code>ldpi</code>, <code>mdpi</code> and <code>hdpi</code> a few years back, today we just don’t know how many ‘x’ we are going to be able to fit in front of ‘hdpi’ (at the time of this writing we reached <code>xxxhdpi</code>).</p>

<p>I have actually <a href="http://blog.neteril.org/blog/2013/10/10/xamsvg-managed-svg-for-xamarin-android/">already talked</a> about this subject and, at the time, released my own library to try to tackle this issue.</p>

<p>But today we can finally rejoice as Google gave developers a blessed way to create unlimited scalable graphics with the recent release of Lollipop (or Android 5.0).</p>

<p>This new types of drawable is unoriginaly called <a href="http://developer.android.com/reference/android/graphics/drawable/VectorDrawable.html">Vector Drawables</a> and, as with any other drawable, they are natively understood by the Android toolchain which make their use as seamless as feasible (i.e. you can reference them in layouts, styles, acquire them through <code>Resources.GetDrawable</code>, …).</p>

<p>This is an example of a vector drawable (store them in your <code>Resources/drawable</code> folder):</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;</span>
</span><span class="line"><span class="nt">&lt;vector</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:height=</span><span class="s">&quot;96dp&quot;</span>
</span><span class="line">	<span class="na">android:width=</span><span class="s">&quot;96dp&quot;</span>
</span><span class="line">	<span class="na">android:viewportHeight=</span><span class="s">&quot;48&quot;</span>
</span><span class="line">	<span class="na">android:viewportWidth=</span><span class="s">&quot;48&quot;</span> <span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;group&gt;</span>
</span><span class="line">		<span class="nt">&lt;path</span>
</span><span class="line">			<span class="na">android:fillColor=</span><span class="s">&quot;@color/black_primary&quot;</span>
</span><span class="line">			<span class="na">android:pathData=</span><span class="s">&quot;M12 36l17-12-17-12v24zm20-24v24h4V12h-4z&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line">	<span class="nt">&lt;/group&gt;</span>
</span><span class="line"><span class="nt">&lt;/vector&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Which draws this well known media player action icon:</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/ic_skip_next.png" class="center" /></p>

<p>The beef of a vector drawable is in its various <code>&lt;path/&gt;</code> elements and more precisely its <code>pathData</code> attribute. As arcane as it may look, it actually defines the full blown shape of the icon in the very concise <a href="www.w3.org/TR/SVG/paths.html">SVG Path data</a> format.</p>

<p>Don’t worry too much though, you won’t have to write that down by yourself (you may need to tweak it though for more funky things but more on that in a later post).</p>

<p>Since it’s based on the same specification than used in SVG itself, as long as you can grab a SVG version of your graphic you will directly be able to copy and paste it into a vector drawable XML.</p>

<p>As a matter of fact, the icon example that I pasted above came from Google’s official <a href="http://www.google.com/design/spec/resources/sticker-sheets-icons.html#sticker-sheets-icons-components">material design icon pack</a> which also contains SVG for every icon:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="nt">&lt;svg</span> <span class="na">xmlns=</span><span class="s">&quot;http://www.w3.org/2000/svg&quot;</span> <span class="na">width=</span><span class="s">&quot;48&quot;</span> <span class="na">height=</span><span class="s">&quot;48&quot;</span> <span class="na">viewBox=</span><span class="s">&quot;0 0 48 48&quot;</span><span class="nt">&gt;</span>
</span><span class="line">    <span class="nt">&lt;path</span> <span class="na">d=</span><span class="s">&quot;M12 36l17-12-17-12v24zm20-24v24h4V12h-4z&quot;</span><span class="nt">/&gt;</span>
</span><span class="line"><span class="nt">&lt;/svg&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>Notice also how the <code>viewportHeight</code> and <code>viewportWidth</code> values in the vector drawable reflect what’s in the width/height/viewBox parameter of the SVG. As long as those values are correctly defined, you can play with the <code>android:width</code> and <code>android:height</code> part of your drawable the way you want.</p>

<p>Together with the new general <a href="http://developer.android.com/training/material/drawables.html#DrawableTint">tinting facility</a> in Lollipop, you can now iterate over your assets even faster without leaving your IDE and without having to re-generate 6 variants of your graphics.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Ada Lovelace Day 2014]]></title>
    <link href="http://blog.neteril.org/blog/2014/10/14/ada-lovelace-day-2014/"/>
    <updated>2014-10-14T00:01:30-04:00</updated>
    <id>http://blog.neteril.org/blog/2014/10/14/ada-lovelace-day-2014</id>
    <content type="html"><![CDATA[<p>Today is <a href="http://findingada.com/">Ada Lovelace day</a>, a special occasion to recognize women in our community. I want to take this opportunity to also highlight someone exceptional I have known for a while.</p>

<p>Her name is <a href="https://twitter.com/silverspoon">Andrea Magnorsky</a>.</p>

<p><img alt="Andrea Magnorsky" class="raw" src="http://blog.neteril.org/wp-content/uploads/andrea.jpg" style="display: block; margin: auto; width: 208px; height: 208px; border-radius: 50%;" /></p>

<p>Andrea is an Irish .NET programmer. She’s currently following one of her passion – game development – and is closing production with her studio <a href="http://www.digitalfurnacegames.com/">Digital Furnace</a> (ex-BatCat) on their next title Onikira.</p>

<p>To say that Andrea is a community person is an understatement. In the span of a few years she has not only created popular event/group like <a href="http://dublingamecraft.com/">Global Gamecraft</a> (game jam contest) or Dublin ALT.NET but she is also continously looking for new ways to teach people through numerous talks and meetups like <a href="http://www.meetup.com/FunctionalKats/">Functional Kats</a>.</p>

<p>She is curious of everything and always avid to learn. These days you can see her sailing along with F# and functional programming for instance.</p>

<p>It’s no surprise that she was recognized <a href="http://technologyvoice.com/2012/10/05/another-talented-38-more-of-irelands-top-technology-and-startup-leaders">several</a> <a href="http://www.siliconrepublic.com/careers/item/37203-wit2014">times</a> in Ireland as a top person in her field. Microsoft also recently <a href="http://mvp.microsoft.com/en-us/mvp/Andrea%20Magnorsky-5001102">awarded her an MVP award</a>.</p>

<p>It’s thanks to people like Andrea that I’m happy to be part of the community that is software development.</p>

<p><img alt="Muncho" class="raw" src="http://blog.neteril.org/wp-content/uploads/muncho.jpg" style="display: block; margin: auto; width: 166px; height: 166px; border-radius: 50%;" /></p>

<p align="center" style="font-size: 80%;"><em>Muncho would have loved to conclude this but he had another emergency</em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A Tale of Connected Dots]]></title>
    <link href="http://blog.neteril.org/blog/2014/10/12/a-tale-of-connected-dots/"/>
    <updated>2014-10-12T10:44:16-04:00</updated>
    <id>http://blog.neteril.org/blog/2014/10/12/a-tale-of-connected-dots</id>
    <content type="html"><![CDATA[<p>This past week, we organized <a href="https://evolve.xamarin.com/">Evolve 2014</a> in Atlanta to talk about all things mobile with Xamarin.</p>

<p>Being a mobile conference, we of course made <a href="http://www.windowsphone.com/en-us/store/app/xamarin-evolve/72f908df-63b6-4a86-b9dc-2ae0781722da">our</a> <a href="https://itunes.apple.com/SI/app/id618319027?mt=8&amp;ign-mpt=uo%3D4">own</a> <a href="https://play.google.com/store/apps/details?id=com.xamarin.xamarinevolve">app</a> so that attendees could track out the sessions and the geography of the event.</p>

<p>We also launched something a bit different in the form of a treasure hunt app. Thanks to <a href="http://estimote.com/">Estimote</a>, we used a combination of iBeacon and QR codes spread throughout the conference intertwined with challenges along the way until you reach the end of the quest and a special prize.</p>

<p>The main interface of that quest app is a serie of connected dots:</p>

<p><img alt="Evolve Quest screenshot" class="center" src="http://blog.neteril.org/wp-content/uploads/evolvequest/dotsscreen2.png" /></p>

<p>As you progress through the game, the content scrolls naturally to reveal more odd-shaped arrangement of those dots.</p>

<p>Originally, this screen was just a big tall image containing everything. This is suboptimal on Android for a couple of reason like some graphic chip not supporting big “texture” or simply the need to rescale at runtime on most screen.</p>

<p>Ultimately it’s also not fun because there is really nothing you can do with a big image.</p>

<p><em>Hint:</em> this is NOT what we shipped (on Android at least).</p>

<p>Rather, what attendees could see on their Android phone at the conference was this:</p>

<video width="270" height="480" autoplay="" loop="" controls="" poster="/wp-content/uploads/evolvequest/questdots.png"><source src="http://blog.neteril.org/wp-content/uploads/evolvequest/questdots.mp4" type="video/mp4" /></video>

<p>A much more satisfying, softly animated, connected system of dots. The current game position is also highlighted with a discrete pulse.</p>

<p>We will open-source the entire Quest application at some point but I wanted to share how we did that specific bit that is entirely exclusive to Android.</p>

<p>▸ <a href="https://gist.github.com/garuma/3de89edd4055854625e0">View Source Code</a></p>

<p>Since this is a really custom animation, it’s a bit different than the other type of animation samples I have already shown.</p>

<p>For this type of thing, I usually rely on a very simple animator that gives me a floating value between 0 and 1 so that I can do my own tweening in code. I also manage to pass this value by hijacking one of the standard view animatable property so that I don’t need to expose more information to the Java bridge:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
<span class="line-number">12</span>
<span class="line-number">13</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="c1">// Interpolator instantiation</span>
</span><span class="line"><span class="n">shiverAnimator</span> <span class="p">=</span> <span class="n">ObjectAnimator</span><span class="p">.</span><span class="n">OfFloat</span> <span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="s">&quot;scaleX&quot;</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">1</span><span class="p">);</span>
</span><span class="line"><span class="n">shiverAnimator</span><span class="p">.</span><span class="n">RepeatCount</span> <span class="p">=</span> <span class="n">ValueAnimator</span><span class="p">.</span><span class="n">Infinite</span><span class="p">;</span>
</span><span class="line"><span class="n">shiverAnimator</span><span class="p">.</span><span class="n">AnimationRepeat</span> <span class="p">+=</span> <span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="n">e</span><span class="p">)</span> <span class="p">=&gt;</span> <span class="n">shiverIndex</span><span class="p">++;</span>
</span><span class="line">
</span><span class="line"><span class="c1">// Property hijack</span>
</span><span class="line"><span class="k">public</span> <span class="k">override</span> <span class="kt">float</span> <span class="n">ScaleX</span> <span class="p">{</span>
</span><span class="line">	<span class="k">get</span> <span class="p">{</span> <span class="k">return</span> <span class="n">currentShiverInterpolation</span><span class="p">;</span> <span class="p">}</span>
</span><span class="line">	<span class="k">set</span> <span class="p">{</span>
</span><span class="line">		<span class="n">currentShiverInterpolation</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span>
</span><span class="line">		<span class="n">Invalidate</span> <span class="p">();</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>In our case, I then use this value to compute for each drawing pass an offset that is added to the base position of every dots:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="c1">// Expressed in dp units</span>
</span><span class="line"><span class="kt">int</span><span class="p">[]</span> <span class="n">shiverOffsets</span> <span class="p">=</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="m">9</span><span class="p">,</span> <span class="m">3</span><span class="p">,</span> <span class="p">-</span><span class="m">8</span><span class="p">,</span> <span class="m">4</span><span class="p">,</span> <span class="p">-</span><span class="m">7</span><span class="p">,</span> <span class="m">6</span> <span class="p">};</span>
</span><span class="line">
</span><span class="line"><span class="c1">// Extra applied offset code</span>
</span><span class="line"><span class="kt">int</span> <span class="nf">ApplyShivering</span> <span class="p">(</span><span class="kt">int</span> <span class="n">dotIndex</span><span class="p">,</span> <span class="kt">int</span> <span class="k">value</span><span class="p">)</span>
</span><span class="line"><span class="p">{</span>
</span><span class="line">	<span class="kt">var</span> <span class="n">off</span> <span class="p">=</span> <span class="n">shiverOffsets</span> <span class="p">[(</span><span class="n">dotIndex</span> <span class="p">+</span> <span class="n">shiverIndex</span><span class="p">)</span> <span class="p">%</span> <span class="n">shiverOffsets</span><span class="p">.</span><span class="n">Length</span><span class="p">]</span>
</span><span class="line">		<span class="p">*</span> <span class="n">currentShiverInterpolation</span><span class="p">;</span>
</span><span class="line">	<span class="k">value</span> <span class="p">+=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">Math</span><span class="p">.</span><span class="n">Round</span> <span class="p">(</span><span class="n">off</span><span class="p">);</span>
</span><span class="line">	<span class="k">return</span> <span class="k">value</span><span class="p">;</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>The wave that you see on the highlighted pin comes from a <code>GradientDrawable</code> that I create from a shape drawable XML definition as follow:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
</pre></td><td class="code"><pre><code class="xml"><span class="line"><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
</span><span class="line"><span class="nt">&lt;shape</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
</span><span class="line">	<span class="na">android:shape=</span><span class="s">&quot;ring&quot;</span>
</span><span class="line">	<span class="na">android:useLevel=</span><span class="s">&quot;false&quot;</span>
</span><span class="line">	<span class="na">android:innerRadiusRatio=</span><span class="s">&quot;2&quot;</span><span class="nt">&gt;</span>
</span><span class="line">	<span class="nt">&lt;solid</span> <span class="na">android:color=</span><span class="s">&quot;#99ffffff&quot;</span> <span class="nt">/&gt;</span>
</span><span class="line"><span class="nt">&lt;/shape&gt;</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>The reason for using a drawable like this is to avoid redoing common drawing code and also taking advantage of the ring shape type automatic radius scaling (notice the <code>innerRadiusRatio</code> attribute) to create a nice spreading effect as the ring grows larger.</p>

<p>The ring size and color is dynamically computed from a slightly interpolated (quadratic or accelerated) value coming from our shared shiver interpolator:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
<span class="line-number">9</span>
<span class="line-number">10</span>
<span class="line-number">11</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="kt">var</span> <span class="n">dur</span> <span class="p">=</span> <span class="n">shiverAnimator</span><span class="p">.</span><span class="n">Duration</span> <span class="p">/</span> <span class="m">4</span><span class="p">;</span>
</span><span class="line"><span class="kt">var</span> <span class="n">fraction</span> <span class="p">=</span> <span class="p">(</span><span class="kt">float</span><span class="p">)(</span><span class="n">shiverAnimator</span><span class="p">.</span><span class="n">CurrentPlayTime</span> <span class="p">%</span> <span class="n">dur</span><span class="p">)</span> <span class="p">/</span> <span class="n">dur</span><span class="p">;</span>
</span><span class="line"><span class="c1">// Cheap interpolation</span>
</span><span class="line"><span class="n">fraction</span> <span class="p">*=</span> <span class="n">fraction</span><span class="p">;</span>
</span><span class="line">
</span><span class="line"><span class="kt">var</span> <span class="n">rippleRad</span> <span class="p">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)(</span><span class="n">radius</span> <span class="p">*</span> <span class="p">(</span><span class="m">5</span> <span class="p">*</span> <span class="n">fraction</span> <span class="p">+</span> <span class="m">1</span><span class="p">))</span> <span class="p">-</span> <span class="m">8</span><span class="p">;</span>
</span><span class="line"><span class="n">ripple</span><span class="p">.</span><span class="n">SetBounds</span> <span class="p">(</span><span class="n">x</span> <span class="p">-</span> <span class="n">rippleRad</span><span class="p">,</span> <span class="n">y</span> <span class="p">-</span> <span class="n">rippleRad</span><span class="p">,</span> <span class="n">x</span> <span class="p">+</span> <span class="n">rippleRad</span><span class="p">,</span> <span class="n">y</span> <span class="p">+</span> <span class="n">rippleRad</span><span class="p">);</span>
</span><span class="line">
</span><span class="line"><span class="kt">var</span> <span class="n">color</span> <span class="p">=</span> <span class="n">Color</span><span class="p">.</span><span class="n">Argb</span> <span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="n">Math</span><span class="p">.</span><span class="n">Round</span> <span class="p">(</span><span class="m">0</span><span class="n">x99</span> <span class="p">*</span> <span class="p">(</span><span class="m">1</span> <span class="p">-</span> <span class="n">fraction</span><span class="p">)),</span>
</span><span class="line">                        <span class="m">0</span><span class="n">xFF</span><span class="p">,</span> <span class="m">0</span><span class="n">xFF</span><span class="p">,</span> <span class="m">0</span><span class="n">xFF</span><span class="p">);</span>
</span><span class="line"><span class="p">((</span><span class="n">GradientDrawable</span><span class="p">)</span><span class="n">ripple</span><span class="p">).</span><span class="n">SetColor</span> <span class="p">(</span><span class="n">color</span><span class="p">.</span><span class="n">ToArgb</span> <span class="p">());</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>If you have been to my Mastering Time and Space session, you’ll likely also have detected the presence of a custom interpolator in there that is set on the shared shivering animator. The code is following:</p>

<div class="bogus-wrapper"><notextile><figure class="code"><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
<span class="line-number">7</span>
<span class="line-number">8</span>
</pre></td><td class="code"><pre><code class="csharp"><span class="line"><span class="k">class</span> <span class="nc">TriangleWave</span> <span class="p">:</span> <span class="n">Java</span><span class="p">.</span><span class="n">Lang</span><span class="p">.</span><span class="n">Object</span><span class="p">,</span> <span class="n">ITimeInterpolator</span>
</span><span class="line"><span class="p">{</span>
</span><span class="line">	<span class="k">public</span> <span class="kt">float</span> <span class="nf">GetInterpolation</span> <span class="p">(</span><span class="kt">float</span> <span class="n">input</span><span class="p">)</span>
</span><span class="line">	<span class="p">{</span>
</span><span class="line">		<span class="kt">var</span> <span class="n">t</span> <span class="p">=</span> <span class="n">input</span> <span class="p">*</span> <span class="m">2</span><span class="p">;</span>
</span><span class="line">		<span class="k">return</span> <span class="p">(</span><span class="kt">float</span><span class="p">)(</span><span class="m">2</span> <span class="p">*</span> <span class="n">Math</span><span class="p">.</span><span class="n">Abs</span> <span class="p">(</span><span class="n">t</span> <span class="p">-</span> <span class="n">Math</span><span class="p">.</span><span class="n">Floor</span> <span class="p">(</span><span class="n">t</span> <span class="p">+</span> <span class="m">0.5</span><span class="p">))</span> <span class="p">*</span> <span class="p">(</span><span class="m">1</span> <span class="p">-</span> <span class="m">2</span> <span class="p">*</span> <span class="n">Math</span><span class="p">.</span><span class="n">Floor</span> <span class="p">(</span><span class="n">t</span><span class="p">)));</span>
</span><span class="line">	<span class="p">}</span>
</span><span class="line"><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure></notextile></div>

<p>This interpolator generates a triangle pattern that is repeatable (i.e. it both starts and ends at the same position for the dot) so that the animation can run continuously:</p>

<p><img alt="Triangle curve" class="raw" src="http://blog.neteril.org/wp-content/uploads/evolvequest/trianglecurve.png" style="display: block;margin: auto" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Wear support in Moyeu]]></title>
    <link href="http://blog.neteril.org/blog/2014/09/24/wear-support-in-moyeu/"/>
    <updated>2014-09-24T09:02:46-04:00</updated>
    <id>http://blog.neteril.org/blog/2014/09/24/wear-support-in-moyeu</id>
    <content type="html"><![CDATA[<p><img src="http://blog.neteril.org/wp-content/uploads/moyeu_wear.png" alt="Final Setup" class="center" /></p>

<p>I just officially added Android Wear support in the shipped version of <a href="http://moyeuapp.net/">Moyeu</a>, my Hubway (Boston’s bike sharing system) app for Android.</p>

<p>As usual, the code is available in <a href="https://github.com/garuma/Moyeu/tree/master/MoyeuWear">my GitHub repository</a> and you can grab it <a href="https://play.google.com/store/apps/details?id=org.neteril.Moyeu">from Google Play</a>.</p>

<p>It’s an example of what’s possible to achieve today with our <a href="http://blog.xamarin.com/tips-for-your-first-android-wear-app/">Xamarin.Android Wear support</a> and Google’s <a href="http://www.nuget.org/packages/Xamarin.Android.Wear/">Wearable UI library</a>. Feel free to reuse as you see fit.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Build Your Own Continuous Integration Pole]]></title>
    <link href="http://blog.neteril.org/blog/2014/09/02/build-your-own-ci-pole/"/>
    <updated>2014-09-02T22:35:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2014/09/02/build-your-own-ci-pole</id>
    <content type="html"><![CDATA[<p>If you live in Boston and happen to walk around the Commons when evening falls, you may have noticed a strange glow coming from the top of one the building along the park:</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/pole/glow-on-the-commons.jpg" alt="A Mysterious Glow on Boston" class="center" /></p>

<p>This eerie light comes from our designer pole, an experiment I did to provide cheap feedback over our build status in our continuous integration system:</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/pole/full_pole.jpg" alt="Le Pole" class="center" /></p>

<p>The setup is based around 3 main components: a Raspberry Pi, a 5V relay module board and a basic 12V RGB LED strip. You can buy all those parts directly from Amazon for about $112 total (of which $77 was for a premium Raspberry Pi package but it’s up to you).</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/pole/setup.jpg" alt="Setup" /></p>

<p>No matter the RGB LED strip “brand” you end up buying (it all seems to be from the same generic supplier), the wiring is pretty simple and consist of a common ground and a wire for each color channel (red, green, blue) so 4 wires in total.</p>

<p>Thus in the simplest form we can very easily turn on and off those channels using a bunch of relays. Each build status (success, test failure and build failure) will be mapped to a specific color (green, blue, red respectively).</p>

<p>A relay is the basic building block to control a power circuit (the 12V DC from the LED strip power adapter) from a control circuit (the 3.3V DC of the Raspberry Pi). There are a bunch of different designs available (magnetic, solid state, …) depending on the amount of power you are controlling. For this type of setup pretty much anything should work (it’s just LEDs after all).</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/pole/relays.jpg" alt="A relay module" class="center" /></p>

<p>Those relays are then mounted on a board like the one in the picture to conveniently expose a control interface that you can plug to your Raspberry Pi GPIO ports. That’s the final product you can buy (unless you want to do your own PCB).</p>

<p>Below is a close-up of the wiring between all the different pieces, the GPIO ports are exported to the breadboard and then connected onto the relay module control circuit.</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/pole/close-up.jpg" alt="Close-up wiring" class="center" /></p>

<p>I also made a more schematic version so that you can see which GPIO ports are used:</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/pole/wiring.png" alt="Wiring schema" class="center" /></p>

<p>The common of the LED strip (the white cable) is connected directly to the power source (we don’t care about controlling it). All the other color wires go in and out of their own relay.</p>

<p>If you are short on connectors, you may have noticed a little trick I use which is to go scavenge your old computers for IDE connectors (what you used to plug your old harddrive, floppy disk readers and the likes). They fit perfectly well and have the same type of wire that standard Dupont cables.</p>

<p>Below is the part of the code that controls the relay module to turn on and off the LEDs:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Threading</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">RaspberryPiDotNet</span><span class="p">;</span>

<span class="k">namespace</span> <span class="nn">WrenchBerry</span>
<span class="p">{</span>
	<span class="k">public</span> <span class="k">static</span> <span class="k">class</span> <span class="nc">Ledder</span>
	<span class="p">{</span>
		<span class="k">public</span> <span class="k">enum</span> <span class="n">Color</span> <span class="p">{</span>
			<span class="n">Green</span><span class="p">,</span>
			<span class="n">Orange</span><span class="p">,</span>
			<span class="n">Red</span>
		<span class="p">}</span>

		<span class="k">static</span> <span class="n">GPIOPins</span><span class="p">[]</span> <span class="n">pinMapping</span> <span class="p">=</span> <span class="k">new</span> <span class="n">GPIOPins</span><span class="p">[]</span> <span class="p">{</span>
			<span class="n">GPIOPins</span><span class="p">.</span><span class="n">V2_GPIO_17</span><span class="p">,</span>
			<span class="n">GPIOPins</span><span class="p">.</span><span class="n">V2_GPIO_27</span><span class="p">,</span>
			<span class="n">GPIOPins</span><span class="p">.</span><span class="n">V2_GPIO_22</span><span class="p">,</span>
		<span class="p">};</span>

		<span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">FlashLed</span> <span class="p">(</span><span class="n">Color</span> <span class="n">color</span><span class="p">,</span> <span class="kt">int</span> <span class="n">times</span> <span class="p">=</span> <span class="m">3</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="kt">var</span> <span class="n">pin</span> <span class="p">=</span> <span class="n">pinMapping</span> <span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">color</span><span class="p">];</span>
			<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">times</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span> <span class="p">{</span>
				<span class="n">GPIO</span><span class="p">.</span><span class="n">Write</span> <span class="p">(</span><span class="n">pin</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
				<span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span> <span class="p">(</span><span class="m">500</span><span class="p">);</span>
				<span class="n">GPIO</span><span class="p">.</span><span class="n">Write</span> <span class="p">(</span><span class="n">pin</span><span class="p">,</span> <span class="k">false</span><span class="p">);</span>
				<span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span> <span class="p">(</span><span class="m">500</span><span class="p">);</span>
			<span class="p">}</span>
		<span class="p">}</span>

		<span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">TurnOn</span> <span class="p">(</span><span class="n">Color</span> <span class="n">color</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="kt">var</span> <span class="n">pin</span> <span class="p">=</span> <span class="n">pinMapping</span> <span class="p">[(</span><span class="kt">int</span><span class="p">)</span><span class="n">color</span><span class="p">];</span>
			<span class="n">GPIO</span><span class="p">.</span><span class="n">Write</span> <span class="p">(</span><span class="n">pin</span><span class="p">,</span> <span class="k">false</span><span class="p">);</span>
		<span class="p">}</span>

		<span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">TurnAllColorOff</span> <span class="p">()</span>
		<span class="p">{</span>
			<span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">pin</span> <span class="k">in</span> <span class="n">pinMapping</span><span class="p">)</span>
				<span class="n">GPIO</span><span class="p">.</span><span class="n">Write</span> <span class="p">(</span><span class="n">pin</span><span class="p">,</span> <span class="k">true</span><span class="p">);</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre></div>

<p>The code use the <a href="https://github.com/cypherkey/RaspberryPi.Net/">RaspberryPi.Net</a> library to directly access the chip memory controlling the GPIO pins.</p>

<p>The main program is then a super-simplistic infinite loop over the CI results:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.IO</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">System.Linq</span><span class="p">;</span>

<span class="k">namespace</span> <span class="nn">WrenchBerry</span>
<span class="p">{</span>
	<span class="k">class</span> <span class="nc">MainClass</span>
	<span class="p">{</span>
		<span class="k">const</span> <span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span> <span class="n">NoColor</span> <span class="p">=</span> <span class="p">(</span><span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span><span class="p">)(-</span><span class="m">1</span><span class="p">);</span>
		<span class="k">static</span> <span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span> <span class="n">currentColor</span> <span class="p">=</span> <span class="n">NoColor</span><span class="p">;</span>

		<span class="k">public</span> <span class="k">static</span> <span class="k">void</span> <span class="nf">Main</span> <span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="kt">var</span> <span class="n">lane</span> <span class="p">=</span> <span class="n">args</span> <span class="p">[</span><span class="m">0</span><span class="p">];</span>

			<span class="k">while</span> <span class="p">(</span><span class="k">true</span><span class="p">)</span> <span class="p">{</span>
				<span class="k">try</span> <span class="p">{</span>
					<span class="kt">var</span> <span class="n">builds</span> <span class="p">=</span> <span class="n">CISystem</span><span class="p">.</span><span class="n">GetStateListFromLane</span> <span class="p">(</span><span class="n">lane</span><span class="p">);</span>
					<span class="k">if</span> <span class="p">(</span><span class="n">builds</span> <span class="p">==</span> <span class="k">null</span> <span class="p">||</span> <span class="n">builds</span><span class="p">.</span><span class="n">Length</span> <span class="p">==</span> <span class="m">0</span> <span class="p">||</span> <span class="p">!</span><span class="n">builds</span><span class="p">.</span><span class="n">Any</span> <span class="p">(</span><span class="n">IsFinishedState</span><span class="p">))</span> <span class="p">{</span>
					    <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span> <span class="p">(</span><span class="s">&quot;Lane or fetching is fucked up&quot;</span><span class="p">);</span>
					    <span class="k">return</span><span class="p">;</span>
					<span class="p">}</span>
					<span class="kt">var</span> <span class="n">firstBuilt</span> <span class="p">=</span> <span class="n">builds</span><span class="p">.</span><span class="n">First</span> <span class="p">(</span><span class="n">IsFinishedState</span><span class="p">);</span>
					<span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span> <span class="p">(</span><span class="n">DateTime</span><span class="p">.</span><span class="n">Now</span><span class="p">.</span><span class="n">ToString</span> <span class="p">(</span><span class="s">&quot;u&quot;</span><span class="p">)</span> <span class="p">+</span> <span class="s">&quot; - &quot;</span> <span class="p">+</span> <span class="n">firstBuilt</span><span class="p">);</span>

					<span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span> <span class="n">color</span> <span class="p">=</span> <span class="n">GetColorForState</span> <span class="p">(</span><span class="n">firstBuilt</span><span class="p">);</span>

					<span class="k">if</span> <span class="p">(</span><span class="n">color</span> <span class="p">!=</span> <span class="n">NoColor</span> <span class="p">&amp;&amp;</span> <span class="n">currentColor</span> <span class="p">!=</span> <span class="n">color</span><span class="p">)</span> <span class="p">{</span>
					    <span class="n">Ledder</span><span class="p">.</span><span class="n">TurnAllColorOff</span> <span class="p">();</span>
					    <span class="n">Ledder</span><span class="p">.</span><span class="n">FlashLed</span> <span class="p">(</span><span class="n">color</span><span class="p">);</span>
					    <span class="n">Ledder</span><span class="p">.</span><span class="n">TurnOn</span> <span class="p">(</span><span class="n">color</span><span class="p">);</span>
					<span class="p">}</span>
					<span class="n">currentColor</span> <span class="p">=</span> <span class="n">color</span><span class="p">;</span>
				<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="n">Exception</span> <span class="n">e</span><span class="p">)</span> <span class="p">{</span>
					<span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span> <span class="p">(</span><span class="n">e</span><span class="p">);</span>
				<span class="p">}</span>

				<span class="n">System</span><span class="p">.</span><span class="n">Threading</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Sleep</span> <span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="n">TimeSpan</span><span class="p">.</span><span class="n">FromMinutes</span> <span class="p">(</span><span class="m">2</span><span class="p">).</span><span class="n">TotalMilliseconds</span><span class="p">);</span>
			<span class="p">}</span>
		<span class="p">}</span>

		<span class="k">static</span> <span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span> <span class="n">GetColorForState</span> <span class="p">(</span><span class="n">DBState</span> <span class="n">state</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span> <span class="n">color</span> <span class="p">=</span> <span class="n">NoColor</span><span class="p">;</span>
			<span class="k">switch</span> <span class="p">(</span><span class="n">state</span><span class="p">)</span> <span class="p">{</span>
			<span class="k">case</span> <span class="n">DBState</span><span class="p">.</span><span class="n">Failed</span><span class="p">:</span>
				<span class="n">color</span> <span class="p">=</span> <span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span><span class="p">.</span><span class="n">Red</span><span class="p">;</span>
				<span class="k">break</span><span class="p">;</span>
			<span class="k">case</span> <span class="n">DBState</span><span class="p">.</span><span class="n">Issues</span><span class="p">:</span>
				<span class="n">color</span> <span class="p">=</span> <span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span><span class="p">.</span><span class="n">Orange</span><span class="p">;</span>
				<span class="k">break</span><span class="p">;</span>
			<span class="k">case</span> <span class="n">DBState</span><span class="p">.</span><span class="n">Success</span><span class="p">:</span>
				<span class="n">color</span> <span class="p">=</span> <span class="n">Ledder</span><span class="p">.</span><span class="n">Color</span><span class="p">.</span><span class="n">Green</span><span class="p">;</span>
				<span class="k">break</span><span class="p">;</span>
			<span class="p">}</span>
			<span class="k">return</span> <span class="n">color</span><span class="p">;</span>
		<span class="p">}</span>

		<span class="k">static</span> <span class="kt">bool</span> <span class="nf">IsFinishedState</span> <span class="p">(</span><span class="n">DBState</span> <span class="n">state</span><span class="p">)</span>
		<span class="p">{</span>
			<span class="k">return</span> <span class="n">state</span> <span class="p">==</span> <span class="n">DBState</span><span class="p">.</span><span class="n">Failed</span> <span class="p">||</span> <span class="n">state</span> <span class="p">==</span> <span class="n">DBState</span><span class="p">.</span><span class="n">Issues</span> <span class="p">||</span> <span class="n">state</span> <span class="p">==</span> <span class="n">DBState</span><span class="p">.</span><span class="n">Success</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre></div>

<p>All that’s left to do is to make yourself a nice little storage area and, why not, spice up the system a little bit. For instance in our setup (pictured below) I also hooked up a small speaker.</p>

<p><img src="http://blog.neteril.org/wp-content/uploads/pole/final_setup.jpg" alt="Final Setup" class="center" /></p>

<p>As an example our current playlist consist of: the Imperial March (build failure), Mass Effect Reaper sound (test failure) and, last but not least, <a href="https://www.youtube.com/watch?v=eh7lp9umG2I">our friend He-Man</a> (build success).</p>

<p>Happy (hardware) hacking!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Scrolling-based effects in Android UI]]></title>
    <link href="http://blog.neteril.org/blog/2014/06/05/scrolling-based-effects-in-android-ui/"/>
    <updated>2014-06-05T13:35:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2014/06/05/scrolling-based-effects-in-android-ui</id>
    <content type="html"><![CDATA[<p>Scrolling is a central behavior of a lot of common elements in Android UIs with widgets like <code>ScrollView</code>, <code>ViewPager</code> or <code>ListView</code>.</p>

<p>It also has the nice property that, knowing the scroll extents, it’s very easy to infer a floating ratio (i.e. a value between 0 and 1) from a given intermediary scroll state.</p>

<p>This last property makes scrolling very similar to animations, replacing the need for a time-based interpolator by this scroll-state inferred value.</p>

<p>In addition, since scroll events are generally triggered in response to a continuous user action, those intermediates values can be used to implement nifty navigation effects.</p>

<p>I have already talked about one of such effect earlier, <a href="http://blog.neteril.org/blog/2014/01/02/using-parallax-for-fun-and-profit/">the infamous parallax</a>, that a lot of people are already using but there is much more opportunities around.</p>

<p>In the last release of my pet app <a href="http://bikrapp.net/">Bikr</a> for instance, I added a new statistics screen:</p>

<p align="center"><img class="raw" src="http://blog.neteril.org/wp-content/uploads/scrolling-effects/stats_framed_small2.png" alt="Stats screen" width="338" /></p>

<p>As is common in Android land, the navigation is implemented using <code>ActionBar</code>’s tabs at the top of the screen. This is coupled with a <code>ViewPager</code> instance as the root fragment layout so that screens can be accessed both by swiping and by tabs selection.</p>

<p>The statistics panel itself consists of a subclass of <code>ScrollView</code> that snaps to each of its subsection scroll offset to display multiple sub-pages.</p>

<p>Since both of those elements can generate scroll states, the rest of the UI take advantage of it by dynamically refreshing itself based on those value changes.</p>

<p>For the <code>ViewPager</code> for example, the tab icons are progressively made more transparent or opaque. The overall gradient background is also subtly inverted to influence the reading direction of the user upwards instead of downwards:</p>

<video autoplay="true" muted="true" loop="true" width="300">
  <source src="http://blog.neteril.org/wp-content/uploads/scrolling-effects/viewpager-transition.webm" type="video/webm" />
  <source src="http://blog.neteril.org/wp-content/uploads/scrolling-effects/viewpager-transition.mp4" type="video/mp4" />
</video>

<p align="center"><a href="https://github.com/garuma/bikr/blob/master/Bikr/MainActivity.cs#L92">View Code</a></p>

<p>The scroll information of the statistics <code>ScrollView</code> is linked to a custom scrollbar knob that is aligned to the subsection title. I use the intermediary scroll values in that case to both infer the knob vertical position and dynamically adjust its size:</p>

<video autoplay="true" muted="true" loop="true" width="300">
  <source src="http://blog.neteril.org/wp-content/uploads/scrolling-effects/scrollview-transition.webm" type="video/webm" />
  <source src="http://blog.neteril.org/wp-content/uploads/scrolling-effects/scrollview-transition.mp4" type="video/mp4" />
</video>

<p align="center">View Code: <a href="https://github.com/garuma/bikr/blob/master/Bikr/Views/SnapScrollView.cs#L111">Event</a> - <a href="https://github.com/garuma/bikr/blob/master/Bikr/Views/ScrollBarExtraordinaire.cs#L208">Drawing</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bikr, the fun UI parts]]></title>
    <link href="http://blog.neteril.org/blog/2014/04/25/bikr-fun-ui-parts/"/>
    <updated>2014-04-25T22:00:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2014/04/25/bikr-fun-ui-parts</id>
    <content type="html"><![CDATA[<p>A couple of days ago, <a href="http://blog.neteril.org/blog/2014/04/22/bikr-delicious-ride-tracker/">I released Bikr</a> my new Android app to effortlessly track your bicycle rides.</p>

<p>Right from the start the development motto was that the app should be as simple and straightforward as the problem it solves: keeping track of users rides without needing their input.</p>

<p>This lead to a very clean UI with no apparent settings and interaction requirements kept to a bare minimum while still making it a delightful experience.</p>

<p>In the rest of this post I’m going to show you some UI tidbits that got implemented in Bikr as a result.</p>

<h2 id="on-boarding">On-boarding</h2>

<p>▸ <a href="https://github.com/garuma/bikr/blob/master/Bikr/MainActivity.cs#L162">View Source Code</a></p>

<p>As I mentioned in the introduction, the need for user involvement was voluntarily maintained low as the whole experience is supposed to be automatic.</p>

<p>As a matter of fact, the only actionable element of the entire main UI is the switch at the top-right of the screen that enable or disable globally the service.</p>

<p>This gave me the inspiration for this on-boarding:</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/bikr/onboarding.gif" alt="Tank Fill screencast" /></p>

<p>The idea is to overlay on top of our main UI that same switch with a short explanation text and let the user initializes himself the service before being able to proceed further.</p>

<p>The effect is implemented by using Android view caching mechanism, retrieving the composited top-most bitmap and using Renderscript to blur the image as a background much like I described <a href="http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/">in this article</a>.</p>

<h2 id="tank-filling-animation">Tank Filling Animation</h2>

<p>▸ <a href="https://github.com/garuma/bikr/blob/master/Bikr/WaveDrawable.cs#L188">View Source Code</a></p>

<p>When the app starts, each circle fills out to show you how far you are in reaching the same level than the previous day, week or month (accordingly).</p>

<p>When thinking about it I almost right away draw a parallel between this and filling a container with water.</p>

<p>This animation thus reproduce the familiar bubbling at the surface of a liquid when poured rapidly:</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/bikr/bubbles.gif" alt="Tank Fill screencast" /></p>

<p>I use a sine function to distribute the bubbles uniformly across the vertical top band of the liquid and then animate them to grow out and “burst” at the surface as they get closer to the top.</p>

<h2 id="wave-simulation">Wave Simulation</h2>

<p>▸ <a href="https://github.com/garuma/bikr/blob/master/Bikr/WaveDrawable.cs#L241">View Source Code</a></p>

<p>Although the circles are not actual actionable items, when showing the app to friends they would unconsciously reach and try to interact with them.</p>

<p>In the spirit of rewarding the user for experimentation and not unsettling them, the water analogy is continued here by implementing a simple wave simulation that generates ripples where the user is tapping.</p>

<p>I also use a nice springy touch feedback that will influence the force of the final ripple to give even more touch satisfaction:</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/bikr/wave.gif" alt="Tank Fill screencast" /></p>

<p>The simulation algorithm itself is based on <a href="http://www.matthiasmueller.info/talks/gdc2008.pdf">the work of Matthias Müller</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Bikr, delicious ride tracker]]></title>
    <link href="http://blog.neteril.org/blog/2014/04/22/bikr-delicious-ride-tracker/"/>
    <updated>2014-04-22T10:00:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2014/04/22/bikr-delicious-ride-tracker</id>
    <content type="html"><![CDATA[<p>Today I’m introducing <a href="http://bikrapp.net">Bikr</a>, a new Android application to track your bicycle rides.</p>

<video autoplay="true" muted="true">
  <source src="http://blog.neteril.org/wp-content/uploads/bikr/screen.webm" type="video/webm" />
  <source src="http://blog.neteril.org/wp-content/uploads/bikr/screen.mp4" type="video/mp4" />
</video>

<p>It’s a no fuss, down to fundamental app that records how many miles you cycle and gives you a roundup per day, week and month. It will also show how you compare with the previous corresponding metrics (i.e. yesterday, previous week, previous month).</p>

<p>Best of all is that you don’t have to do anything. Thanks to <a href="http://developer.android.com/google/play-services/location.html">Google Activity Recognition APIs</a>, the app will take care of itself meaning you can just bike and forget about it.</p>

<p>The app is built using Xamarin as you would expect and you can find the entire source code at <a href="https://github.com/garuma/bikr">garuma/bikr</a> on GitHub. As usual, code is under the Apache 2.0 license which basically mean you can reuse whatever you want.</p>

<p>It’s also available for <a href="https://play.google.com/store/apps/details?id=org.neteril.Bikr">download on the Play Store</a>.</p>

<p><em>This is a joint release with James Montemagno’s MyStepCounter Android app, <a href="http://motzcod.es/post/83620382186/my-stepcounter-for-android-goes-live-open-source">check it out too!</a></em></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using Parallax for Fun And Profit]]></title>
    <link href="http://blog.neteril.org/blog/2014/01/02/using-parallax-for-fun-and-profit/"/>
    <updated>2014-01-02T16:30:00-05:00</updated>
    <id>http://blog.neteril.org/blog/2014/01/02/using-parallax-for-fun-and-profit</id>
    <content type="html"><![CDATA[<p>The idea of a parallax is to give the illusion of depth thanks to targets seemingly moving at a different pace. You have probably already noticed the effect in real life when riding on a straight line e.g. staring at individual scenery items from a train window.</p>

<p>The idea is basically that the closer an object is to you, the faster it seems to move to your eyes. The extreme being the background (like distant mountains) which doesn’t seem to move at all.</p>

<p>This effect, called <a href="http://en.wikipedia.org/wiki/Parallax">Parallax</a>, is used proficiently on iOS and Android launchers when scrolling through your apps to make it look like your wallpaper is further away from your icons as they move.</p>

<p>We can re-create parallax pretty easily on Android using the <code>ViewPager</code> class of the <a href="http://developer.android.com/reference/android/support/v4/view/ViewPager.html">support package</a> as a foundation for handling the touch events and displaying our content.</p>

<p>Our goal here is to create an awesome on-boarding screen to present your app. Each “slides” will have its own background and a couple of visual elements (text, device frame, other widgets) that will be arranged in different virtual layer (i.e. some will move faster than others).</p>

<p>Check out an example below of such a screen and the slightly different position offsets applied to each elements:</p>

<video width="360" height="640" preload="none" controls="" poster="/wp-content/uploads/parallax/parallax.jpg"><source src="http://blog.neteril.org/wp-content/uploads/parallax/parallax.mp4" type="video/mp4; codecs=&quot;avc1.42E01E, mp4a.40.2&quot;" /></video>

<p>The core idea is to setup a <code>ViewPager</code> taking up all the screen space (you can even use the new KitKat translucent window chrome like in the screencast with the <code>Holo.*.NoActionBar.Translucent</code> style) and then create a generic <code>FrameLayout</code>-based layout (remember how <a href="http://blog.neteril.org/blog/2013/10/10/framelayout-your-best-ui-friend/">FrameLayout is your friend</a>?) for the page. You don’t need to add an <code>ImageView</code> for the background since we will directly use the background property of the <code>FrameLayout</code>.</p>

<p>It’s also not necessary to have pre-scaled those background images since setting them as the background drawable of the main <code>FrameLayout</code> will automatically make them fit but it’s better if their dimensions are close to the form factor of the device (16/9 portrait usually) so that they don’t appear squashed (if you want to get fancy you might want to <a href="http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/">dynamically blur those</a> too).</p>

<p>Afterwards, just sprinkle the layout with <code>TextView</code>, <code>ImageView</code> or whatever other view you may want to showcase your app using the <code>layout_gravity</code> and <code>layout_margin</code> attributes to align them on the screen. Here is the example, very dumb, layout I’m using for the demo:</p>

<div class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;FrameLayout</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
    <span class="na">android:layout_width=</span><span class="s">&quot;fill_parent&quot;</span>
    <span class="na">android:layout_height=</span><span class="s">&quot;fill_parent&quot;</span>
    <span class="na">android:id=</span><span class="s">&quot;@+id/backgroundFrame&quot;</span>
    <span class="na">android:background=</span><span class="s">&quot;@drawable/onboarding_bg_1&quot;</span><span class="nt">&gt;</span>
    <span class="nt">&lt;TextView</span>
        <span class="na">android:text=</span><span class="s">&quot;A Big Title About Something&quot;</span>
        <span class="na">android:layout_width=</span><span class="s">&quot;wrap_content&quot;</span>
        <span class="na">android:layout_height=</span><span class="s">&quot;wrap_content&quot;</span>
        <span class="na">android:id=</span><span class="s">&quot;@+id/bigTitle&quot;</span>
        <span class="na">android:layout_gravity=</span><span class="s">&quot;center_horizontal|top&quot;</span>
        <span class="na">android:layout_marginTop=</span><span class="s">&quot;64dp&quot;</span>
        <span class="na">android:textColor=</span><span class="s">&quot;#ffffffff&quot;</span>
        <span class="na">android:textSize=</span><span class="s">&quot;24sp&quot;</span>
        <span class="na">android:shadowColor=</span><span class="s">&quot;#ff000000&quot;</span>
        <span class="na">android:shadowDx=</span><span class="s">&quot;0&quot;</span>
        <span class="na">android:shadowDy=</span><span class="s">&quot;1&quot;</span>
        <span class="na">android:shadowRadius=</span><span class="s">&quot;0.5&quot;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;TextView</span>
        <span class="na">android:text=</span><span class="s">&quot;A Subtitle About the Thing&quot;</span>
        <span class="na">android:layout_width=</span><span class="s">&quot;wrap_content&quot;</span>
        <span class="na">android:layout_height=</span><span class="s">&quot;wrap_content&quot;</span>
        <span class="na">android:id=</span><span class="s">&quot;@+id/bigSubtitle&quot;</span>
        <span class="na">android:layout_gravity=</span><span class="s">&quot;center_horizontal|bottom&quot;</span>
        <span class="na">android:layout_marginBottom=</span><span class="s">&quot;64dp&quot;</span>
        <span class="na">android:textColor=</span><span class="s">&quot;#ffffffff&quot;</span>
        <span class="na">android:textSize=</span><span class="s">&quot;20sp&quot;</span>
        <span class="na">android:shadowColor=</span><span class="s">&quot;#ff000000&quot;</span>
        <span class="na">android:shadowDx=</span><span class="s">&quot;0&quot;</span>
        <span class="na">android:shadowDy=</span><span class="s">&quot;1&quot;</span>
        <span class="na">android:shadowRadius=</span><span class="s">&quot;0.5&quot;</span> <span class="nt">/&gt;</span>
    <span class="nt">&lt;ImageView</span>
        <span class="na">android:src=</span><span class="s">&quot;@android:drawable/ic_menu_gallery&quot;</span>
        <span class="na">android:layout_width=</span><span class="s">&quot;200dp&quot;</span>
        <span class="na">android:layout_height=</span><span class="s">&quot;300dp&quot;</span>
        <span class="na">android:id=</span><span class="s">&quot;@+id/centerImage&quot;</span>
        <span class="na">android:layout_gravity=</span><span class="s">&quot;center&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/FrameLayout&gt;</span></code></pre></div>

<p>Once you have wired your <code>ViewPager</code> with an Adapter feeding the right content, we are going to create a <a href="http://developer.android.com/reference/android/support/v4/view/ViewPager.PageTransformer.html">PageTransformer</a> which is where the parallax magic is gonna be created. Implementing this interface requires only one method which is called for every scroll offset of a given page <code>View</code> together with a value indicating its position relative to the center of the screen.</p>

<p>That relative position is very handy because it’s clamped between -1 (left of the screen) and +1 (right of the screen) with the zero value in the middle. That means we can derive a very simple parallax equation based on its value:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="k">public</span> <span class="k">class</span> <span class="nc">OnBoardingPageTransformer</span> <span class="p">:</span> <span class="n">Java</span><span class="p">.</span><span class="n">Lang</span><span class="p">.</span><span class="n">Object</span><span class="p">,</span> <span class="n">ViewPager</span><span class="p">.</span><span class="n">IPageTransformer</span>
<span class="p">{</span>
	<span class="kt">float</span> <span class="n">parallaxCoefficient</span><span class="p">;</span>
	<span class="kt">float</span> <span class="n">distanceCoefficient</span><span class="p">;</span>
	<span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;[]</span> <span class="n">viewLayers</span><span class="p">;</span>

	<span class="k">public</span> <span class="nf">OnBoardingPageTransformer</span> <span class="p">(</span><span class="kt">float</span> <span class="n">parallaxCoefficient</span><span class="p">,</span>
	                                  <span class="kt">float</span> <span class="n">distanceCoefficient</span><span class="p">,</span>
	                                  <span class="k">params</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;[]</span> <span class="n">viewLayers</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">this</span><span class="p">.</span><span class="n">parallaxCoefficient</span> <span class="p">=</span> <span class="n">parallaxCoefficient</span><span class="p">;</span>
		<span class="k">this</span><span class="p">.</span><span class="n">distanceCoefficient</span> <span class="p">=</span> <span class="n">distanceCoefficient</span><span class="p">;</span>
		<span class="k">this</span><span class="p">.</span><span class="n">viewLayers</span> <span class="p">=</span> <span class="n">viewLayers</span><span class="p">;</span>
	<span class="p">}</span>

	<span class="k">public</span> <span class="k">void</span> <span class="nf">TransformPage</span> <span class="p">(</span><span class="n">View</span> <span class="n">page</span><span class="p">,</span> <span class="kt">float</span> <span class="n">position</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="kt">float</span> <span class="n">coefficient</span> <span class="p">=</span> <span class="n">page</span><span class="p">.</span><span class="n">Width</span> <span class="p">*</span> <span class="n">parallaxCoefficient</span><span class="p">;</span>
		<span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">layer</span> <span class="k">in</span> <span class="n">viewLayers</span><span class="p">)</span> <span class="p">{</span>
			<span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">viewID</span> <span class="k">in</span> <span class="n">layer</span><span class="p">)</span> <span class="p">{</span>
				<span class="kt">var</span> <span class="n">v</span> <span class="p">=</span> <span class="n">page</span><span class="p">.</span><span class="n">FindViewById</span> <span class="p">(</span><span class="n">viewID</span><span class="p">);</span>
				<span class="k">if</span> <span class="p">(</span><span class="n">v</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
					<span class="n">v</span><span class="p">.</span><span class="n">TranslationX</span> <span class="p">=</span> <span class="n">coefficient</span> <span class="p">*</span> <span class="n">position</span><span class="p">;</span>
			<span class="p">}</span>
			<span class="n">coefficient</span> <span class="p">*=</span> <span class="n">distanceCoefficient</span><span class="p">;</span>
		<span class="p">}</span>
	<span class="p">}</span>
<span class="p">}</span></code></pre></div>

<p>The trick is then to have a way to define layers and then let the user supply a couple of arguments to parametrize the effect. In the above class, we achieve this by letting the user gives a list of view IDs for each layer they want to create. You can then set the instance on your <code>ViewPager</code> by calling the <code>SetPageTransformer</code> method.</p>

<p>As a final piece of information, know that this technique only work on Android 3.0+ because <code>ViewPager</code> assumes you are using animatable properties.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Android tip: ViewPager with protruding children]]></title>
    <link href="http://blog.neteril.org/blog/2013/10/14/android-tip-viewpager-with-protruding-children/"/>
    <updated>2013-10-14T00:12:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2013/10/14/android-tip-viewpager-with-protruding-children</id>
    <content type="html"><![CDATA[<p><code>ViewPager</code> is a widget part of the <a href="http://developer.android.com/tools/support-library/index.html">Support package</a> that lets you display an horizontal list of “page”. In a nutshell, it’s to <code>HorizontalScrollView</code> what a <code>ListView</code> is to a vertical <code>ScrollView</code>.</p>

<p>By default pages are laid out to span the entire surface of the pager. In our case what we want to do is something akin to how the search results in the Apple’s AppStore iPhone app are displayed, a card-like style with adjacent items slightly taking over the surface edges:</p>

<p><a href="http://www.engadget.com/2012/09/18/ios-6-review/"><img class="center" src="http://blog.neteril.org/wp-content/uploads/viewpager-hinting/appstore.jpg" width="300" /></a></p>

<p>Getting this to work with the default <code>ViewPager</code> class is a bit tricky. We have basically to change 3 things:</p>

<ul>
  <li>The global padding of the pager</li>
  <li>The spacing between each page</li>
  <li>The width of a single page</li>
</ul>

<p>The first one might seem straightforward, you would just go and add both a <code>android:paddingLeft</code> and <code>android:paddingRight</code> onto the pager XML declaration. The problem is that by doing so, the clip rectangle is also moved by that same padding so it looks like the pages are cut in the middle of nowhere.</p>

<p>Fortunately, every <code>ViewGroup</code> subclass accept the <code>android:clipToPadding</code> attribute (<a href="http://developer.android.com/reference/android/view/ViewGroup.html#attr_android:clipToPadding">doc</a>) which allows to alter exactly that. By setting this one to false, the clip rect will remain equal to the container bounds but padding will still be taken into account during the layout phase.</p>

<p>The spacing between pages is a property settable on the pager itself, <code>PageMargin</code> (<a href="http://developer.android.com/reference/android/view/ViewGroup.html#attr_android:clipToPadding">doc</a>). This value should be about half the size of the left padding value.</p>

<p>Finally, to change the width of the pages, you override the <code>GetPageWidth</code> method of your <code>PagerAdapter</code> subclass (<a href="http://developer.android.com/reference/android/support/v4/view/PagerAdapter.html#getPageWidth(int)">doc</a>). The right value you use depends on the sizing you put beforehand so slightly tune it until you find the desired effect.</p>

<p>Applying those 3 techniques we arrive at the following result:</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/viewpager-hinting/animation.gif" width="282" height="423" /></p>

<p>For reference sake, here are the XML and code used for that output:</p>

<div class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;android.support.v4.view.ViewPager</span>
  	<span class="na">android:id=</span><span class="s">&quot;@+id/pager&quot;</span>
  	<span class="na">android:gravity=</span><span class="s">&quot;center&quot;</span>
  	<span class="na">android:layout_width=</span><span class="s">&quot;match_parent&quot;</span>
  	<span class="na">android:layout_height=</span><span class="s">&quot;0px&quot;</span>
  	<span class="na">android:paddingLeft=</span><span class="s">&quot;24dp&quot;</span>
  	<span class="na">android:paddingRight=</span><span class="s">&quot;12dp&quot;</span>
  	<span class="na">android:layout_weight=</span><span class="s">&quot;1&quot;</span> <span class="nt">/&gt;</span></code></pre></div>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="kt">var</span> <span class="n">pager</span> <span class="p">=</span> <span class="n">view</span><span class="p">.</span><span class="n">FindViewById</span><span class="p">&lt;</span><span class="n">ViewPager</span><span class="p">&gt;</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Id</span><span class="p">.</span><span class="n">pager</span><span class="p">);</span>
<span class="n">pager</span><span class="p">.</span><span class="n">SetClipToPadding</span> <span class="p">(</span><span class="k">false</span><span class="p">);</span>
<span class="n">pager</span><span class="p">.</span><span class="n">PageMargin</span> <span class="p">=</span> <span class="m">12.</span><span class="n">ToPixels</span> <span class="p">();</span>
<span class="n">pager</span><span class="p">.</span><span class="n">Adapter</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MyPageAdapter</span> <span class="p">(</span><span class="n">ChildFragmentManager</span><span class="p">);</span>

<span class="k">class</span> <span class="nc">MyPageAdapter</span> <span class="p">:</span> <span class="n">FragmentStatePagerAdapter</span>
<span class="p">{</span>
	<span class="k">public</span> <span class="k">override</span> <span class="kt">float</span> <span class="nf">GetPageWidth</span> <span class="p">(</span><span class="kt">int</span> <span class="n">position</span><span class="p">)</span>
	<span class="p">{</span>
		<span class="k">return</span> <span class="m">0.93f</span><span class="p">;</span>
	<span class="p">}</span>
	
	<span class="c1">// ...</span>
<span class="p">}</span></code></pre></div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[FrameLayout, your best UI friend]]></title>
    <link href="http://blog.neteril.org/blog/2013/10/10/framelayout-your-best-ui-friend/"/>
    <updated>2013-10-10T10:15:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2013/10/10/framelayout-your-best-ui-friend</id>
    <content type="html"><![CDATA[<p>You have probably already used <code>FrameLayout</code> (<a href="http://developer.android.com/reference/android/widget/FrameLayout.html">doc</a>) for what it’s named, adding a decoration around other content element. It can actually be much more than that and is probably one of the most versatile container of all.</p>

<p>The secret of <code>FrameLayout</code> is how it layouts its children. Although normally designed to contain one item, it will happily stack up other element on top of each other. Thus <code>FrameLayout</code> is essentially a way to manipulate the Z-order of views on the screen.</p>

<p>This is super useful for a couple of UI tricks from HUD-like elements to sliding panels to more complex animated transitions. In this post we will see an example for each of those.</p>

<h3 id="overlay-elements">Overlay Elements</h3>

<p>As I mentioned, <code>FrameLayout</code> will automatically stacks its children on top of each other. This makes it really easy to implement overlay or HUD element in your interface.</p>

<p>The idea is to wrap the part of the UI into an outer <code>FrameLayout</code> instance. Generally this will be the root element of your layout. You can then add below the main layout definition the other elements you want to overlay.</p>

<p>These elements will generally have a fixed size or be set as <code>wrap_content</code>. You can then place them at the right position on screen using the <code>layout_gravity</code> and <code>layout_margin</code> XML attributes.</p>

<p>In the following screenshot, my main content is a Google Map view. I have then added two overlays above it, one that replicate a toast message (center-bottom corner) and a <code>TextView</code> displaying the last time the data was loaded (upper-right corner).</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/framelayout/overlay.png" /></p>

<p>This is simply achieved with the following layout:</p>

<div class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="nt">&lt;FrameLayout</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
    <span class="na">android:layout_width=</span><span class="s">&quot;match_parent&quot;</span>
    <span class="na">android:layout_height=</span><span class="s">&quot;match_parent&quot;</span><span class="nt">&gt;</span>
    <span class="c">&lt;!-- The main content --&gt;</span>
    <span class="nt">&lt;com.google.android.gms.maps.MapView</span>
        <span class="na">android:id=</span><span class="s">&quot;@+id/map&quot;</span>
        <span class="na">android:layout_width=</span><span class="s">&quot;match_parent&quot;</span>
        <span class="na">android:layout_height=</span><span class="s">&quot;match_parent&quot;</span> <span class="nt">/&gt;</span>
    <span class="c">&lt;!-- &quot;Loaded&quot; flash bar layout --&gt;</span>
    <span class="nt">&lt;FrameLayout</span>
        <span class="na">android:id=</span><span class="s">&quot;@+id/FlashBarLayout&quot;</span>
        <span class="na">android:layout_width=</span><span class="s">&quot;wrap_content&quot;</span>
        <span class="na">android:layout_height=</span><span class="s">&quot;wrap_content&quot;</span>
        <span class="na">android:layout_gravity=</span><span class="s">&quot;center_horizontal|bottom&quot;</span>
        <span class="na">android:layout_marginBottom=</span><span class="s">&quot;72dp&quot;</span><span class="nt">&gt;</span>
        <span class="c">&lt;!-- flash bar content --&gt;</span>
    <span class="nt">&lt;/FrameLayout&gt;</span>
    <span class="c">&lt;!-- Last loaded time layout --&gt;</span>
    <span class="nt">&lt;TextView</span>
        <span class="na">android:id=</span><span class="s">&quot;@+id/UpdateTimeText&quot;</span>
        <span class="na">android:layout_width=</span><span class="s">&quot;wrap_content&quot;</span>
        <span class="na">android:layout_height=</span><span class="s">&quot;wrap_content&quot;</span>
        <span class="na">android:layout_gravity=</span><span class="s">&quot;top|right&quot;</span>
        <span class="na">android:layout_marginTop=</span><span class="s">&quot;4dp&quot;</span>
        <span class="na">android:layout_marginRight=</span><span class="s">&quot;4dp&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/FrameLayout&gt;</span></code></pre></div>

<p>Being just normal views, you can manipulate the overlays as usual. For instance you will probably want to implement some sort of animations for transition between visibility states if the overlay is transient.</p>

<h3 id="sliding-panels">Sliding Panels</h3>

<p>Sliding panels (aka drawers, aka fly-out menus) are the rage these days. They mainly consist of a panel that is placed, depending on the desired spatial effect, above or below another piece of content. Again this falls back to placing elements using a <code>FrameLayout</code> object.</p>

<p>The trick then is to use the <code>translationX</code> and <code>translationY</code> properties of the panel <code>View</code> to move the element back and forth.</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/framelayout/sliding-panel.gif" /></p>

<p>Alternatively, <code>View</code> also exposes the <code>OffsetTopAndBottom</code> and <code>OffsetLeftAndRight</code> methods (working on display list directly) but those are not as easy to animate. Indeed, with the translation properties you can directly use <code>ObjectAnimator</code> or <code>ViewPropertyAnimator</code>.</p>

<p>The panel is initially “hidden” by setting its <code>translationY</code> property to its height (i.e. top side forced to the bottom of the screen). We create the initial appearing effect with the following code piece inside the panel class:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="c1">// As its name imply, this interpolator will let the view go slightly overboard</span>
<span class="c1">// and then spring it back to its place</span>
<span class="kt">var</span> <span class="n">intp</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Android</span><span class="p">.</span><span class="n">Views</span><span class="p">.</span><span class="n">Animations</span><span class="p">.</span><span class="n">OvershootInterpolator</span> <span class="p">();</span>
<span class="kt">var</span> <span class="n">d</span> <span class="p">=</span> <span class="n">Context</span><span class="p">.</span><span class="n">Resources</span><span class="p">.</span><span class="n">GetInteger</span> <span class="p">(</span><span class="n">Android</span><span class="p">.</span><span class="n">Resource</span><span class="p">.</span><span class="n">Integer</span><span class="p">.</span><span class="n">ConfigMediumAnimTime</span><span class="p">);</span>
<span class="c1">// Only the header part of the view should be visible, we thus just make</span>
<span class="c1">// the bottom of the view translated off-screen</span>
<span class="kt">var</span> <span class="n">tY</span> <span class="p">=</span> <span class="n">Height</span> <span class="p">-</span> <span class="n">FindViewById</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Id</span><span class="p">.</span><span class="n">PaneHeaderView</span><span class="p">).</span><span class="n">Height</span><span class="p">;</span>

<span class="k">this</span><span class="p">.</span><span class="n">Animate</span> <span class="p">().</span><span class="n">TranslationY</span> <span class="p">(</span><span class="n">tY</span><span class="p">).</span><span class="n">SetDuration</span> <span class="p">(</span><span class="n">d</span><span class="p">).</span><span class="n">SetInterpolator</span> <span class="p">(</span><span class="n">intp</span><span class="p">).</span><span class="n">Start</span> <span class="p">();</span></code></pre></div>

<p>A common idiom of those panel is also to draw a shadow on the edge where they meet the content. This can be implemented very efficiently by overriding the <code>DispatchDraw</code> method of the sliding panel <code>View</code> and drawing a black linear <code>GradientDrawable</code> at the right place (use the <code>Translate</code> method on <code>Canvas</code> for the right positioning).</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">DispatchDraw</span> <span class="p">(</span><span class="n">Android</span><span class="p">.</span><span class="n">Graphics</span><span class="p">.</span><span class="n">Canvas</span> <span class="n">canvas</span><span class="p">)</span>
<span class="p">{</span>
    <span class="k">base</span><span class="p">.</span><span class="n">DispatchDraw</span> <span class="p">(</span><span class="n">canvas</span><span class="p">);</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">shadowDrawable</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
        <span class="n">shadowDrawable</span> <span class="p">=</span> <span class="k">new</span> <span class="n">GradientDrawable</span> <span class="p">(</span><span class="n">GradientDrawable</span><span class="p">.</span><span class="n">Orientation</span><span class="p">.</span><span class="n">BottomTop</span><span class="p">,</span>
                                               <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="n">Color</span><span class="p">.</span><span class="n">Argb</span> <span class="p">(</span><span class="m">0</span><span class="n">x60</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">),</span> <span class="n">Color</span><span class="p">.</span><span class="n">Argb</span> <span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">)</span> <span class="p">});</span>
    <span class="c1">// The reserved area for the shadow is set with top padding on the view.</span>
    <span class="n">shadowDrawable</span><span class="p">.</span><span class="n">SetBounds</span> <span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="m">0</span><span class="p">,</span> <span class="n">Width</span><span class="p">,</span> <span class="n">PaddingTop</span><span class="p">);</span>
    <span class="n">shadowDrawable</span><span class="p">.</span><span class="n">Draw</span> <span class="p">(</span><span class="n">canvas</span><span class="p">);</span>
<span class="p">}</span></code></pre></div>

<h3 id="transitions">Transitions</h3>

<p>With the move to a <code>Fragment</code> world, everything becomes just another <code>View</code> to manage and thereby removing the need for <code>Activity</code>.</p>

<p>When you think about the different “screen” of you application as individual fragments it becomes very easy to manipulate them in fun ways. Notably, being just managed <code>View</code> objects, you can apply any of the animations techniques you are already familiar with to implement very nifty transition effects.</p>

<p>At the core of such system, you will find again the same idea of a central, expanded <code>FrameLayout</code> surface where your <code>Fragment</code> are added.</p>

<p>The idea is to pile the <code>Fragment</code> views on top of each other like a deck of card. The current screen is thus the first card of the pile and application transitions are then simply how you want the middle cards to be put on top.</p>

<p>I’m using this analogy of the card deck because the method we are going to use here is <code>View.BringToFront</code>. This method will move the view at the last position inside its parent array. The end result of that operation of course depends on the type of container but in the case of <code>FrameLayout</code> it will make the <code>View</code> be drawn on top.</p>

<p>Note that this method doesn’t force a relayout which is fine for <code>FrameLayout</code> since children individual bounds aren’t dependent on each other but in the case of e.g. <code>LinearLayout</code> you will have to call <code>RequestLayout</code> for the modification to happen.</p>

<p>We will assume the layout of our main <code>Activity</code> is a single full-size <code>FrameLayout</code> container. Our application is composed of two screens represented as two fragments.</p>

<p>Initially, we create and attach directly those fragments to our content frame, hiding the second one to get into an initial state:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="n">FirstFragment</span> <span class="n">fragment1</span><span class="p">;</span>
<span class="n">SecondFragment</span> <span class="n">fragment2</span><span class="p">;</span>

<span class="n">Fragment</span> <span class="n">currentFragment</span><span class="p">;</span>

<span class="k">protected</span> <span class="k">override</span> <span class="k">void</span> <span class="nf">OnCreate</span> <span class="p">(</span><span class="n">Bundle</span> <span class="n">bundle</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">SetContentView</span> <span class="p">(</span><span class="cm">/* ... */</span><span class="p">);</span>
	
	<span class="n">fragment1</span> <span class="p">=</span> <span class="k">new</span> <span class="n">FirstFragment</span> <span class="p">(</span><span class="k">this</span><span class="p">);</span>
	<span class="n">fragment2</span> <span class="p">=</span> <span class="k">new</span> <span class="n">SecondFragment</span> <span class="p">(</span><span class="k">this</span><span class="p">);</span>
	
	<span class="n">SupportFragmentManager</span><span class="p">.</span><span class="n">BeginTransation</span> <span class="p">()</span>
		<span class="p">.</span><span class="n">Add</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Id</span><span class="p">.</span><span class="n">content_frame</span><span class="p">,</span> <span class="n">fragment2</span><span class="p">,</span> <span class="n">SecondFragment</span><span class="p">.</span><span class="n">Name</span><span class="p">)</span>
		<span class="p">.</span><span class="n">Hide</span> <span class="p">(</span><span class="n">fragment2</span><span class="p">)</span>
		<span class="p">.</span><span class="n">Add</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Id</span><span class="p">.</span><span class="n">content_frame</span><span class="p">,</span> <span class="n">fragment1</span><span class="p">,</span> <span class="n">FirstFragment</span><span class="p">.</span><span class="n">Name</span><span class="p">)</span>
		<span class="p">.</span><span class="n">Commit</span> <span class="p">();</span>
	<span class="n">currentFragment</span> <span class="p">=</span> <span class="n">fragment1</span><span class="p">;</span>
<span class="p">}</span></code></pre></div>

<p>When we want to change the <code>Fragment</code> that is shown, we will make sure that both views are on top of the drawing pile with the current one being on top of the other using <code>BringToFront</code>. We then swap the two fragments in a <code>FragmentTransaction</code>:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="k">void</span> <span class="nf">SwitchTo</span> <span class="p">(</span><span class="n">Fragment</span> <span class="n">fragment</span><span class="p">,</span> <span class="kt">string</span> <span class="n">name</span><span class="p">)</span>
<span class="p">{</span>
	<span class="k">if</span> <span class="p">(</span><span class="n">fragment</span><span class="p">.</span><span class="n">IsVisible</span><span class="p">)</span>
		<span class="k">return</span><span class="p">;</span>
	<span class="kt">var</span> <span class="n">t</span> <span class="p">=</span> <span class="n">SupportFragmentManager</span><span class="p">.</span><span class="n">BeginTransaction</span> <span class="p">();</span>
	<span class="n">t</span><span class="p">.</span><span class="n">SetCustomAnimations</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Animator</span><span class="p">.</span><span class="n">frag_slide_in</span><span class="p">,</span>
	                       <span class="n">Resource</span><span class="p">.</span><span class="n">Animator</span><span class="p">.</span><span class="n">frag_slide_out</span><span class="p">);</span>

	<span class="c1">// Make sure the next view is below the current one</span>
	<span class="n">fragment</span><span class="p">.</span><span class="n">View</span><span class="p">.</span><span class="n">BringToFront</span> <span class="p">();</span>
	<span class="c1">// And bring the current one to the very top</span>
	<span class="n">currentFragment</span><span class="p">.</span><span class="n">View</span><span class="p">.</span><span class="n">BringToFront</span> <span class="p">();</span>

	<span class="c1">// Hide the current fragment</span>
	<span class="n">t</span><span class="p">.</span><span class="n">Hide</span> <span class="p">(</span><span class="n">currentFragment</span><span class="p">);</span>
	<span class="n">t</span><span class="p">.</span><span class="n">Show</span> <span class="p">(</span><span class="n">existingFragment</span><span class="p">);</span>
	<span class="n">currentFragment</span> <span class="p">=</span> <span class="n">existingFragment</span><span class="p">;</span>

	<span class="c1">// You probably want to add the transaction to the backstack</span>
	<span class="c1">// so that user can use the back button</span>
	<span class="n">t</span><span class="p">.</span><span class="n">AddToBackStack</span> <span class="p">(</span><span class="k">null</span><span class="p">);</span>
	<span class="n">t</span><span class="p">.</span><span class="n">Commit</span> <span class="p">();</span>
<span class="p">}</span></code></pre></div>

<p>To add a bit of woosh, we are using customs animations to mark the transition between the two fragments to get this result:</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/framelayout/transitions.gif" /></p>

<p>These animations need to be defined in an XML resource using either <a href="http://developer.android.com/guide/topics/resources/animation-resource.html#Property">property animator</a> (aka from Android.Animations) if you are using framework <code>Fragment</code> or using <a href="http://developer.android.com/guide/topics/resources/animation-resource.html#View">view animations</a> (aka from Android.View.Animations) if you are using <code>Fragment</code> from the support package.</p>

<p>To register custom animations, we call the <code>SetCustomAnimations</code> method on <code>FragmentTransaction</code> like so:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="n">t</span><span class="p">.</span><span class="n">SetCustomAnimations</span> <span class="p">(</span><span class="n">Resource</span><span class="p">.</span><span class="n">Animator</span><span class="p">.</span><span class="n">frag_slide_in</span><span class="p">,</span>
                       <span class="n">Resource</span><span class="p">.</span><span class="n">Animator</span><span class="p">.</span><span class="n">frag_slide_out</span><span class="p">);</span></code></pre></div>

<p>The first animation will be run on any fragment added/attached/shown while the second animation will be played on fragments hidden/detached/removed. Both are ran at the same time but you can use the animation <code>startOffset</code> attribute to delay one or the other.</p>

<p>For instance in my example, my <code>frag_slide_out</code> animation is defined like so:</p>

<div class="highlight"><pre><code class="language-xml" data-lang="xml"><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span>
<span class="nt">&lt;set</span> <span class="na">xmlns:android=</span><span class="s">&quot;http://schemas.android.com/apk/res/android&quot;</span>
     <span class="na">android:interpolator=</span><span class="s">&quot;@android:interpolator/accelerate_cubic&quot;</span><span class="nt">&gt;</span>
   <span class="nt">&lt;translate</span>
      <span class="na">android:fromXDelta=</span><span class="s">&quot;0&quot;</span>
      <span class="na">android:toXDelta=</span><span class="s">&quot;100%&quot;</span>
      <span class="na">android:duration=</span><span class="s">&quot;300&quot;</span> <span class="nt">/&gt;</span>
   <span class="nt">&lt;alpha</span>
        <span class="na">android:fromAlpha=</span><span class="s">&quot;1.0&quot;</span>
        <span class="na">android:toAlpha=</span><span class="s">&quot;0.3&quot;</span>
        <span class="na">android:duration=</span><span class="s">&quot;300&quot;</span> <span class="nt">/&gt;</span>
<span class="nt">&lt;/set&gt;</span></code></pre></div>

<h3 id="conclusion">Conclusion</h3>

<p>Everything I have presented here is part of a big refresh to Moyeu. You can view the full source code on the GitHub repository at  <a href="https://github.com/garuma/Moyeu">garuma/Moyeu</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[XamSvg, managed SVG support for Android]]></title>
    <link href="http://blog.neteril.org/blog/2013/10/10/xamsvg-managed-svg-for-xamarin-android/"/>
    <updated>2013-10-10T10:10:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2013/10/10/xamsvg-managed-svg-for-xamarin-android</id>
    <content type="html"><![CDATA[<p>As part of the new release of <a href="http://moyeuapp.net">Moyeu</a>, I’m also finally publishing a library that I have been using for some time.</p>

<p>This library is called <a href="https://github.com/garuma/xamsvg">XamSvg</a> and in a nutshell it’s a managed (partial) implementation of an SVG parser/renderer for, currently only, Xamarin.Android.</p>

<p>The idea stems from the fact that Android has by default no serious way to do scalable graphics in a world with an exploding amount of device densities.</p>

<p>SVG appeared as a good fit because it’s easy to parse (XML), text-based (compress well) and fit well with the Android graphics API. It’s also incidentally the format used by the lovely <a href="http://inkscape.org/">Inkscape</a> which makes my work even easier.</p>

<p>Before anyone gets their hopes high and starts throwing fancy SVG tigers at the library, know that this is by no mean meant to be a complete implementation of the standard.</p>

<p>As described in the <a href="https://github.com/garuma/xamsvg/blob/master/README.md">README</a>, the goal is to provide a minimum viable product™ to support traditional shape-based icons.</p>

<p>Still, I haven’t had any problem parsing all the SVG that I have created as almost all the icons in Moyeu are entirely SVG based. In general, if you follow the exporting guide in the README you should be fine.</p>

<p>The other good thing about the library is that it’s very simple to use. You will generally use only one class, <code>SvgFactory</code> and its two methods <code>GetBitmap</code> / <code>GetDrawable</code>:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="kt">var</span> <span class="n">bmp</span> <span class="p">=</span> <span class="n">SvgFactory</span><span class="p">.</span><span class="n">GetBitmap</span> <span class="p">(</span><span class="n">Activity</span><span class="p">.</span><span class="n">Resources</span><span class="p">,</span> <span class="n">Resource</span><span class="p">.</span><span class="n">Raw</span><span class="p">.</span><span class="n">ic_svg</span><span class="p">,</span> <span class="m">48</span><span class="p">,</span> <span class="m">48</span><span class="p">);</span>
<span class="kt">var</span> <span class="n">drawable</span> <span class="p">=</span> <span class="n">SvgFactory</span><span class="p">.</span><span class="n">GetDrawable</span> <span class="p">(</span><span class="n">Activity</span><span class="p">.</span><span class="n">Resources</span><span class="p">,</span> <span class="n">Resource</span><span class="p">.</span><span class="n">Raw</span><span class="p">.</span><span class="n">ic_svg</span><span class="p">);</span></code></pre></div>

<p>I recommend the second form as the returned drawable will automatically scale depending on the bounds requested. This means that if you have an <code>ImageView</code> set up using dp units like this:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="p">&lt;</span><span class="n">ImageView</span>
    <span class="n">android</span><span class="p">:</span><span class="n">layout_width</span><span class="p">=</span><span class="s">&quot;14dp&quot;</span>
    <span class="n">android</span><span class="p">:</span><span class="n">layout_height</span><span class="p">=</span><span class="s">&quot;9dp&quot;</span>
    <span class="n">android</span><span class="p">:</span><span class="n">scaleType</span><span class="p">=</span><span class="s">&quot;fitXY&quot;</span> <span class="p">/&gt;</span></code></pre></div>

<p>The displayed image will look the same crispy crispness on every devices no matter how many pixel per inches they have.</p>

<p>Another cool thing about the library is that it lets you dynamically adapt colors at runtime. To do so, you need to provide an implementation of the <code>ISvgColorMapper</code> interface which sports the single method <code>Color MapColor (Color c)</code> (instance that can also be retrieved from a <code>Func&lt;Color, Color&gt;</code>).</p>

<p>I use this tricks for the pins that are displayed by Moyeu on the map. Concretely, the pins are all the same base SVG:</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/xamsvg/pin_raw.png" /></p>

<p>On which I can apply tinting with my color mapper:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="n">Color</span> <span class="nf">ColorReplacer</span> <span class="p">(</span><span class="n">Color</span> <span class="n">inColor</span><span class="p">,</span> <span class="kt">float</span> <span class="n">ratio</span><span class="p">)</span>
<span class="p">{</span>
	<span class="n">Color</span> <span class="n">tone</span> <span class="p">=</span> <span class="n">InterpolateColor</span> <span class="p">(</span><span class="n">baseLightRedColor</span><span class="p">,</span> <span class="n">baseLightGreenColor</span><span class="p">,</span> <span class="n">ratio</span><span class="p">);</span>
	<span class="n">Color</span> <span class="n">result</span> <span class="p">=</span> <span class="n">inColor</span><span class="p">;</span>

	<span class="k">if</span> <span class="p">(</span><span class="n">inColor</span> <span class="p">==</span> <span class="n">fillColor</span><span class="p">)</span>
		<span class="n">result</span> <span class="p">=</span> <span class="n">tone</span><span class="p">;</span>
	<span class="k">else</span> <span class="nf">if</span> <span class="p">(</span><span class="n">inColor</span> <span class="p">==</span> <span class="n">borderColor</span><span class="p">)</span>
		<span class="n">result</span> <span class="p">=</span> <span class="n">Lighten</span> <span class="p">(</span><span class="n">tone</span><span class="p">,</span> <span class="m">0</span><span class="n">x20</span><span class="p">);</span>
	<span class="k">else</span> <span class="nf">if</span> <span class="p">(</span><span class="n">inColor</span> <span class="p">==</span> <span class="n">bottomFillColor</span><span class="p">)</span>
		<span class="n">result</span> <span class="p">=</span> <span class="n">InterpolateColor</span> <span class="p">(</span><span class="n">baseDarkRedColor</span><span class="p">,</span> <span class="n">baseDarkGreenColor</span><span class="p">,</span> <span class="n">ratio</span><span class="p">);</span>

	<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span></code></pre></div>

<p>In order to have a multi-colored view of the world:</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/xamsvg/pins_rendered.png" /></p>

<p>You can find more usage sample of the library in Moyeu <a href="https://github.com/garuma/Moyeu">source code</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[A big refresh to Moyeu]]></title>
    <link href="http://blog.neteril.org/blog/2013/10/10/a-big-refresh-to-moyeu/"/>
    <updated>2013-10-10T10:02:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2013/10/10/a-big-refresh-to-moyeu</id>
    <content type="html"><![CDATA[<p><a href="http://moyeuapp.net">Moyeu</a> is an Android application that hopes to provide a better alternative to Boston’s Hubway bike sharing system. You can view <a href="http://localhost:4000/blog/2013/05/25/moyeu-hubway-on-a-xamarin-map/">the introductory post</a> I made at the time.</p>

<p>This new version sports a good number of new features and general UI refresh.</p>

<p>For starter, the navigation is now exposed as a drawer that also lets you visualize stations that are near you.</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/moyeu/around-med.png" /></p>

<p>Instead of the old info window style, information about a station are presented with a sliding info view in the same fashion than the new Google Maps application. That info view when expanded also shows you a Google Street View shot of the station surroundings for easier pinpointing.</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/moyeu/richinfos-med.png" /></p>

<p>The pins displayed on the map are also now showing the number of bikes available at each station. They also have a better tinting system to provide a direct feedback on each station bike availability.</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/moyeu/gmapsv2-med.png" /></p>

<p>Just for fun, I also made a little featurette page for the app. Check it out at <a href="http://moyeuapp.net">moyeuapp.net</a>.</p>

<p>For installation, head to the usual corner of the web:</p>

<p><a href="https://play.google.com/store/apps/details?id=org.neteril.Moyeu"><img class="raw" alt="Get it on Google Play" src="http://blog.neteril.org/wp-content/uploads/moyeu/en_generic_rgb_wo_60.png" /></a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Similardio, Rdio meets Lastfm]]></title>
    <link href="http://blog.neteril.org/blog/2013/08/16/similardio-rdio-meets-lastfm/"/>
    <updated>2013-08-16T11:13:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2013/08/16/similardio-rdio-meets-lastfm</id>
    <content type="html"><![CDATA[<p align="center"><img src="http://blog.neteril.org/wp-content/uploads/similardio/logo_medium.png" class="raw" /></p>

<h3 id="what">What?</h3>

<p>An experiment in bridging <a href="http://www.rdio.com/">Rdio</a> and <a href="http://last.fm/">Lastfm</a> together.</p>

<p>The idea is to gather your most listened to artists on Rdio and generously gather similar talents from Lastfm comprehensive database.</p>

<p>All of this straight from your Android phone.</p>

<h3 id="what-does-it-look-like">What does it look like?</h3>

<p>It has pretty animations. It has blurring. It has large images.</p>

<video width="289" height="480" preload="none" controls="" poster="/wp-content/uploads/similardio/screencast.jpg"><source src="http://blog.neteril.org/wp-content/uploads/similardio/screencast.m4v" type="video/mp4; codecs=&quot;avc1.42E01E, mp4a.40.2&quot;" /></video>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/similardio/fresque_small.png" /></p>

<h3 id="what-should-i-do-with-it">What should I do with it</h3>

<p>Use it as an example for <a href="https://github.com/bduncavage/RdioSdkBindings">bduncavage/RdioSdkBindings</a> or scavenge any other part of it. All under Apache 2.0 license.</p>

<p>GitHub repository: <a href="https://github.com/garuma/Similardio">garuma/Similardio</a></p>

<p><a href="https://play.google.com/store/apps/details?id=org.neteril.Similardio"><img class="raw" alt="Android app on Google Play" src="https://developer.android.com/images/brand/en_app_rgb_wo_60.png" /></a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Blurring images on Android]]></title>
    <link href="http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android/"/>
    <updated>2013-08-12T23:20:00-04:00</updated>
    <id>http://blog.neteril.org/blog/2013/08/12/blurring-images-on-android</id>
    <content type="html"><![CDATA[<p>One of the most underused Android feature is probably RenderScript (do you even remember what it is?).</p>

<p>As a reminder, RenderScript is essentially Google’s version of OpenCL in that it allows you to write small general-purpose piece of code (called kernel) that executes on the GPU.</p>

<p>As such, it’s very efficient when doing parallelizable work on large data-set. The main hindrance as with any GPGPU scenario is that to interoperate with the CPU, data needs to be copied back and forth between RAM and GPU memory.</p>

<p>One of the main area where RenderScript is useful is with images and pixel-oriented algorithms. Since with recent Android version <code>View</code> instances are hardware-accelerated by default, showing up these GPU-processed images on screen is efficient as they don’t even need to be piggy backed to main memory.</p>

<p>Out of the box, Android ships with a couple of pre-made kernels, mainly picture-related. In that sense it can be considered equivalent to iOS CoreGraphics albeit much less rich in available filters.</p>

<p>One of those default script, <code>ScriptIntrinsicBlur</code>, allows you to blur the content of an image very easily:</p>

<div class="highlight"><pre><code class="language-csharp" data-lang="csharp"><span class="n">Bitmap</span> <span class="nf">BlurImage</span> <span class="p">(</span><span class="n">Bitmap</span> <span class="n">input</span><span class="p">)</span>
<span class="p">{</span>
	<span class="kt">var</span> <span class="n">rsScript</span> <span class="p">=</span> <span class="n">RenderScript</span><span class="p">.</span><span class="n">Create</span> <span class="p">(</span><span class="n">Context</span><span class="p">);</span>
	<span class="kt">var</span> <span class="n">alloc</span> <span class="p">=</span> <span class="n">Allocation</span><span class="p">.</span><span class="n">CreateFromBitmap</span> <span class="p">(</span><span class="n">rsScript</span><span class="p">,</span> <span class="n">input</span><span class="p">);</span>

	<span class="kt">var</span> <span class="n">blur</span> <span class="p">=</span> <span class="n">ScriptIntrinsicBlur</span><span class="p">.</span><span class="n">Create</span> <span class="p">(</span><span class="n">rsScript</span><span class="p">,</span> <span class="n">alloc</span><span class="p">.</span><span class="n">Element</span><span class="p">);</span>
	<span class="n">blur</span><span class="p">.</span><span class="n">SetRadius</span> <span class="p">(</span><span class="m">12</span><span class="p">);</span>
	<span class="n">blur</span><span class="p">.</span><span class="n">SetInput</span> <span class="p">(</span><span class="n">alloc</span><span class="p">);</span>

	<span class="kt">var</span> <span class="n">result</span> <span class="p">=</span> <span class="n">Bitmap</span><span class="p">.</span><span class="n">CreateBitmap</span> <span class="p">(</span><span class="n">input</span><span class="p">.</span><span class="n">Width</span><span class="p">,</span> <span class="n">input</span><span class="p">.</span><span class="n">Height</span><span class="p">,</span> <span class="n">input</span><span class="p">.</span><span class="n">GetConfig</span> <span class="p">());</span>
	<span class="kt">var</span> <span class="n">outAlloc</span> <span class="p">=</span> <span class="n">Allocation</span><span class="p">.</span><span class="n">CreateFromBitmap</span> <span class="p">(</span><span class="n">rsScript</span><span class="p">,</span> <span class="n">result</span><span class="p">);</span>
	<span class="n">blur</span><span class="p">.</span><span class="n">ForEach</span> <span class="p">(</span><span class="n">outAlloc</span><span class="p">);</span>
	<span class="n">outAlloc</span><span class="p">.</span><span class="n">CopyTo</span> <span class="p">(</span><span class="n">result</span><span class="p">);</span>

	<span class="n">rsScript</span><span class="p">.</span><span class="n">Destroy</span> <span class="p">();</span>
	<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span></code></pre></div>

<p>The code will certainly look familiar to those of you who have already used OpenCL. You basically create a context (<code>RenderScript</code>), setup typed buffers (<code>Allocation</code>), create the kernel (<code>ScriptIntrinsicBlur</code>), define its entry point (<code>SetInput</code>) and execute it (<code>ForEach</code>).</p>

<p>Below is the result in a small app to select different blur radius:</p>

<p><img class="center" src="http://blog.neteril.org/wp-content/uploads/blur-renderscript/blurring.gif" /></p>

<p>You can read up <a href="http://developer.android.com/guide/topics/renderscript/compute.html#using-rs-from-java">Android basic guide on RenderScript</a> for a more in-depth explanation of each step.</p>

<p>Blur effects are becoming more and more trendy these days, being one of the design focus of iOS 7 and also used extensively by apps such as Rdio. With RenderScript you can now cheaply use that trick in your Android app too.</p>
]]></content>
  </entry>
  
</feed>
