<?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" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ RxAndroid - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ RxAndroid - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 27 Jul 2026 04:23:02 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/rxandroid/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ Simplifying RecyclerView Adapters with Rx & Databinding ]]>
                </title>
                <description>
                    <![CDATA[ By Ahmed Rizwan I recently wanted to dive deeper into Rx. So I experimented with Rx and the RecyclerView Adapters, and the results were pretty interesting! With Rx in mind, I set out to accomplish three things: Create a RecyclerView adapter which sh... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/simplifying-recyclerview-adapters-with-rx-databinding-f02ebed0b386/</link>
                <guid isPermaLink="false">66c35ee6c7095d76345eb004</guid>
                
                    <category>
                        <![CDATA[ Android ]]>
                    </category>
                
                    <category>
                        <![CDATA[ mobile app development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ RecyclerView   ]]>
                    </category>
                
                    <category>
                        <![CDATA[ RxAndroid ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 10 Dec 2015 16:03:17 +0000</pubDate>
                <media:content url="https://cdn-media-1.freecodecamp.org/images/1*q63b1qjfmWKwQt_MPjYhDQ.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Ahmed Rizwan</p>
<p>I recently wanted to dive deeper into Rx. So I experimented with Rx and the RecyclerView Adapters, and the results were pretty interesting!</p>
<p>With Rx in mind, I set out to accomplish three things:</p>
<ol>
<li>Create a RecyclerView adapter which should be <strong>generic</strong> — one adapter class to rule them all!</li>
<li>It should return <strong>bindings</strong> in the form of Rx streams!</li>
<li>There should also be an option for supporting multiple item <strong>types</strong>!</li>
</ol>
<p>Now, you may be thinking: this isn’t really necessary. I mean why use Rx in the first place with RecyclerAdapters? And why exactly do you need bindings as Rx streams?</p>
<p>Well that’s true. Personally, I thought it’d be a good experiment to incorporate Rx into RecyclerView Adapters, instead of using simple callbacks or delegates. So it was sort of experimental.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*6oS0HYL3OOVu9b4PupalmA.gif" alt="Image" width="250" height="205" loading="lazy"></p>
<p>So I wrote a library called <a target="_blank" href="https://github.com/ahmedrizwan/RxRecyclerAdapter"><strong>RxRecyclerAdapter</strong></a> to get Rx to work with the Adapters. Let’s break down how it simplifies use of the recycler adapters.</p>
<h4 id="heading-rxdatasource-simplifies-the-use-of-rxrecycleradapter">RxDataSource simplifies the use of RxRecyclerAdapter</h4>
<p>Let’s say you have a beautiful String array list that you want to display:</p>
<pre><code><span class="hljs-comment">//Dummy DataSetdataSet = new ArrayList&lt;&gt;();dataSet.add("this");dataSet.add("is");dataSet.add("an");dataSet.add("example");dataSet.add("of rx!");</span>
</code></pre><p>Here’s what you would do:</p>
<ol>
<li>Enable data binding by adding this into build.gradle</li>
</ol>
<pre><code>dataBinding {      enabled = <span class="hljs-literal">true</span>}
</code></pre><ol start="2">
<li>create the layout file for the item:</li>
</ol>
<pre><code>&amp;lt;?xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"utf-8"</span>?&gt;&amp;lt;layout xmlns:android=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span>        xmlns:tools=<span class="hljs-string">"http://schemas.android.com/tools"</span>&gt;    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">LinearLayout</span>        <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>        <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"match_parent"</span>        <span class="hljs-attr">android:orientation</span>=<span class="hljs-string">"vertical"</span>        <span class="hljs-attr">android:padding</span>=<span class="hljs-string">"@dimen/activity_horizontal_margin"</span>&gt;</span>        <span class="hljs-tag">&lt;<span class="hljs-name">;TextView</span> <span class="hljs-attr">android:id</span>=<span class="hljs-string">"@+id/textViewItem"</span>                  <span class="hljs-attr">android:layout_width</span>=<span class="hljs-string">"match_parent"</span>                  <span class="hljs-attr">android:layout_height</span>=<span class="hljs-string">"wrap_content"</span>                  <span class="hljs-attr">tools:text</span>=<span class="hljs-string">"Recycler Item"</span>/&gt;</span></span>    &lt;<span class="hljs-regexp">/LinearLayout&gt;&lt;/</span>layout&gt;
</code></pre><ol start="3">
<li>Create an instance of <strong>RxDataSource</strong> telling it what the dataSet type is:</li>
</ol>
<pre><code>RxDataSource&amp;lt;<span class="hljs-built_in">String</span>&gt; rxDataSource = <span class="hljs-keyword">new</span> RxDataSource&lt;&gt;(dataSet);
</code></pre><ol start="4">
<li>Compose and then cast-call bindRecyclerView (passing in the RecyclerView and layout) with LayoutBinding. Because of casting, viewHolder can infer the type of binding.</li>
</ol>
<pre><code>rxDataSource  .map(<span class="hljs-built_in">String</span>::toLowerCase)  .repeat(<span class="hljs-number">10</span>)  .&amp;lt;ItemLayoutBinding&gt;bindRecyclerView(recyclerView,                               R.layout.item_layout)  .subscribe(viewHolder -&gt; {         ItemLayoutBinding b = viewHolder.getViewDataBinding();         b.textViewItem.setText(viewHolder.getItem());  });
</code></pre><p>The output will be…</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*T10QOX-L1dbfFlr8UCiAOg.png" alt="Image" width="341" height="582" loading="lazy"></p>
<p>Note that calling observeOn(AndroidSchedulers.mainThread()) would be unnecessary here, as you’re already on the mainThread. And when you call it, it causes a delay of about ~20–30 milliseconds in the stream, which would lower your frame rate.</p>
<p>Now for a bit more practical example.</p>
<p>Let’s say you want to dynamically update the dataSet. Let’s say you want to search the dataSet and filter out the results specific results. Here’s how that would be done:</p>
<pre><code>RxTextView.afterTextChangeEvents(searchEditText).subscribe(event -&gt; {  rxDataSource.updateDataSet(dataSet)       .filter(s -&gt; s.contains(event.view().getText()))      .updateAdapter();});
</code></pre><p>In combination with <a target="_blank" href="https://github.com/JakeWharton/RxBinding">RxBindings</a> (because RxBindings are awesome), I register for textChange events. And when the event occurs I update the DataSet with the <strong>base dataSet!</strong></p>
<p>Now this is important because the RxDataSource changes its dataSet instance when I call methods like <em>filter</em>, <em>map</em> and so on. So filtering needs to be done on the <strong>original dataSet</strong>, not the changed one. And… bam!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*uMxIbKfiEySpqx027Ilh3A.gif" alt="Image" width="292" height="501" loading="lazy"></p>
<p>I did come across some limitations — one being that you can’t change the <strong>type</strong> of dataSet after it has been bound with the data source. So functions like <em>map</em> and <em>flatmap</em> can’t return a different type of dataSet. But I have yet to run into a situation where I needed to be able to change the dataSet at runtime.</p>
<h4 id="heading-rxrecycleradapter-simplifies-the-situations-where-you-have-multiple-item-types">RxRecyclerAdapter simplifies the situations where you have multiple item types</h4>
<p>Now let’s say you wanted multiple Item types in your RecyclerView, for example a header and an item type. Then you would:</p>
<ol>
<li>Create List of <strong>ViewHolderInfo</strong> specifying all the layouts</li>
</ol>
<pre><code>List&lt;ViewHolderInfo&gt; vi = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();vi.add(<span class="hljs-keyword">new</span> ViewHolderInfo(R.layout.item_layout, TYPE_ITEM)); vi.add(<span class="hljs-keyword">new</span> ViewHolderInfo(R.layout.item_header_layout, TYPE_HEADER));
</code></pre><ol start="2">
<li>Create instance of <strong>RxDataSource</strong> like before:</li>
</ol>
<pre><code>RxDataSource&lt;<span class="hljs-built_in">String</span>&gt; rxDataSource = <span class="hljs-keyword">new</span> RxDataSource&lt;&gt;(dataSet);
</code></pre><ol start="3">
<li>Compose and call bindRecyclerView passing in the <strong>recyclerView</strong>, the <strong>viewHolderInfo</strong> list and implementation of <strong>getItemViewType</strong>:</li>
</ol>
<pre><code>rxDataSource.bindRecyclerView(recyclerView, viewHolderInfoList,    <span class="hljs-keyword">new</span> OnGetItemViewType() {      @Override public int getItemViewType(int position) {        <span class="hljs-keyword">if</span> (position % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>) {          <span class="hljs-keyword">return</span> TYPE_HEADER; <span class="hljs-comment">//headers are even positions        }        return TYPE_ITEM;      }    }  ).subscribe(vH -&gt; {    //Check instance type and bind!    final ViewDataBinding b = vH.getViewDataBinding();    if (b instanceof ItemLayoutBinding) {      final ItemLayoutBinding iB = (ItemLayoutBinding) b;      iB.textViewItem.setText("ITEM: " + vH.getItem());    } else if (b instanceof ItemHeaderLayoutBinding) {      ItemHeaderLayoutBinding hB = (ItemHeaderLayoutBinding) b;      hB.textViewHeader.setText("HEADER: " + vH.getItem());    }  });</span>
</code></pre><pre><code><span class="hljs-comment">/* and like before, you can do this as well    rxDataSource.filter(s -&gt; s.length() &gt; 0)               .map(String::toUpperCase)              .updateAdapter();*/</span>
</code></pre><p>Now <strong>recyclerView</strong> would look something like:</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*bz1gu8r1BtqqOxQ2c0Jo5Q.png" alt="Image" width="341" height="571" loading="lazy"></p>
<h3 id="heading-a-little-about-the-implementation">A little about the Implementation</h3>
<h4 id="heading-publishsubject">PublishSubject</h4>
<p>Preface → I utilized <a target="_blank" href="http://reactivex.io/documentation/subject.html"><strong>PublishSubjects</strong></a> for the most part, and <strong>generics</strong> to create the adapter.</p>
<p>PublishSubject is a type of observable which can be both <em>Observable</em> and an <em>Observer</em> at the same time.</p>
<p>Because it is an observer, it can subscribe to one or more Observables. And because it is an Observable, it can pass through the items it observes by reemitting them, and it can also emit new items.</p>
<h4 id="heading-internals">Internals</h4>
<p>Internally, there are two adapters, which you can also access directly if you want: <strong>RxAdapter</strong> and <strong>RxAdapterForTypes</strong>.</p>
<p>For these two, I created a generic <strong>ViewHolder</strong> implementation, which binds the layout with an instance of ViewDataBinding:</p>
<pre><code>public <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SimpleViewHolder</span>&lt;<span class="hljs-title">T</span>, <span class="hljs-title">V</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ViewDataBinding</span>&gt; <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">ViewHolder</span> </span>{    private V mViewDataBinding;    public V getViewDataBinding() {        <span class="hljs-keyword">return</span> mViewDataBinding;    }    public T getItem() {        <span class="hljs-keyword">return</span> mItem;    }    private T mItem;    protected <span class="hljs-keyword">void</span> setItem(final T item) {        mItem = item;    }    public SimpleViewHolder(final View itemView) {        <span class="hljs-built_in">super</span>(itemView);        mViewDataBinding = DataBindingUtil.bind(itemView);    }}
</code></pre><p>Then I created RxAdapter — It takes two generics:</p>
<pre><code>RxAdapter&amp;lt;DataType, LayoutBinding <span class="hljs-keyword">extends</span> ViewDataBinding&gt;
</code></pre><p>I created a <a target="_blank" href="http://reactivex.io/RxJava/javadoc/rx/subjects/PublishSubject.html">PublishSubject</a> for my ViewHolder, and in onBindViewHolder I call onNext. The viewHolder contains the item itself:</p>
<pre><code>@Overridepublic <span class="hljs-keyword">void</span> onBindViewHolder(final SimpleViewHolder&lt;T, V&gt; holder, final int position) {    holder.setItem(mDataSet.get(position));    mPublishSubject.onNext(holder);}
</code></pre><p>Finally, I created a method asObservable, which returns the publishSubject as an Observable so that you can subscribe to it:</p>
<pre><code>public Observable&lt;SimpleViewHolder&gt; asObservable(){    <span class="hljs-keyword">return</span> mPublishSubject.asObservable();}
</code></pre><p>But wait, what about the RxDataSource? Well it’s just a wrapper for Rx Observables. It’s main purpose is to provide you with an abstraction over the two adapters and Rx methods. It basically connects everything together.</p>
<p>When I say it’s a wrapper, that means that you only get methods that are <strong>relevant to a recyclerAdapter</strong>, like <em>filter</em>, <em>map</em>, <em>take</em>, <em>first</em>, <em>repeat</em> and so on. It doesn’t give you methods which have something to do with threading or schedulers.</p>
<p>As the class is pretty straight-forward. You can check out the code for RxDataSource <a target="_blank" href="https://github.com/ahmedrizwan/RxRecyclerAdapter/blob/master/rxrecycler-adapter/src/main/java/com/minimize/android/rxrecycleradapter/RxDataSource.java"><strong>here</strong></a>.</p>
<p>That’s pretty much it… I hope you found this article useful. Do give <a target="_blank" href="https://github.com/ahmedrizwan/RxRecyclerAdapter">RxAdapter</a> a try. And if you have any questions (or suggestions), fire away!</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/1*rgZIWDa7Zr8GJhb5zQiyPA.jpeg" alt="Image" width="400" height="400" loading="lazy"></p>
<p>Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
