<?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[ RecyclerView   - 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[ RecyclerView   - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 30 May 2026 14:18:22 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/recyclerview/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Implement 'Swipe for Options' in RecyclerView ]]>
                </title>
                <description>
                    <![CDATA[ By Gagandeep Singh Let's say a user of your site wants to edit a list item without opening the item and looking for editing options. If you can enable this functionality, it gives that user a good User Experience.  Pocket, a bookmarking app owned by ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-implement-swipe-for-options-in-recyclerview/</link>
                <guid isPermaLink="false">66d45edb264384a65d5a9516</guid>
                
                    <category>
                        <![CDATA[ Java ]]>
                    </category>
                
                    <category>
                        <![CDATA[ RecyclerView   ]]>
                    </category>
                
                    <category>
                        <![CDATA[ user experience ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 18 May 2020 23:09:12 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9aef740569d1a4ca28ba.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Gagandeep Singh</p>
<p>Let's say a user of your site wants to edit a list item without opening the item and looking for editing options. If you can enable this functionality, it gives that user a <strong>good User Experience</strong>. </p>
<p><a target="_blank" href="https://play.google.com/store/apps/details?id=com.ideashower.readitlater.pro&amp;hl=en_IN">Pocket</a>, a bookmarking app owned by Mozilla, does something similar. You can share/archive/delete your saved articles directly from the list without opening the article. Then you can click the menu button in the top-right corner and select your edit option.</p>
<p>So in this tutorial we'll try to code this one out.</p>
<p><strong>Here's what we want to achieve</strong>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/08/recycler-view-example.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<h2 id="heading-first-lets-create-a-normal-recyclerview-list">First let’s create a normal RecyclerView list</h2>
<p>RecyclerView is an advanced and flexible version of ListView and GridView. It's capable of holding large amounts of list data and has better performance than its predecessors. </p>
<p>As the name suggests, RecyclerView 'recycles' the items of our list once it's out of view on scrolling and re-populates them when they come back to view. So the list container has to maintain only a limited number of views and not the entire list.</p>
<p>It's so flexible that the new <a target="_blank" href="https://developer.android.com/training/animation/vp2-migration#diffutil">ViewPager2</a> class, used to create swipe-able tabs, is written over RecyclerView.</p>
<h3 id="heading-create-a-pojo-plain-old-java-object-to-hold-the-list-data">Create a POJO (Plain Old Java Object) to hold the list data</h3>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RecyclerEntity</span> </span>{
    <span class="hljs-keyword">private</span> String title;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> showMenu = <span class="hljs-keyword">false</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> image;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">RecyclerEntity</span><span class="hljs-params">()</span> </span>{
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">RecyclerEntity</span><span class="hljs-params">(String title, <span class="hljs-keyword">int</span> image, <span class="hljs-keyword">boolean</span> showMenu)</span> </span>{
        <span class="hljs-keyword">this</span>.title = title;
        <span class="hljs-keyword">this</span>.showMenu = showMenu;
        <span class="hljs-keyword">this</span>.image = image;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getImage</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> image;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setImage</span><span class="hljs-params">(<span class="hljs-keyword">int</span> image)</span> </span>{
        <span class="hljs-keyword">this</span>.image = image;
    }

    <span class="hljs-comment">//... all the getters and setters</span>
}
</code></pre>
<p>Notice we have a showMenu member here which will handle the visibility of the menu for that list item in our RecyclerView.</p>
<h3 id="heading-create-a-recyclerview-adapter">Create a RecyclerView Adapter</h3>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RecyclerAdapter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">Adapter</span>&lt;<span class="hljs-title">RecyclerView</span>.<span class="hljs-title">ViewHolder</span>&gt; </span>{
    List&lt;RecyclerEntity&gt; list;
    Context context;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">RecyclerAdapter</span><span class="hljs-params">(Context context, List&lt;RecyclerEntity&gt; articlesList)</span> </span>{
        <span class="hljs-keyword">this</span>.list = articlesList;
        <span class="hljs-keyword">this</span>.context = context;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-keyword">public</span> RecyclerView.<span class="hljs-function">ViewHolder <span class="hljs-title">onCreateViewHolder</span><span class="hljs-params">(ViewGroup parent, <span class="hljs-keyword">int</span> viewType)</span> </span>{
        View v;
            v= LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_list, parent, <span class="hljs-keyword">false</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MyViewHolder(v);
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onBindViewHolder</span><span class="hljs-params">(RecyclerView.ViewHolder holder, <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> position)</span> </span>{
        RecyclerEntity entity = list.get(position);
        <span class="hljs-keyword">if</span>(holder <span class="hljs-keyword">instanceof</span> MyViewHolder){
            ((MyViewHolder)holder).title.setText(entity.getTitle());
            ((MyViewHolder)holder).imageView.setImageDrawable(context.getResources().getDrawable(entity.getImage()));   
        }
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getItemCount</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> list.size();
    }

    <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyViewHolder</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">ViewHolder</span> </span>{
        TextView title;
        ImageView imageView;
        ConstraintLayout container;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MyViewHolder</span><span class="hljs-params">(View itemView)</span> </span>{
            <span class="hljs-keyword">super</span>(itemView);
            title = itemView.findViewById(R.id.title);
            imageView = itemView.findViewById(R.id.imageView);
            container = itemView.findViewById(R.id.container);
        }
    }
}
</code></pre>
<p>Usually we put our ViewHolder sub class (MyViewHolder) in the super class template. This lets us directly return our defined ViewHolder subclass object from the onCreateViewHolder() method. Then we don't have to cast it again and again in onBindViewHolder() method. </p>
<p>But here we can't do that, and we'll learn why in a minute. </p>
<h3 id="heading-initialise-the-recyclerview-in-the-activity">Initialise the RecyclerView in the Activity</h3>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> </span>{
    RecyclerView recyclerView;
    List&lt;RecyclerEntity&gt; list;
    RecyclerAdapter adapter;


    <span class="hljs-meta">@RequiresApi(api = Build.VERSION_CODES.M)</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(Bundle savedInstanceState)</span> </span>{
        <span class="hljs-keyword">super</span>.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.recyclerview);
        list = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;();

        list.add(<span class="hljs-keyword">new</span> RecyclerEntity(<span class="hljs-string">"This is the best title"</span>, R.drawable.one, <span class="hljs-keyword">false</span>));
        list.add(<span class="hljs-keyword">new</span> RecyclerEntity(<span class="hljs-string">"This is the second-best title"</span>, R.drawable.two, <span class="hljs-keyword">false</span>));
        <span class="hljs-comment">//... rest of the list items</span>

        adapter = <span class="hljs-keyword">new</span> RecyclerAdapter(<span class="hljs-keyword">this</span>, list);
        recyclerView.setLayoutManager(<span class="hljs-keyword">new</span> LinearLayoutManager(<span class="hljs-keyword">this</span>));
        recyclerView.setAdapter(adapter);
    }
}
</code></pre>
<p>Now let's start making things a little more interesting.</p>
<h2 id="heading-create-a-layout-resource-for-the-menu">Create a layout resource for the menu</h2>
<p>And initialise it in Recycler Adapter:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RecyclerAdapter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">Adapter</span>&lt;<span class="hljs-title">RecyclerView</span>.<span class="hljs-title">ViewHolder</span>&gt; </span>{
    List&lt;RecyclerEntity&gt; list;
    Context context;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> SHOW_MENU = <span class="hljs-number">1</span>;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> HIDE_MENU = <span class="hljs-number">2</span>;

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">RecyclerAdapter</span><span class="hljs-params">(Context context, List&lt;RecyclerEntity&gt; articlesList)</span> </span>{
        <span class="hljs-keyword">this</span>.list = articlesList;
        <span class="hljs-keyword">this</span>.context = context;
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getItemViewType</span><span class="hljs-params">(<span class="hljs-keyword">int</span> position)</span> </span>{
        <span class="hljs-keyword">if</span>(list.get(position).isShowMenu()){
            <span class="hljs-keyword">return</span> SHOW_MENU;
        }<span class="hljs-keyword">else</span>{
            <span class="hljs-keyword">return</span> HIDE_MENU;
        }
    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-keyword">public</span> RecyclerView.<span class="hljs-function">ViewHolder <span class="hljs-title">onCreateViewHolder</span><span class="hljs-params">(ViewGroup parent, <span class="hljs-keyword">int</span> viewType)</span> </span>{
        View v;
        <span class="hljs-keyword">if</span>(viewType==SHOW_MENU){
            v= LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_menu, parent, <span class="hljs-keyword">false</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MenuViewHolder(v);
        }<span class="hljs-keyword">else</span>{
            v= LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_list, parent, <span class="hljs-keyword">false</span>);
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> MyViewHolder(v);
        }

    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onBindViewHolder</span><span class="hljs-params">(RecyclerView.ViewHolder holder, <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> position)</span> </span>{
        RecyclerEntity entity = list.get(position);
        <span class="hljs-keyword">if</span>(holder <span class="hljs-keyword">instanceof</span> MyViewHolder){
            <span class="hljs-comment">//... same as above</span>
        }

        <span class="hljs-keyword">if</span>(holder <span class="hljs-keyword">instanceof</span> MenuViewHolder){
            <span class="hljs-comment">//Menu Actions</span>
        }

    }

    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> <span class="hljs-title">getItemCount</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">return</span> list.size();
    }

    <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyViewHolder</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">ViewHolder</span> </span>{
        <span class="hljs-comment">//... same as above</span>
    }
    <span class="hljs-comment">//Our menu view</span>
    <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MenuViewHolder</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">RecyclerView</span>.<span class="hljs-title">ViewHolder</span></span>{
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MenuViewHolder</span><span class="hljs-params">(View view)</span></span>{
            <span class="hljs-keyword">super</span>(view);
        }
    }
}
</code></pre>
<p>Now we have two ViewHolder sub-classes in our adapter, MyViewHolder (the actual list item) and MenuViewHolder. Both inherit the same class so we return the parent class <em>RecyclerView.ViewHolder</em> from onCreateViewHolder(). </p>
<p>Our getItemViewType() method returns the int variable (viewType) which tells the kind of view we want to show in our RecyclerView for a particular position: that is, either MyViewHolder or MenuViewHolder. </p>
<p>This viewType variable is then used by onCreateViewHolder() which actually returns the respective ViewHolder object.</p>
<h2 id="heading-add-the-functions-to-showhide-menu-in-recycleradapter">Add the functions to show/hide menu in RecyclerAdapter</h2>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">showMenu</span><span class="hljs-params">(<span class="hljs-keyword">int</span> position)</span> </span>{
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;list.size(); i++){
            list.get(i).setShowMenu(<span class="hljs-keyword">false</span>);
        }
        list.get(position).setShowMenu(<span class="hljs-keyword">true</span>);
        notifyDataSetChanged();
    }


    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isMenuShown</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;list.size(); i++){
            <span class="hljs-keyword">if</span>(list.get(i).isShowMenu()){
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
            }
        }
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">closeMenu</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">for</span>(<span class="hljs-keyword">int</span> i=<span class="hljs-number">0</span>; i&lt;list.size(); i++){
            list.get(i).setShowMenu(<span class="hljs-keyword">false</span>);
        }
        notifyDataSetChanged();
    }
</code></pre>
<p>Note that there are many ways to handle this. But for simplicity's sake we're keeping a boolean value in our POJO to maintain the menu's visibility.</p>
<p>After changing our data list, we call the notifyDataSetChanged() method to redraw the list. </p>
<h2 id="heading-show-the-menu-on-long-press-of-our-list-item-in-recycleradapter">Show the menu on long press of our list item in RecyclerAdapter</h2>
<pre><code class="lang-java"><span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onBindViewHolder</span><span class="hljs-params">(RecyclerView.ViewHolder holder, <span class="hljs-keyword">final</span> <span class="hljs-keyword">int</span> position)</span> </span>{
        RecyclerEntity entity = list.get(position);
        <span class="hljs-keyword">if</span>(holder <span class="hljs-keyword">instanceof</span> MyViewHolder){
            ((MyViewHolder)holder).title.setText(entity.getTitle());
            ((MyViewHolder)holder).imageView.setImageDrawable(context.getResources().getDrawable(entity.getImage()));

            ((MyViewHolder)holder).container.setOnLongClickListener(<span class="hljs-keyword">new</span> View.OnLongClickListener() {
                <span class="hljs-meta">@Override</span>
                <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onLongClick</span><span class="hljs-params">(View v)</span> </span>{
                    showMenu(position);
                    <span class="hljs-keyword">return</span> <span class="hljs-keyword">true</span>;
                }
            });
        }
        <span class="hljs-keyword">if</span>(holder <span class="hljs-keyword">instanceof</span> MenuViewHolder){
            <span class="hljs-comment">//Set Menu Actions like:</span>
            <span class="hljs-comment">//((MenuViewHolder)holder).edit.setOnClickListener(null);</span>
        }

    }
</code></pre>
<p>Again, setting events on our views can also be done in various ways. </p>
<p>In our example, we have three actions in our menu. You can write your logic to handle those actions in the second if statement like shown in the comments.</p>
<h2 id="heading-show-the-menu-on-swipe">Show the menu on swipe</h2>
<p>To do this, we add a touch helper in our MainActivity.java:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MainActivity</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">AppCompatActivity</span> </span>{
    RecyclerView recyclerView;
    List&lt;RecyclerEntity&gt; list;
    RecyclerAdapter adapter;


    <span class="hljs-meta">@RequiresApi(api = Build.VERSION_CODES.M)</span>
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onCreate</span><span class="hljs-params">(Bundle savedInstanceState)</span> </span>{
        <span class="hljs-comment">//... same as above </span>

        adapter = <span class="hljs-keyword">new</span> RecyclerAdapter(<span class="hljs-keyword">this</span>, list);
        recyclerView.setLayoutManager(<span class="hljs-keyword">new</span> LinearLayoutManager(<span class="hljs-keyword">this</span>));
        recyclerView.setAdapter(adapter);

        ItemTouchHelper.SimpleCallback touchHelperCallback = <span class="hljs-keyword">new</span> ItemTouchHelper.SimpleCallback(<span class="hljs-number">0</span>, ItemTouchHelper.LEFT) {
            <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> ColorDrawable background = <span class="hljs-keyword">new</span> ColorDrawable(getResources().getColor(R.color.background));

            <span class="hljs-meta">@Override</span>
            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">onMove</span><span class="hljs-params">(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target)</span> </span>{
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
            }

            <span class="hljs-meta">@Override</span>
            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onSwiped</span><span class="hljs-params">(RecyclerView.ViewHolder viewHolder, <span class="hljs-keyword">int</span> direction)</span> </span>{
                adapter.showMenu(viewHolder.getAdapterPosition());
            }

            <span class="hljs-meta">@Override</span>
            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onChildDraw</span><span class="hljs-params">(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, <span class="hljs-keyword">float</span> dX, <span class="hljs-keyword">float</span> dY, <span class="hljs-keyword">int</span> actionState, <span class="hljs-keyword">boolean</span> isCurrentlyActive)</span> </span>{
                <span class="hljs-keyword">super</span>.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);

                View itemView = viewHolder.itemView;

                <span class="hljs-keyword">if</span> (dX &gt; <span class="hljs-number">0</span>) {
                    background.setBounds(itemView.getLeft(), itemView.getTop(), itemView.getLeft() + ((<span class="hljs-keyword">int</span>) dX), itemView.getBottom());
                } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (dX &lt; <span class="hljs-number">0</span>) {
                    background.setBounds(itemView.getRight() + ((<span class="hljs-keyword">int</span>) dX), itemView.getTop(), itemView.getRight(), itemView.getBottom());
                } <span class="hljs-keyword">else</span> {
                    background.setBounds(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);
                }

                background.draw(c);
            }
        };
        ItemTouchHelper itemTouchHelper = <span class="hljs-keyword">new</span> ItemTouchHelper(touchHelperCallback);
        itemTouchHelper.attachToRecyclerView(recyclerView);

    }
</code></pre>
<p>We call the showMenu() function inside our adapter when a list item is swiped.</p>
<p>The onChildDraw() function draws the background while we swipe. Otherwise there'll be a white background while swiping and our menu layout will show up with a pop.</p>
<h2 id="heading-hiding-the-menu">Hiding the menu</h2>
<p>There are three ways to hide our menu.</p>
<ol>
<li>Hiding the menu when another row is swiped:</li>
</ol>
<p>This case is already handled in showMenu() method in our Adapter. Before showing the menu for any row, we first call <em>setShowMenu(false)</em> for all the rows to hide the menu.</p>
<ol start="2">
<li>Hiding the menu when the back button is pressed (in our Activity):</li>
</ol>
<pre><code class="lang-java"><span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onBackPressed</span><span class="hljs-params">()</span> </span>{
        <span class="hljs-keyword">if</span> (adapter.isMenuShown()) {
            adapter.closeMenu();
        } <span class="hljs-keyword">else</span> {
            <span class="hljs-keyword">super</span>.onBackPressed();
        }
    }
</code></pre>
<ol start="3">
<li>Hiding the menu when a user scrolls the list:</li>
</ol>
<pre><code class="lang-java">recyclerView.setOnScrollChangeListener(<span class="hljs-keyword">new</span> View.OnScrollChangeListener() {
            <span class="hljs-meta">@Override</span>
            <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">onScrollChange</span><span class="hljs-params">(View v, <span class="hljs-keyword">int</span> scrollX, <span class="hljs-keyword">int</span> scrollY, <span class="hljs-keyword">int</span> oldScrollX, <span class="hljs-keyword">int</span> oldScrollY)</span> </span>{
                adapter.closeMenu();
            }
        });
</code></pre>
<p>Though pocket only has a long-press action to show the menu, in this example we've added swipe to show the menu for added functionality. You can hide your menu item on swipe right/left again, but I think it might confuse the user. </p>
<h2 id="heading-wrapping-up">Wrapping up</h2>
<p>If your app has a very large dataset to show in a RecyclerView, this type of UX might not be the way to go. In that case you should have a bulk-edit sort of functionality. </p>
<p>Also if your edit options are more than what you can adjust in a RecyclerView row but you still want to show some quick actions, you can show a Bottomsheet dialog on long press of your item and it can have all your edit options. The <a target="_blank" href="https://play.google.com/store/apps/details?id=com.google.android.apps.docs&amp;hl=en_IN">Google Drive</a> android app does exactly the same thing.  </p>
<p>If you want to implement a simple swipe to delete function, the code for that can be found here <a target="_blank" href="https://github.com/iamtherealgd/RecyclerViewSwipeDelete">on Github</a>.</p>
<p>You can also check the <a target="_blank" href="https://github.com/iamtherealgd/RecyclerViewSwipeOptions">source code for this project</a> on Github.</p>
<p>Visit <a target="_blank" href="https://22boxes.com/">22Boxes.com</a> for more Mobile &amp; Web development resources.</p>
 ]]>
                </content:encoded>
            </item>
        
            <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>
