<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Nicolas Duponchel on Medium]]></title>
        <description><![CDATA[Stories by Nicolas Duponchel on Medium]]></description>
        <link>https://medium.com/@nicolas.duponchel?source=rss-e1be2e24d25e------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*tRsvs3skOGn8fUoh.</url>
            <title>Stories by Nicolas Duponchel on Medium</title>
            <link>https://medium.com/@nicolas.duponchel?source=rss-e1be2e24d25e------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 11:14:16 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@nicolas.duponchel/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Custom ItemDecoration]]></title>
            <link>https://medium.com/@nicolas.duponchel/custom-itemdecoration-3b244de437d9?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/3b244de437d9</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[recyclerview]]></category>
            <category><![CDATA[divideritemdecoration]]></category>
            <category><![CDATA[viewtype]]></category>
            <category><![CDATA[itemdecoration]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Wed, 27 May 2020 11:19:12 GMT</pubDate>
            <atom:updated>2020-05-27T11:19:12.641Z</atom:updated>
            <content:encoded><![CDATA[<p>I had to build a custom item decorator and realised I hardly found answers on the web. So I’m writing this, hope it could help 😃</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*W3kRj1GmQar02mgKT5Dx5A.gif" /></figure><ol><li><strong>Simple ItemDecoration</strong></li><li><strong>Custom ItemDecoration<br></strong>1. ItemDecoration based on item position<br>2. ItemDecoration without last item<br>3. ItemDecoration base on item view type</li></ol><h3>1. Simple ItemDecoration : DividerItemDecoration</h3><p>The main use case can be achieved using DividerItemDecoration provided by Android.</p><pre>DividerItemDecoration(Context context, <em>int </em>orientation)</pre><blockquote><em>It</em> creates a divider <strong>RecyclerView.ItemDecoration</strong> that can be used with a LinearLayoutManager.<br><strong>@param context </strong>[…]<strong> </strong>will be used to access resources.<br><strong>@param orientation </strong>[…]<strong> </strong>should be #HORIZONTAL or #VERTICAL.</blockquote><p>What you need is to set the correct orientation, then provide a drawable used to split each item.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/62c5feb83ce8dee2071c8407e594bb39/href">https://medium.com/media/62c5feb83ce8dee2071c8407e594bb39/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*TRaAunLSi9Ap706REU1usA.gif" /><figcaption>Simple DividerItemDecoration</figcaption></figure><p><strong>Goods</strong></p><ul><li>4 lines of code</li><li>Provided by Android</li><li>Simple to use</li></ul><p><strong>Bads</strong></p><ul><li>As named : limited usage to divide with space or line</li><li>Limited to “infinity” scrolling use case : decoration will be drawn for each item, which means also the last one. Most of the time, we don’t want this.</li></ul><h3>2. Custom ItemDecoration</h3><p>For better control and more advanced things we’ll extend <a href="https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.ItemDecoration">RecyclerView.ItemDecoration</a>.</p><p>3 methods are available :<br>- <strong>getItemOffsets</strong> used to determine spacing between items.<br>- <strong>onDraw</strong> used to decorate space between items.<br>- <strong>onDrawOver</strong> is same that onDraw but after item itself is drawn.</p><p>📖 See official doc : <a href="https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.ItemDecoration#getItemOffsets(android.graphics.Rect,%20android.view.View,%20androidx.recyclerview.widget.RecyclerView,%20androidx.recyclerview.widget.RecyclerView.State)">getItemOffsets</a><strong>, </strong><a href="https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.ItemDecoration#onDraw(android.graphics.Canvas,%20androidx.recyclerview.widget.RecyclerView,%20androidx.recyclerview.widget.RecyclerView.State)">onDraw</a>, <a href="https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView.ItemDecoration#onDrawOver(android.graphics.Canvas,%20androidx.recyclerview.widget.RecyclerView,%20androidx.recyclerview.widget.RecyclerView.State)">onDrawOver</a></p><p>🔎 Please note following examples concern #Horizontal use cases. We can do same for #Vertical ones.</p><h4>2.1. Decoration based on Item POSITION</h4><p>Simple example to begin with: let’s decorate items on <strong>odd</strong> adapter position.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*SxKngpQAu7SDQzt45-HXwQ.gif" /><figcaption>Custom ItemDecoration based on item View position</figcaption></figure><p>Main instruction here is parent.getChildAdapterPosition(view).</p><blockquote><em>It</em> Returns the adapter position that the given child view corresponds to<em>. See </em><a href="https://developer.android.com/reference/kotlin/androidx/recyclerview/widget/RecyclerView#getchildadapterposition"><em>complete doc</em></a><em>.</em></blockquote><blockquote><em>⚠️ Not to be confused with the parent’s children positions (</em><em>parent.children are items displayed on screen).</em></blockquote><blockquote><em>⚠️ Be careful not to miss </em><em>RecyclerView.NO_POSITION case : </em><em>getChildAdapterPosition could return </em><em>-1.</em></blockquote><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1b6a98ea45b1f0c9ef21320ed5f5b6ef/href">https://medium.com/media/1b6a98ea45b1f0c9ef21320ed5f5b6ef/href</a></iframe><h4>2.2. Remove last item decoration</h4><p>This is the most common use case you guys are asking on stackoverflow. It’s a special case of custom ItemDecoration based on items’ adapter position.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*5I8_m09wRPPY25jMHY0ngw.gif" /><figcaption>Custom DividerItemDecoration excluding last item decoration</figcaption></figure><p>Exclude last item if(childAdapterPosition == adapter.itemCount-1).</p><p>⚠️ parent.adapter is nullable</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d3a2fab4e24e7b68bf36e47223a40d08/href">https://medium.com/media/d3a2fab4e24e7b68bf36e47223a40d08/href</a></iframe><p>🔎 Note that in almost cases, you probably only need spacing between your items (last one excluded). No need to override onDraw method, setting the correct Rect size in getItemsOffsets method is enough.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*3heyFqrymbDKUwzTPkokcg.gif" /><figcaption>Custom DividerItemDecoration excluding last item spacing decoration</figcaption></figure><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a3cdd76e0ad1fc7388cc1302701f2395/href">https://medium.com/media/a3cdd76e0ad1fc7388cc1302701f2395/href</a></iframe><h4>2.3. Decoration based on item view Type</h4><p>For this example we have 2 item types illustrated in black and grey. We decorate items with blue and red Drawables depending on item View type (declared in Adapter).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*J075kzryjvG4RtNuoyNv1w.gif" /><figcaption>Custom ItemDecoration based on item View type</figcaption></figure><p>Main instruction here is adapter.getItemViewType(childAdapterPosition). We need to override getItemViewType method in our Adapter.</p><blockquote><em>It </em>returns the view type of the item at position for the purposes of view recycling.<em>[…]</em> Consider using id resources to uniquely identify item view types.</blockquote><blockquote><em>See </em>getItemViewType<em> </em><a href="https://developer.android.com/reference/android/widget/Adapter#getItemViewType(int)"><em>official doc</em></a>.</blockquote><p>Once you’re able to identify your item View type, you can put the correct spacing, and decorate as you wish 😉.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6357c2044ca814f7c17d9302e236c69a/href">https://medium.com/media/6357c2044ca814f7c17d9302e236c69a/href</a></iframe><p>You can find the full GitHub repo on <a href="https://github.com/NicolasDuponchel">my GitHub page</a> or just below 😉</p><p><a href="https://github.com/NicolasDuponchel/CustomItemDecoration">NicolasDuponchel/CustomItemDecoration</a></p><p>If it helped follow and 👏 ! Thanks you readers 🙏</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3b244de437d9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android onTouch for Dummies]]></title>
            <link>https://medium.com/@nicolas.duponchel/android-ontouch-for-dummies-45274dcc4a2b?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/45274dcc4a2b</guid>
            <category><![CDATA[ontouchevent]]></category>
            <category><![CDATA[zoom]]></category>
            <category><![CDATA[gesturedetector]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[scalegesturedetector]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Wed, 14 Aug 2019 12:55:49 GMT</pubDate>
            <atom:updated>2020-10-02T09:03:48.407Z</atom:updated>
            <content:encoded><![CDATA[<h3>Android <strong>onTouch &amp; GestureDetector </strong>for Dummies</h3><p>This article explains how to use GestureDetector in Android.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Vf_bo4qAZYtQtqpUEi0sNA.jpeg" /></figure><p>All of us have already deal with android touch events with or without success!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/375/1*HIAmTCchqoVAWgZyvVYpVQ.gif" /></figure><p>Everything begins with a simple setOnClickListener{}, then comes the need to translate, scale, rotate, or do stuff with your View. So, most of android developers (including me of course) would say : “<em>ok let’s create a custom onTouchListener, look events, then identify it and do what I need to do with it!</em>”. Here is an example of what could <strong>(but should not)</strong> be done:</p><pre>class CustomTouchListener(private val view: View) : View.OnTouchListener {<br>    private val actionDownPoint = PointF(0f, 0f)<br>    private val actionMoovePoint = PointF(0f, 0f)<br>    private var touchDownTime = 0L<br><br>    override fun onTouch(v: View, event: MotionEvent) = when (event.<em>action</em>) {<br>        MotionEvent.<em>ACTION_DOWN </em>-&gt;<br>            PointF(event.<em>x</em>, event.<em>y</em>).<em>let </em><strong>{<br>                </strong>actionDownPoint.set(<strong>it</strong>)<br>                actionMoovePoint.set(<strong>it</strong>)<br>                touchDownTime = System.currentTimeMillis()<br>                true<br>            <strong>}<br>        </strong>MotionEvent.<em>ACTION_MOVE </em>-&gt;<br>            PointF(event.<em>x</em>, event.<em>y</em>).<em>let </em><strong>{<br>                </strong>// DO YOUR TRANSLATE ACTION HERE<br>                actionMoovePoint.set(<strong>it</strong>)<br>                true<br>            <strong>}<br>        </strong>MotionEvent.<em>ACTION_UP </em>-&gt;<br>            PointF(event.<em>x</em>, event.<em>y</em>).<em>let </em><strong>{<br>                </strong>val isTouchDuration = System.currentTimeMillis() - touchDownTime &lt; 200<br>                val isTouchLength = <em>abs</em>(<strong>it</strong>.x - actionDownPoint.x) + <em>abs</em>(<strong>it</strong>.y - actionDownPoint.y) &lt; 25<br>                val shouldClick = isTouchLength &amp;&amp; isTouchDuration<br>                //OVERRIDE AND SEND CLICK EVENT<br>                if (shouldClick) view.performClick() <br>                true<br>            <strong>}<br>        </strong>else -&gt; false<br>    }<br>}</pre><h3>GestureDetector</h3><p>🤔 That sounds like reinventing the wheel don’t you think? GestureDetector will avoid that loss of time. Let’s see an example:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/371785059fd5385a5b3642d9c1f720ea/href">https://medium.com/media/371785059fd5385a5b3642d9c1f720ea/href</a></iframe><p>All that you need is onSingleTapUp and onScroll. In this case you don’t really care about onFling or others don’t you? Yet again, there is nothing to get up to. You can use SimpleGestureDetector which overrides all methods with empty body, and then you only override methods you need.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/10ded466b37c163449b554a0db5a147a/href">https://medium.com/media/10ded466b37c163449b554a0db5a147a/href</a></iframe><p>Now you’ve got your <strong>scroll</strong> and <strong>tap</strong> event. GestureDetectorListener is ready, final step is to call it in your view → override onTouchEvent method.</p><pre>private val gestureDetector =<br>    GestureDetector(context, MySimpleGestureDetectorListener())<br><br>override fun onTouchEvent(event: MotionEvent) =<br>    gestureDetector.onTouchEvent(event)</pre><blockquote>Note that GestureDetector also provides <a href="https://developer.android.com/reference/android/view/GestureDetector.OnDoubleTapListener">OnDoubleTapListener</a> and <a href="https://developer.android.com/reference/android/view/View.OnContextClickListener">OnContextClickListener</a> ( <a href="https://stackoverflow.com/a/35330198/10030894">What’s onContextClick ?</a> )</blockquote><blockquote>Note that if you’re not using androidX yet you could use <a href="https://developer.android.com/reference/android/support/v4/view/GestureDetectorCompat">GestureDetectorCompat</a></blockquote><h3>ScaleGestureDetector</h3><p>Ok guys, something is still lacking. What about zooming events? Just add <em>Scale</em> before! <a href="https://developer.android.com/reference/android/view/ScaleGestureDetector">ScaleGestureDetector</a> will do the job.</p><pre>class MyScaleGestureDetectorListener :<br>    ScaleGestureDetector.OnScaleGestureListener {<br><br>    override fun onScaleBegin(detector: ScaleGestureDetector) =true<br><br>    override fun onScaleEnd(detector: ScaleGestureDetector) {}<br><br>    override fun onScale(detector: ScaleGestureDetector) = true<br><br>}</pre><p>Here again we could use SimpleOnScaleGestureListener the same way.</p><h3>GestureDetector + ScaleGestureDetector</h3><p>What if you want to handle <strong>zoom</strong> and <strong>scroll</strong>? Obviously you could create a class which implements both OnGestureListener and OnScaleGestureListener, but here comes the tricky part. You need to handle both listeners events.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e7d3febc2c5a16f3904ceb961819eb05/href">https://medium.com/media/e7d3febc2c5a16f3904ceb961819eb05/href</a></iframe><p>Note that <a href="https://developer.android.com/training/gestures/scale">android doc</a> calls the detector the following way, but in some case you will need to check if a scale gesture is in progress. See that <a href="https://stackoverflow.com/a/47168465/10030894">stackverflow topic</a>.</p><pre>fun handleTouchEvents(event: MotionEvent) =<br>    scaleGestureDetector.onTouchEvent(event)<br>        || gestureDetector.onTouchEvent(event)</pre><h3>CustomGestureDetector</h3><p>Final code of your custom gesture detector.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9209107147118f43f98e9d211a81e710/href">https://medium.com/media/9209107147118f43f98e9d211a81e710/href</a></iframe><p>Then you pass the context and the Listener as params, and call it in onTouchEvent() in your View.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f17afbb38a41829c7b801a55a2df62e0/href">https://medium.com/media/f17afbb38a41829c7b801a55a2df62e0/href</a></iframe><h3>Note</h3><p>Thanks to Google, android native zoom (scale detector) is caped to a minimal distance. If your fingers are to close, it will trigger onScaleEnd() 😢 They communicated this aswon&#39;t fix ! Get more info <a href="https://stackoverflow.com/questions/45958725/scalegesturedetector-on-android-fires-onscaleend-when-pointers-get-too-close">on this post</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=45274dcc4a2b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[android.graphics.Matrix functional approach]]></title>
            <link>https://medium.com/@nicolas.duponchel/android-graphics-matrix-functional-approach-de31e2a4902c?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/de31e2a4902c</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[matrix]]></category>
            <category><![CDATA[functional-programming]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[video-editing]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Mon, 05 Aug 2019 14:36:37 GMT</pubDate>
            <atom:updated>2019-08-07T09:59:28.195Z</atom:updated>
            <content:encoded><![CDATA[<h3>Introduction</h3><p>Over the half year that I have been a member of GoPro team, I had to deal with media edition. Here it comes my experience on <a href="https://developer.android.com/reference/android/graphics/Matrix.html">android.graphics.Matrix</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5VRq9ikEhOMicWA9cMxaog.jpeg" /></figure><p><strong>Rotation</strong>, <strong>zoom</strong>, <strong>translation</strong> are basic transforms I needed to apply to images or videos. All those can be done with matrix operations, then applying the resulting transform to a <a href="https://developer.android.com/reference/android/view/TextureView">TextureView</a>.</p><p>Let’s see an example</p><pre>fun simpleExampleTransform() {<br>    val matrix = Matrix()<br>    matrix.preRotate(90f, 0.5f, 0.5f)<br>    matrix.preTranslate(97f, 4f)<br>    matrix.preScale(12f, 1f)<br><br>    <em>textureView</em>.setTransform(matrix)<br>}</pre><h3>Functional motivation</h3><p>As a supporter of functional approach, I would have expected <em>android.graphics.Matrix </em>class’<em> </em>methods to return the result of the operation as a Matrix object. This is not the case and most of them return a boolean. Thanks to Kotlin extensions I re-wrote the Matrix API (at least methods I needed) to respect functional approach.</p><p>3 main transform kotlin extensions</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/62dee7bbe51a0a04e38a758b3ecb664a/href">https://medium.com/media/62dee7bbe51a0a04e38a758b3ecb664a/href</a></iframe><p>Previous example can be written</p><pre>fun simpleFunctionalExampleTransform() {<br>    val center = PointF(0.5f, 0.5f)<br><br>    <em>textureView</em>.setTransform(<br>        Matrix()<br>            .<em>translate</em>(97f, 4f)<br>            .<em>scale</em>(12f, 1f, center)<br>            .<em>rotate</em>(90f, center)<br>    )<br>}</pre><h3>Going further</h3><p>Those methods simplify operations. But in some cases I just need to concat transform matrices. Let’s consider I have 3 different media-editing widgets that give me 3 matrices rotationMatrix, translationMatrix, scaleMatrix. The final transform is the multiplication of those 3 matrices.</p><pre>fun simpleExampleTransform(<br>    rotationMatrix: Matrix,<br>    translationMatrix: Matrix,<br>    scaleMatrix: Matrix<br>): Matrix {<br>    val finalTransform = Matrix()<br>    finalTransform.preConcat(rotationMatrix)<br>    finalTransform.preConcat(translationMatrix)<br>    finalTransform.preConcat(scaleMatrix)<br>    return finalTransform<br>}</pre><blockquote>If you’re not confortable with set / pre / post operations please have a look at <a href="https://stackoverflow.com/a/8197896">that stackoverflow answer</a>.</blockquote><p>Same story for concat method, it could look like following</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8ef18eb7e38c55d66b7b46b89b38a966/href">https://medium.com/media/8ef18eb7e38c55d66b7b46b89b38a966/href</a></iframe><p>Then, the previous example can be written</p><pre>fun simpleFunctionalExampleTransform(<br>    rotationMatrix: Matrix,<br>    translationMatrix: Matrix,<br>    scaleMatrix: Matrix<br>): Matrix = rotationMatrix<br>    .<em>concat</em>(translationMatrix)<br>    .<em>concat</em>(scaleMatrix)</pre><h3>Conclusion</h3><p>All the android.graphics.Matrix could be extended the same way and finally answer the functional approach.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=de31e2a4902c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android ScaleType bottomCrop instead of centerCrop]]></title>
            <link>https://medium.com/@nicolas.duponchel/android-scaletype-bottomcrop-instead-of-centercrop-e22c7b27b2c3?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/e22c7b27b2c3</guid>
            <category><![CDATA[bottomcrop]]></category>
            <category><![CDATA[centercrop]]></category>
            <category><![CDATA[scaletype]]></category>
            <category><![CDATA[imageview]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Sun, 13 Jan 2019 00:41:33 GMT</pubDate>
            <atom:updated>2019-01-13T00:41:33.705Z</atom:updated>
            <content:encoded><![CDATA[<p>Android offers 8 scale types.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/964/1*oeh8V-5f_EE8K31hFi2W-g.png" /></figure><p>But 2 scale types are missing ! I would like something like</p><p>android:scaleType=&quot;centerCrop|fitBottom&quot;</p><p>android:scaleType=&quot;centerCrop|fitTop&quot;</p><p>So I created a customImageView with those two new scale types. I reuse the MATRIX type, and then rewrite the setFrame method to redraw the right way.</p><pre>val drawableRect = when (matrixType) {</pre><pre>    MatrixType.FIT_BOTTOM -&gt; <br>        RectF(0f, drawableHeight - x, drawableWidth, drawableHeight)<br>    <br>    MatrixType.FIT_TOP -&gt; <br>        RectF(0f, 0f, drawableWidth, x)</pre><pre>}</pre><p>The CustomView full code is <a href="https://github.com/NicolasDuponchel/ScalableImageView/blob/master/scalable-image-view/src/main/java/duponchel/nicolas/ImageView.kt">here</a> ! 😃</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hzjc8UWzaxYwkJT0iz3mRw.png" /></figure><p><a href="https://github.com/NicolasDuponchel/ScalableImageView/blob/master/scalable-image-view/src/main/java/duponchel/nicolas/ImageView.kt">NicolasDuponchel/ScalableImageView</a></p><p>And the Android project is also available <a href="https://github.com/NicolasDuponchel/ScalableImageView">on GitHub</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/540/1*qYtXHuFX_SmcWsM8N4jDRw.png" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e22c7b27b2c3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[RxKotlin — Completable.atLeast(delay)]]></title>
            <link>https://medium.com/@nicolas.duponchel/rxkotlin-completable-atleast-delay-2fe27e637467?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/2fe27e637467</guid>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[rxkotlin]]></category>
            <category><![CDATA[time]]></category>
            <category><![CDATA[rxjava]]></category>
            <category><![CDATA[delay]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Mon, 03 Dec 2018 21:13:24 GMT</pubDate>
            <atom:updated>2018-12-03T21:13:24.593Z</atom:updated>
            <content:encoded><![CDATA[<h3>RxKotlin — Completable.atLeast(delay)</h3><p><strong>Goal</strong> : A minimal elapsed time before an Observable emits its result.</p><p><strong>Motivation</strong> : For example, displaying a splash screen while performing initialization jobs. For fast devices, those jobs might be too fast to let the users contemplate the wonderful cat picture you placed on this splash screen. 🙀</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sct5KczOA6Xha4YKlxN1fw.png" /></figure><h3>The first solution</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/59ca607bdc8926a0e6994f641314738d/href">https://medium.com/media/59ca607bdc8926a0e6994f641314738d/href</a></iframe><p>Single.timer(delay, unit) returns a Single that emits a success with 0L value after the given delay.</p><p>this.toSingleDefault(Unit) converts the Completable into a Single which when this Completable completes normally, emits the given value through onSuccess.</p><p>single1.zipWith(single2) returns a Single that emits the result of applying a specified function to the pair of items emitted by the first and the second Single.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/505/1*0L__T1e1j3PkhwoB6tIBzA.png" /></figure><p>single.ignoreElement() returns a Completable that ignores the success value of this Single and calls onComplete instead on the returned Completable. Note that it does the same that toCompletable() function, but this one is dreprecated, and will be removed in <em>3.0</em>. 😙</p><p>This first solution does the job. But if we take a look at errors handling, we’ll see that this solution may not be the one we expect. In fact when your Completable emits an error, the stream will be broken. Then onError() will directly be called.</p><h3>The second solution</h3><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c4df1cf97f07a2028e8a35a36e78d8c6/href">https://medium.com/media/c4df1cf97f07a2028e8a35a36e78d8c6/href</a></iframe><p>Observable.timer() does the same that for Singles, but returns an Observable.</p><p>completable.toObservable() converts a Completable into an Observable and relays the terminal events to the subscriber.</p><p>observable.ignoreElement() does the same that for Singles.</p><p>Observable.mergeDelayError(observable1, observable2) is mainly the same that a simple merge. The main difference is that it allows the Observer to receive all successfully emitted items from each of observable1 and observable2 without being interrupted by an error notification from one of them.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/505/1*miazMorX0mW_NyHpyptHnw.png" /></figure><p>With this solution, whatever the emission of your completable, it will be emitted after the wanted elapsed time. 👏</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2fe27e637467" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android Views animation — Kotlin extension]]></title>
            <link>https://medium.com/@nicolas.duponchel/kotlin-extension-to-animate-view-33b1aecc5748?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/33b1aecc5748</guid>
            <category><![CDATA[extension-functions]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[animation]]></category>
            <category><![CDATA[onanimationevent]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Wed, 04 Jul 2018 13:55:08 GMT</pubDate>
            <atom:updated>2018-07-10T09:59:11.730Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zr8QYYJPWxh-kpoSBUeZyQ.png" /></figure><p>This extension is perfect to manage <strong>onAnimationStart, onAnimationRepeat &amp; onAnimationEnd</strong>. No need to rewrite an AnimationListener each time ! Just have a look.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5a0924fd5e1be9407ba5db01acdc2ad9/href">https://medium.com/media/5a0924fd5e1be9407ba5db01acdc2ad9/href</a></iframe><p>With this extension you can easily add animation and precise what to do on animation events.</p><pre>my_view.<em>playAnimation</em>(<br>    animResId = R.anim.<em>rotate</em>,<br>    onAnimationEnd = <strong>{ </strong>your action here <strong>}<br></strong>)</pre><p>And that’s it ! 😄</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=33b1aecc5748" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android developer trying to play with this thing called iOS ]]></title>
            <link>https://medium.com/@nicolas.duponchel/android-developer-trying-to-play-with-this-thing-called-ios-2b7d80012449?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/2b7d80012449</guid>
            <category><![CDATA[android-vs-ios]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[pods]]></category>
            <category><![CDATA[rest-api]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Mon, 25 Jun 2018 12:50:30 GMT</pubDate>
            <atom:updated>2018-06-25T16:06:30.448Z</atom:updated>
            <content:encoded><![CDATA[<p>I write this article to share my early stages moving from Android to iOS.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/299/1*QZxKsHayfa5wKjg0ZMvQuQ.jpeg" /></figure><p>In this <a href="https://medium.com/@nicolas.duponchel/rx-java-for-beginners-8b7c1e7bfc44">previous article</a>, I explain how to call a public REST API. This project uses RxKotlin, LiveData, retrofit… It is a simple example of basic MVVM Android app. I asked myself how could I do same on iOS. Let’s have a look !</p><h3>Running Xcode</h3><p>Prerequisite : A Macbook with Xcode installed and an iTunes identifier.<br>Install Xcode and run a new project. Select Single View App. Do not care about CoreData and tests. Believe me, do not choose Objective-C, unless you love pain. Swift is probably the thing that could change android developers’ mind about iOS, especially when you already use Kotlin.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/564/1*6lOwV184Z2Q5JrHXb9Qqgw.png" /></figure><p>😱 There is no Activity, no Manifest, no res, no Gradle... Don’t panic, it’s gonna be alright !</p><p><strong>AppDelegate</strong> is the equivalent to your android Application file. You will see that the methods are similar in Android : applicationWillResignActive, applicationDidEnterBackground … with some coments to explain.</p><p><strong>ViewController</strong> could be your MainActivity. Methods are similar too : viewDidLoad for example is quiet the same that onResume.</p><p><strong>Main.storyboard</strong> is the ios equivalent to your .xml file but there are some differences.</p><p><strong>Assets.xcassets</strong> is the folder you could compare to <strong>res</strong> in Android. By the way iOS do not natively manage .svg files. So forget about your lovely Android vectors.</p><p><strong>Info.plist</strong> make me think to a mix between the main Gradle file and the manifest.</p><p><strong>LaunchScreen.storyboard</strong> is the bonus. Do you remember the first time you tried to implement a splash screen ? This file is literally an “iOS splash screen”. No need to do anything more in the code.</p><h3>Creating a view</h3><p>Dear Android developers, have you ever tried to drag and drop any UI component to build your views ? If you already succeed once, I beg you to show me how.<br>Building views in iOS is absolutely different, you can unplug your keyboard ! (ok I am exaggerating a bit, but a very little) Let’s try.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*KWvJFdj99THTAJon97TKKQ.gif" /></figure><p>As you can see above, I just need to drag and drop a Label on the <strong>Main.storyboard</strong>. Then I add some constraints :</p><ul><li>center X</li><li>center Y</li><li>leading (left)</li><li>trailing (right)</li></ul><p>The trick is to maintain <strong>ctrl</strong> while you are dragging the Object to choose on which other component to place constraints. In this case the four constraints are related to the <strong>Safe Area</strong>. Thanks to iPhoneX and its beautiful notch, iOS introduced this view called Safe Area where you are sure nothing will be hidden.</p><p><strong>Tip :</strong> Set Lines to 0 if you want your Label to use as much lines as needed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/502/1*TJNLWRCWgxaz8qiBhY9tow.png" /></figure><p>I confess, I find this way of building views pretty cool ! 🙌 +1 for iOS.</p><h3>External libs import</h3><p>As you can see above, I deployed an application but I didn’t write any code line. Let’s go “deeper” through the code. I’m gonna try to call a REST API. That for, I need to import <a href="https://github.com/Moya/Moya">Moya</a>. This lib is a kind of extension of <a href="https://github.com/Alamofire/Alamofire">Alamofire</a> and facilitate http networking. Damn there is no Gradle ! How could we import something in the project ?</p><p>There is something called <strong>pod</strong> in iOS which is used to import libs in a project. This is managed by <a href="https://cocoapods.org/">Cocoapod</a>, it is well documented. Moreover this is an open source lib stored on GitHub.</p><pre>$ sudo gem install cocoapods</pre><p>I create my Podfile</p><pre>$ pod init</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/756/1*zM5GrvizTLlhxC2PVzoX5A.png" /><figcaption>Write your Podfile</figcaption></figure><p>Save your Podfile in First API call directory. Then navigate to your folder and install your pod as follow</p><pre>$ pod install</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*b4TfoMiW7Pu0jIy_n8uPjw.png" /><figcaption>pod install</figcaption></figure><p>Close Xcode and double click on <strong>First API call.xcworkspace. </strong>And you are now ready to use your libs.</p><p>I find the iOS way to import libs a bit weird on first approach. In Android I just add the line bellow to build.gradle and sync. +1 for Android ! 😙 But there is no doubt, Cocoapods is easy to use, and all libs needed are precised in the Podfile.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EEVT-QnAuzKrmtTugrqsDg.png" /><figcaption>Android way to import lib</figcaption></figure><h3>Calling REST API</h3><p>I will now call <a href="http://api.icndb.com/jokes/random">this Chuck Norris Api</a>. I already explained the structure of its response in <a href="https://medium.com/@nicolas.duponchel/rx-java-for-beginners-8b7c1e7bfc44">this article</a>, so do not hesitate to have a look.</p><p>The structure is almost the same that in my android project, I create the following files :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/522/1*xTbg376GmWT4y1Ccb0EWJg.png" /><figcaption>Files needed</figcaption></figure><p>The first file to create is <strong>ChuckNorrisApi</strong>. It implements the protocol TargetType of Moya. It contains all needed informations about the API (Urls, headers, parameters …).</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/55082ccea112f75b3b699f5b11e5f575/href">https://medium.com/media/55082ccea112f75b3b699f5b11e5f575/href</a></iframe><p><strong>ChuckNorrisApiService</strong> is the file where to precise how to use <strong>ChuckNorrisApi</strong>. It just contains two methods getJoke(…) which call the API.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/80ef6aca7f821e709de17f63ef9340bc/href">https://medium.com/media/80ef6aca7f821e709de17f63ef9340bc/href</a></iframe><p><strong>ChuckNorrisResponse</strong> and <strong>Joke</strong> are my Objects corresponding to the Json returned by the API. In Kotlin I would have declared data classes, in swift we can use NSObject. Joke and Response will implement ALSwiftyJSONAble protocol which manages Json translation to Object. By the way, it looks like Serializable in Android.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ceb7c8c5162a9e941af53f45ac7c461c/href">https://medium.com/media/ceb7c8c5162a9e941af53f45ac7c461c/href</a></iframe><p>Finally I subscribe to my service in my ViewController.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/6e80de7c8896a2e9451128e9737ccf2d/href">https://medium.com/media/6e80de7c8896a2e9451128e9737ccf2d/href</a></iframe><h3>UI components</h3><p>Now that API is ready, let’s build a button and display the requested joke on the screen. Remember My Label ? Get back on Main.storyboard, and do same with a button.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*hfq9ft_6CNo0B9VtDXsS5Q.gif" /><figcaption>New button</figcaption></figure><p>Time has come to set my onClickListener and change my label text. I hope you did not put your mouse away guys! 🖱</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*18MzXTJNP8E4gAkiYVwdAw.gif" /><figcaption>Binding</figcaption></figure><p>As you can see above, I just need to drag and drop to reference the label in my ViewController, and same for my button click event. I choose the Touch Up Inside event with the interface builder which I named onNewJokeRequested(). Finally, I just need to call getJoke() and I update the label text with my response.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ef3b71b57f294cb2546b8ebb82529710/href">https://medium.com/media/ef3b71b57f294cb2546b8ebb82529710/href</a></iframe><h3>Permissions</h3><p>In iOS, android permissions equivalent are set in the Info.plist. To call a public REST API, the needed one are the following :</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/912/1*d4iNNLx0Eg4ccYVWMQbNuQ.png" /></figure><h3>Run the App</h3><p>Your app is ready ! <strong>cmd+r</strong> and let’s see the result.</p><h3>Conclusion</h3><p>It is quiet easy to start learning iOS when you are mastering Android. I still have a preference for Kotlin language. I find it more powerful especially with data classes, side effect methods, null check, etc… But I admit iOS and Android os are really close.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*JnBuYQXMeUl2B9OSxrFr7w.jpeg" /></figure><p>For those who would like to go further on this project, please check the github repo !</p><p><a href="https://github.com/NicolasDuponchel/ChuckNorris-iOS-API">NicolasDuponchel/ChuckNorris-iOS-API</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2b7d80012449" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Parameterized unit tests]]></title>
            <link>https://medium.com/@nicolas.duponchel/kotlin-parameterized-unit-tests-13f6bf2316a8?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/13f6bf2316a8</guid>
            <category><![CDATA[parameterized]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[unit-testing]]></category>
            <category><![CDATA[kotlin]]></category>
            <category><![CDATA[junit]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Sat, 26 May 2018 16:52:39 GMT</pubDate>
            <atom:updated>2018-05-28T06:47:31.044Z</atom:updated>
            <content:encoded><![CDATA[<p>Tired to write 28 times the same test with different values ? Keep calm and parameterize your tests.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*qkxiFG_AAGHGcqVQyy9XaA.gif" /></figure><p>Simple example, a function converting Int into an Error</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/550/1*ixxJCJqfukCJtTshcxIUiw.png" /></figure><pre>enum class ERROR {<br>    ANDROID,<br>    NETWORK,<br>    HUMAN,<br>    UNICORN,<br>    FIRE,<br>    HOMER_SIMPSON,<br>    BANANA,<br>    UNKNOWN<br>}<br><br>fun Int.toError() = when (this) {<br>    22000, 1890 -&gt; ANDROID<br>    404 -&gt; NETWORK<br>    1111 -&gt; HUMAN<br>    999, 888 -&gt; UNICORN<br>    666 -&gt; FIRE<br>    123456 -&gt; HOMER_SIMPSON<br>    8 -&gt; BANANA<br>    else -&gt; UNKNOWN<br>}</pre><p>Let’s focus now on unit test. The first approach would be to write as many tests as there are known error codes. Which means the following code would be written 10 times in our case.</p><pre>@Test<br>fun `toError returns ANDROID if code is 22000`() {<br>    val errorCode = 22000<br>    val error = errorCode.<em>toError</em>()<br>    Truth.assert_().that(error).isEqualTo(ANDROID)<br>}</pre><p>What if we had to deal with much more error codes ? Junit offers the possibility to parameterize your tests. Let’s have a look at it.</p><p>The goal is to write a single unit test and to precise which parameters to use. Then junit does the rest.</p><pre>@RunWith(Parameterized::class)<br>class ErrorTranslatorParameterizedTest(<br>    private val errorCode: Int,<br>    private val error: ERROR<br>) {<br>    companion object {<br>        @JvmStatic<br>        @Parameterized.Parameters<br>        fun errorCode() = <em>listOf</em>(<br>            <em>arrayOf</em>(22000, ANDROID),<br>            <em>arrayOf</em>(1890, ANDROID),<br>            <em>arrayOf</em>(404, NETWORK),<br>            <em>arrayOf</em>(1111,HUMAN),<br>            <em>arrayOf</em>(999,UNICORN),<br>            <em>arrayOf</em>(888,UNICORN),<br>            <em>arrayOf</em>(666,FIRE),<br>            <em>arrayOf</em>(123456,HOMER_SIMPSON),<br>            <em>arrayOf</em>(8, BANANA),<br>            <em>arrayOf</em>(0, UNKNOWN)<br>        )<br>    }<br><br>    @Test<br>    fun `toError returns good values`() =<br>        assert_().that(errorCode.<em>toError</em>()).isEqualTo(error)<br>}</pre><p>And that’s it !</p><p><a href="https://github.com/NicolasDuponchel/ParameterizedUnitTest.git">NicolasDuponchel/ParameterizedUnitTest</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=13f6bf2316a8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Testing ViewModel in MVVM using LiveData and RxJava]]></title>
            <link>https://medium.com/@nicolas.duponchel/testing-viewmodel-in-mvvm-using-livedata-and-rxjava-b27878495220?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/b27878495220</guid>
            <category><![CDATA[mvvm]]></category>
            <category><![CDATA[unit-testing]]></category>
            <category><![CDATA[livedata]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[viewmodel]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Wed, 23 May 2018 15:22:27 GMT</pubDate>
            <atom:updated>2018-05-24T08:52:24.603Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/936/1*H-YNHFvea43zBidS5uA7aQ.png" /></figure><p>In my team, we tried out the MVVM architecture with android.arch.lifecycle from Google. No doubt it’s amazing. This article points out how to write ViewModel unit tests.</p><ul><li>Gradle libraries</li><li>Testing LiveData values</li><li>Mocking RxJava with trampoline</li></ul><h4>Gradle</h4><p>I use mockito and google truth.</p><pre>testImplementation &quot;junit:junit:4.12&quot;<br>testImplementation &quot;com.google.truth:truth:0.36&quot;<br>testImplementation &quot;org.mockito:mockito-core:2.13.0&quot;<br>testImplementation &quot;android.arch.core:core-testing:1.1.1&quot;</pre><h4>Testing LiveData values</h4><p>The right way to test LiveData is to store their values in a particular list, then look over this list and check if the content is correct.</p><p>First of all, let’s create our custom Observer to populate the list.</p><pre>class TestObserver&lt;T&gt; : Observer&lt;T&gt; {<br><br>    val observedValues = <em>mutableListOf</em>&lt;T?&gt;()<br><br>    override fun onChanged(value: T?) {<br>        observedValues.add(value)<br>    }<br>}</pre><p>Then, the extension function to use it.</p><pre>fun &lt;T&gt; LiveData&lt;T&gt;.testObserver() = TestObserver&lt;T&gt;().<em>also </em><strong>{<br>    </strong>observeForever(<strong>it</strong>)<br><strong>}</strong></pre><p>A specific TestRule is required for testing architecture components : InstantTaskExecutorRule. Finally here is the test.</p><pre>@get:Rule<br>val mockitoRule = MockitoJUnit.rule()<br><br>@get:Rule<br>val taskExecutorRule = InstantTaskExecutorRule()<br><br>@InjectMocks<br>lateinit var classUnderTest: YourViewModel</pre><pre>@Test<br>fun `init method sets liveData value to empty list`() {<br>    val liveDataUnderTest = classUnderTest.liveData.testObserver()<br><br>    Truth.assert_()<br>        .that(liveDataUnderTest.<em>observedValues</em>)<br>        .isEqualTo(<em>listOf</em>(<em>emptyList</em>&lt;String&gt;()))<br>}</pre><p>Cool isn’t it ? But why do we need a List to store nothing ? Let’s go deeper and have a look at the following example. It is an installation and the screen takes 3 states.</p><pre>@Test<br>fun `onInstall set correct screen states`() {<br>    val liveDataUnderTest = classUnderTest.screenState.testObserver()</pre><pre>    classUnderTest.onInstall()</pre><pre>    Truth.assert_()<br>        .that(liveDataUnderTest.<em>observedValues</em>)<br>        .isEqualTo(<em>listOf</em>(INITIAL, LOADING, INSTALLED))<br>}</pre><h4>Testing Rx methods</h4><p>Now that we’ve done with LiveData values, let’s have a look at Rx. If we try to run the previous test with onInstall() which use Rx, we face to this error :</p><blockquote>java.lang.AssertionError: Not true that &lt;[INITIAL]&gt; is equal to &lt;[INITIAL, LOADING, INSTALLED]&gt;</blockquote><p>The task is executed on parallel with <em>io</em> Scheduler. That’s why the test execution is faster than the operation on background. The values <em>LOADING</em> and <em>INSTALLED</em> have no time to be set before the test ends.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*Cj1UGTisMQzcnMc2u2nHLg.gif" /><figcaption>Rx Trampoline</figcaption></figure><p>What’s beautiful with RxJava is that everything your may need already exists. To achieve unit testing, there’s a specific scheduler called Trampoline. All jobs that subscribes to it will be queued and excuted one by one. Let’s create a new TestRule to use it.</p><pre>class RxSchedulerRule : TestRule {<br><br>    override fun apply(base: Statement, description: Description) =<br>        object : Statement() {<br>            override fun evaluate() {<br>                RxAndroidPlugins.reset()<br>                RxAndroidPlugins.setInitMainThreadSchedulerHandler <strong>{ </strong>SCHEDULER_INSTANCE <strong>}<br><br>                </strong>RxJavaPlugins.reset()<br>                RxJavaPlugins.setIoSchedulerHandler <strong>{ </strong>SCHEDULER_INSTANCE <strong>}<br>                </strong>RxJavaPlugins.setNewThreadSchedulerHandler <strong>{ </strong>SCHEDULER_INSTANCE <strong>}<br>                </strong>RxJavaPlugins.setComputationSchedulerHandler <strong>{ </strong>SCHEDULER_INSTANCE <strong>}<br><br>                </strong>base.evaluate()<br>            }<br>        }<br><br>    companion object {<br>        private val SCHEDULER_INSTANCE = Schedulers.trampoline()<br>    }<br>}</pre><p>Just need to add this TestRule to the test.</p><pre>@get:Rule<br>val rxSchedulerRule = RxSchedulerRule()</pre><blockquote>Process finished with exit code 0</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/630/1*wtPWAJG1vWBO-Sr4QAZqLQ.jpeg" /></figure><p>For those who would be more curious, I wrote this article using <a href="https://medium.com/@nicolas.duponchel/rx-java-for-beginners-8b7c1e7bfc44">a previous MVVM project</a> on which I added some unit tests. You can find it on GitHub <a href="https://github.com/NicolasDuponchel/RxBasics">here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b27878495220" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Android — Jokes REST API call with Rx Java]]></title>
            <link>https://medium.com/@nicolas.duponchel/rx-java-for-beginners-8b7c1e7bfc44?source=rss-e1be2e24d25e------2</link>
            <guid isPermaLink="false">https://medium.com/p/8b7c1e7bfc44</guid>
            <category><![CDATA[observables]]></category>
            <category><![CDATA[rxkotlin]]></category>
            <category><![CDATA[hello-world]]></category>
            <category><![CDATA[rxandroid]]></category>
            <category><![CDATA[rxjava]]></category>
            <dc:creator><![CDATA[Nicolas Duponchel]]></dc:creator>
            <pubDate>Wed, 28 Mar 2018 17:50:54 GMT</pubDate>
            <atom:updated>2018-06-14T21:35:45.824Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dc19FcGWPASnB7t0hoJvcg.png" /></figure><p>If you search a way to start learning Rx ? This article is for you !</p><p>I wrote Medium stories telling some Rx Java tips I found useful (<a href="https://medium.com/@nicolas.duponchel/perfecting-logs-with-rx-kotlin-dfd56ea907c8">logging</a>, <a href="https://medium.com/@nicolas.duponchel/having-fun-with-rxkotlin-8508cdfee214">errors</a>, <a href="https://medium.com/@nicolas.duponchel/rx-java-timeout-improvement-with-kotlin-ec07eff59302">timeout</a>, <a href="https://medium.com/@nicolas.duponchel/try-to-retry-with-rxkotlin-69906b2d181e">retry</a> …) But I realized I never mentioned the basics. Let’s start from the beginning. I wont try to reword the <a href="http://reactivex.io/intro.html">Rx documentation</a>, but tell about my own reactive programming experience with Rx.</p><h4>What is Rx ?</h4><blockquote>It is an API for asynchronous programming with observable streams.</blockquote><p>If I would quickly illustrate Rx I would take the image of a roller coaster with marbles. Rx permits to change the rails directions and the marbles’ type, color, form etc. We can observe this roller coaster’s finishing line and catch the marbles.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*AlTWxgsnciuQoNdyhm2GqQ.gif" /></figure><p>We can use it in many languages like Python, Kotlin, Swift, Java, JS, PHP… I’m a mobile developper so my experience belong to Rx Java &amp; Kotlin on Android framework. But whatever, the principe is still the same.</p><h4>Why should I use Rx ?</h4><p>For a powerful, readable and minimal code</p><h4>When should I use Rx ?</h4><p>Every time I make an asynchronous operation.</p><h3>Base reactive interfaces</h3><p>Before starting with some examples, here is the very first thing to know : Rx base reactive types.</p><blockquote>Rx base reactive types are Observable, Single, Completable, and Maybe.</blockquote><p>Those 4 could be assimilated to roller coasters and their emissions to marbles.</p><ul><li><strong>Completable</strong> emits no item, just a “I’ve got the job done”.</li><li><strong>Single</strong> emits a single one item.</li><li><strong>Observable</strong> can emit few elements.</li><li><strong>Maybe</strong> is a union between Single and Completable. It emits one or no item.</li></ul><p>Notice that since Rx 2, reactive types does not accept nullable values. This also means that tey will never emit null.</p><h3>Basic Hello World example</h3><p>Let’s build a simple HelloWorld using Rx. We need 2 things to make it works :</p><ul><li>The <strong>observable</strong> that will emit a String “HelloWorld”</li><li>The <strong>observer</strong> that will subscribe to the observable emission.</li></ul><p>To create an observable instance, we basically use just <a href="http://reactivex.io/documentation/operators/just.html">operator</a>. It converts an item into an observable that emits that item. Our result is a single “Hello world” String, so the observable source would be a Single.</p><pre>Single.just( &quot;Hello World&quot; )</pre><p>Now that we have an observable ready, we just need to subscribe to it’s emission.</p><pre>fun helloWorld() {<br>    val observable = Single.just(&quot;Hello World&quot;)<br><br>    observable.<em>subscribeBy</em>(<br>            onSuccess = <strong>{ </strong><em>print</em>(<strong>it</strong>) <strong>}</strong>,<br>            onError = <strong>{ }<br>    </strong>)<br>}</pre><p>Moreover, we can choose the thread which will take the subscription responsibility, so basically we choose a non-UI Thread. Then when our observable emits a result, we will observe it on the main Thread to update UI.</p><pre>observable<br>        .subscribeOn(Schedulers.io())<br>        .observeOn(AndroidSchedulers.mainThread())<br>        .<em>subscribeBy</em>(<br>                onSuccess = <strong>{ </strong><em>print</em>(<strong>it</strong>)<strong>}</strong>,<br>                onError = <strong>{}<br>        </strong>)</pre><p>Of course this example do not really matter because there’s no need of asynchronous task to write a HelloWorld ! But now that you’ve got the very basic framework, let’s try little more complex examples.</p><p>I built a simple Android app to illustrate the following ( Completable, Single and Observable) examples. Here is the GitHub <a href="https://github.com/NicolasDuponchel/RxBasics.git">repo</a>. I implemented all those with an Activity and its ViewModel using LiveData.</p><p><a href="https://github.com/NicolasDuponchel/RxBasics.git">NicolasDuponchel/RxBasics</a></p><h3>Completable example</h3><p>This time, we won’t care about task’s result. What matters is simply that our job succeed (or not). The most simple example I found to illustrate Completable consists on simulating an installation of something (doesn’t matter what). So let’s simulate an installation that takes 3 seconds.</p><pre>Completable.timer(3, SECONDS)<br>.<em>subscribeBy</em>(<br>        onComplete = <strong>{ </strong><em>toast</em>(&quot;Fake installation succeed&quot;) <strong>}</strong>,<br>        onError = <strong>{ </strong>toast(&quot;Let me guess this never happen&quot;) <strong>}<br></strong>)</pre><p>Cool don’t you think ? Hum… I know you want to do stuff more interesting am I wrong ? So to deal with real asynchronous task with more fun, I suggest to try this<a href="http://api.icndb.com/jokes/random"> RESTful public api</a> that returns a random joke. Let’s see how Rx could help.</p><h3>API call prerequisite</h3><p>This paragraph explains quickly how to call a REST API on Android. Just skip it if you cannot wait to deal with Rx !</p><pre>{ <br>    &quot;type&quot;: &quot;success&quot;,<br>    &quot;value&quot;: <strong>{<br>        </strong>&quot;id&quot;: 530,<br>        <strong>&quot;joke&quot;: &quot;Chuck Norris can dereference NULL.&quot;</strong>,<br>        &quot;categories&quot;: [&quot;nerdy&quot;] <br>    <strong>}<br></strong>}</pre><p>Here is the Json result. Let’s create a Joke class and get it from the api. Then the basics to call this URL with Retrofit :</p><pre>private fun createService(): ApiService = Retrofit.Builder()<br>        .baseUrl(&quot;http://api.icndb.com/&quot;)<br>        .addConverterFactory(GsonConverterFactory.create(<em>gson</em>))<br>        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())<br>        .build()<br>        .create(ApiService::class.<em>java</em>)</pre><pre>interface ApiService {<br>    @GET(&quot;jokes/random&quot;)<br>    fun randomJoke(): Single&lt;ApiResponse&gt;<br>}</pre><pre>data class ApiResponse(<br>        @SerializedName(&quot;type&quot;) val type: String,<br>        @SerializedName(&quot;value&quot;) val joke: Joke)</pre><pre>data class Joke(<br>        @SerializedName(&quot;id&quot;) val jokeId: Int,<br>        @SerializedName(&quot;joke&quot;) val jokeText: String)</pre><h3>Single example</h3><p>Api’s call is now ready, let’s create and subscribe to Single&lt;Joke&gt;. Notice that randomJoke() returns a Single&lt;ApiResponse&gt;, I use map <a href="http://reactivex.io/documentation/operators/map.html">operator</a> to change it to Single&lt;Joke&gt;.</p><pre>fun displayJoke() {<br>    val apiService = createService()<br><br>    val jokeObservable: Single&lt;Joke&gt; =<br>            apiService.randomJoke().map <strong>{ it</strong>.joke <strong>}<br><br>    </strong>jokeObservable<br>            .subscribeOn(Schedulers.io())<br>            .observeOn(AndroidSchedulers.mainThread())<br>            .<em>subscribeBy</em>(<br>                    onSuccess = <strong>{ </strong><em>print</em>(<strong>it</strong>.jokeText) <strong>}</strong>,<br>                    onError = <strong>{ </strong><em>print</em>(<strong>it</strong>) <strong>}<br>            </strong>)<br>}</pre><p>Why not to add loaders to highlight the background execution ? Methods doOnSubscribe and doFinally can be used to call specified action before subscription and after onSuccess or onError.</p><pre>jokeObservable<br>        .subscribeOn(Schedulers.io())<br>        .observeOn(AndroidSchedulers.mainThread())<br>        .doOnSubscribe(joke_loader.show())<br>        .doFinally(joke_loader.hide())<br>        .<em>subscribeBy</em>(<br>                onSuccess = <strong>{ </strong><em>print</em>(<strong>it</strong>.jokeText) <strong>}</strong>,<br>                onError = <strong>{ </strong><em>print</em>(<strong>it</strong>) <strong>}<br>        </strong>)</pre><p>Cool isn’t it ? Now that we’ve seen the very tip of the Rx iceberg, I suggest to have a look at Observable.</p><h3>Observable example</h3><p>To deal with Observable emission, I suggest to reuse the previous example but this time we could ask for some random jokes in a single flux. Let’s convert the previous Single into an Observable with toObservable. Then, now that we have a “multi-elements” emission, repeat(count)method will help. “It r<em>eturns an Observable that repeats the sequence of items emitted by the source ObservableSource at most {count} times.”</em></p><pre>val jokesObservable = jokeApiService.randomJoke()<br>        .map <strong>{ it</strong>.joke <strong>}<br>        </strong>.toObservable()<br>        .repeat(3)</pre><p>What’s different now ? The emission is constituted of 3 jokes. And by subscribing to an Observable, each time it emits a result, the onNext method is called with it as Joke.</p><pre>jokesObservable.<em>subscribeBy</em>(<br>        onNext = <strong>{ </strong><em>println</em>(<strong>it</strong>.jokeText) <strong>}</strong>,<br>        onComplete = <strong>{ </strong><em>println</em>(&quot;job done&quot;)<strong>}</strong>,<br>        onError = <strong>{ </strong><em>println</em>(<strong>it</strong>.message) <strong>}<br></strong>)</pre><p>This code will print (if no error is encountered) :</p><blockquote>jokeText1<br>jokeText2<br>jokeText3<br>job done</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FTFuF8oY8PSzhWqogkM3Ag.png" /><figcaption>App project on GitHub</figcaption></figure><p>You’ve got now the basics of Rx reactive programming! For technologie lovers, I would affirm that the best app I used to deal with is Rx Kotlin app, build on MVVM using LiveData. Please have a look at <a href="https://github.com/NicolasDuponchel/RxBasics.git">the all project</a> on GitHub.</p><p>Thanks for reading !</p><p>For those who want to learn how to unit test ViewModel in MVVM architecture : see <a href="https://medium.com/@nicolas.duponchel/testing-viewmodel-in-mvvm-using-livedata-and-rxjava-b27878495220">this article</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8b7c1e7bfc44" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>