Skip to content
geeksforgeeks
  • Courses
    • DSA to Development
    • Get IBM Certification
    • Newly Launched!
      • Master Django Framework
      • Become AWS Certified
    • For Working Professionals
      • Interview 101: DSA & System Design
      • Data Science Training Program
      • JAVA Backend Development (Live)
      • DevOps Engineering (LIVE)
      • Data Structures & Algorithms in Python
    • For Students
      • Placement Preparation Course
      • Data Science (Live)
      • Data Structure & Algorithm-Self Paced (C++/JAVA)
      • Master Competitive Programming (Live)
      • Full Stack Development with React & Node JS (Live)
    • Full Stack Development
    • Data Science Program
    • All Courses
  • Tutorials
    • Data Structures & Algorithms
    • ML & Data Science
    • Interview Corner
    • Programming Languages
    • Web Development
    • CS Subjects
    • DevOps And Linux
    • School Learning
  • Practice
    • Build your AI Agent
    • GfG 160
    • Problem of the Day
    • Practice Coding Problems
    • GfG SDE Sheet
  • Contests
    • Accenture Hackathon (Ending Soon!)
    • GfG Weekly [Rated Contest]
    • Job-A-Thon Hiring Challenge
    • All Contests and Events
  • Java for Android
  • Android Studio
  • Android Kotlin
  • Kotlin
  • Flutter
  • Dart
  • Android Project
  • Android Interview
Open In App
Next Article:
How to Animate RecyclerView Items in Android?
Next article icon

How to Add Fade and Shrink Animation in RecyclerView in Android?

Last Updated : 14 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In this article, we are going to show the fade and shrink animation in RecyclerView. When we move downward then the item at the top will be fading out and then it will shrink. In the output, we can see how it is happening.

We will be implementing Java/Kotlin programming language.

Step by Step Implementation

Step 1: Create a new Project

To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.

Step 2: Create a Custom Layout Manager

Navigate to app > java > {package-name}, right click and select New > Java/Kotlin Class and set the name as CustomLayoutManager.

Now add the following code to the file.

CustomLayoutManager.java
package org.geeksforgeeks.demo;  import android.graphics.Rect; import android.util.ArrayMap; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.view.View; import android.view.ViewGroup; import androidx.recyclerview.widget.RecyclerView;  /**  * A custom RecyclerView LayoutManager that arranges items vertically  * with scale and fade animations as they scroll in and out of view.  */ public class CustomLayoutManager extends RecyclerView.LayoutManager {      private int scroll = 0;  // Current scroll position     private final SparseArray<Rect> locationRects = new SparseArray<>(); // Stores bounds of all items     private final SparseBooleanArray attachedItems = new SparseBooleanArray(); // Tracks which views are currently attached     private final ArrayMap<Integer, Integer> viewTypeHeightMap = new ArrayMap<>(); // Caches item heights per viewType      private boolean needSnap = false; // Whether we need to snap after scroll     private int lastDy = 0; // Last scroll delta     private int maxScroll = -1; // Maximum scroll value     private RecyclerView.Adapter adapter; // Adapter reference     private RecyclerView.Recycler recycler; // Recycler reference      public CustomLayoutManager() {         setAutoMeasureEnabled(true); // Enables auto measuring of child views     }      @Override     public RecyclerView.LayoutParams generateDefaultLayoutParams() {         return new RecyclerView.LayoutParams(             ViewGroup.LayoutParams.WRAP_CONTENT,             ViewGroup.LayoutParams.WRAP_CONTENT         );     }      @Override     public void onAdapterChanged(RecyclerView.Adapter oldAdapter, RecyclerView.Adapter newAdapter) {         super.onAdapterChanged(oldAdapter, newAdapter);         this.adapter = newAdapter;     }      @Override     public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {         this.recycler = recycler;          // Skip layout during pre-layout phase         if (state.isPreLayout()) return;          // Rebuild item layout information         buildLocationRects();          // Remove and recycle all current views         detachAndScrapAttachedViews(recycler);          // Layout the initial visible views         layoutItemsOnCreate(recycler);     }      /**      * Builds position and size data for all items.      */     private void buildLocationRects() {         locationRects.clear();         attachedItems.clear();          int tempPosition = getPaddingTop();         int itemCount = getItemCount();          for (int i = 0; i < itemCount; i++) {             int viewType = adapter.getItemViewType(i);             int itemHeight;              // Check height cache for view type             if (viewTypeHeightMap.containsKey(viewType)) {                 itemHeight = viewTypeHeightMap.get(viewType);             } else {                 // Measure item to get height                 View itemView = recycler.getViewForPosition(i);                 addView(itemView);                 measureChildWithMargins(itemView, View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);                 itemHeight = getDecoratedMeasuredHeight(itemView);                 viewTypeHeightMap.put(viewType, itemHeight);             }              // Record layout rectangle for the item             Rect rect = new Rect();             rect.left = getPaddingLeft();             rect.top = tempPosition;             rect.right = getWidth() - getPaddingRight();             rect.bottom = rect.top + itemHeight;             locationRects.put(i, rect);             attachedItems.put(i, false);             tempPosition += itemHeight;         }          // Calculate maximum scroll distance         maxScroll = itemCount == 0 ? 0 : computeMaxScroll();     }      public int findFirstVisibleItemPosition() {         int count = locationRects.size();         Rect displayRect = new Rect(0, scroll, getWidth(), getHeight() + scroll);          for (int i = 0; i < count; i++) {             if (Rect.intersects(displayRect, locationRects.get(i)) && attachedItems.get(i)) {                 return i;             }         }         return 0;     }      private int computeMaxScroll() {         int max = locationRects.get(locationRects.size() - 1).bottom - getHeight();         if (max < 0) return 0;          // Add extra height for snap if items partially fill screen         int screenFilledHeight = 0;         for (int i = getItemCount() - 1; i >= 0; i--) {             Rect rect = locationRects.get(i);             screenFilledHeight += (rect.bottom - rect.top);             if (screenFilledHeight > getHeight()) {                 int extraSnapHeight = getHeight() - (screenFilledHeight - (rect.bottom - rect.top));                 max += extraSnapHeight;                 break;             }         }         return max;     }      /**      * Lays out views during initial layout (onCreate).      */     private void layoutItemsOnCreate(RecyclerView.Recycler recycler) {         int itemCount = getItemCount();         Rect displayRect = new Rect(0, scroll, getWidth(), getHeight() + scroll);          for (int i = 0; i < itemCount; i++) {             Rect thisRect = locationRects.get(i);             if (Rect.intersects(displayRect, thisRect)) {                 View childView = recycler.getViewForPosition(i);                 addView(childView);                 measureChildWithMargins(childView, View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);                 layoutItem(childView, thisRect);                 attachedItems.put(i, true);                 childView.setPivotY(0);                 childView.setPivotX(childView.getMeasuredWidth() / 2f);                  // Stop laying out if beyond screen height                 if (thisRect.top - scroll > getHeight()) break;             }         }     }      /**      * Handles layout during scrolling.      */     private void layoutItemsOnScroll() {         int childCount = getChildCount();         int itemCount = getItemCount();         Rect displayRect = new Rect(0, scroll, getWidth(), getHeight() + scroll);         int firstVisiblePosition = -1, lastVisiblePosition = -1;          // Remove views out of bounds, update bounds of visible ones         for (int i = childCount - 1; i >= 0; i--) {             View child = getChildAt(i);             if (child == null) continue;              int position = getPosition(child);             if (!Rect.intersects(displayRect, locationRects.get(position))) {                 removeAndRecycleView(child, recycler);                 attachedItems.put(position, false);             } else {                 if (lastVisiblePosition < 0) lastVisiblePosition = position;                 if (firstVisiblePosition < 0) firstVisiblePosition = position;                 else firstVisiblePosition = Math.min(firstVisiblePosition, position);                  layoutItem(child, locationRects.get(position));             }         }          // Add views before and after visible range         if (firstVisiblePosition > 0) {             for (int i = firstVisiblePosition - 1; i >= 0; i--) {                 if (Rect.intersects(displayRect, locationRects.get(i)) && !attachedItems.get(i)) {                     reuseItemOnSroll(i, true);                 } else break;             }         }          for (int i = lastVisiblePosition + 1; i < itemCount; i++) {             if (Rect.intersects(displayRect, locationRects.get(i)) && !attachedItems.get(i)) {                 reuseItemOnSroll(i, false);             } else break;         }     }      /**      * Reuses a view at the given position and attaches it to layout.      */     private void reuseItemOnSroll(int position, boolean addViewFromTop) {         View scrap = recycler.getViewForPosition(position);         measureChildWithMargins(scrap, 0, 0);         scrap.setPivotY(0);         scrap.setPivotX(scrap.getMeasuredWidth() / 2f);          if (addViewFromTop) addView(scrap, 0);         else addView(scrap);          layoutItem(scrap, locationRects.get(position));         attachedItems.put(position, true);     }      /**      * Lays out a single child view and applies scale/alpha transformations.      */     private void layoutItem(View child, Rect rect) {         int topDistance = scroll - rect.top;         int layoutTop, layoutBottom;         int itemHeight = rect.bottom - rect.top;          if (topDistance > 0 && topDistance < itemHeight) {             float rate1 = (float) topDistance / itemHeight;             float rate2 = 1 - rate1 * rate1 / 3;             float rate3 = 1 - rate1 * rate1;              child.setScaleX(rate2);             child.setScaleY(rate2);             child.setAlpha(rate3);              layoutTop = 0;             layoutBottom = itemHeight;         } else {             child.setScaleX(1);             child.setScaleY(1);             child.setAlpha(1);             layoutTop = rect.top - scroll;             layoutBottom = rect.bottom - scroll;         }          layoutDecorated(child, rect.left, layoutTop, rect.right, layoutBottom);     }      @Override     public boolean canScrollVertically() {         return true;     }      @Override     public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) {         if (getItemCount() == 0 || dy == 0) return 0;          int travel = dy;         if (scroll + dy < 0) {             travel = -scroll;         } else if (scroll + dy > maxScroll) {             travel = maxScroll - scroll;         }          scroll += travel;         lastDy = dy;          if (!state.isPreLayout() && getChildCount() > 0) {             layoutItemsOnScroll();         }          return travel;     }      @Override     public void onAttachedToWindow(RecyclerView view) {         super.onAttachedToWindow(view);         new StartSnapHelper().attachToRecyclerView(view); // Attach custom snap helper     }      @Override     public void onScrollStateChanged(int state) {         if (state == RecyclerView.SCROLL_STATE_DRAGGING) {             needSnap = true;         }         super.onScrollStateChanged(state);     }      /**      * Returns the amount needed to scroll for a snap-to-position effect.      */     public int getSnapHeight() {         if (!needSnap) return 0;         needSnap = false;          Rect displayRect = new Rect(0, scroll, getWidth(), getHeight() + scroll);         int itemCount = getItemCount();          for (int i = 0; i < itemCount; i++) {             Rect itemRect = locationRects.get(i);             if (displayRect.intersect(itemRect)) {                 if (lastDy > 0 && i < itemCount - 1) {                     Rect nextRect = locationRects.get(i + 1);                     return nextRect.top - displayRect.top;                 }                 return itemRect.top - displayRect.top;             }         }         return 0;     }      /**      * Returns the first visible view to be used for snapping.      */     public View findSnapView() {         if (getChildCount() > 0) {             return getChildAt(0);         }         return null;     } } 
CustomLayoutManager.kt
package org.geeksforgeeks.demo  import android.graphics.Rect import android.util.ArrayMap import android.util.SparseArray import android.util.SparseBooleanArray import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import kotlin.math.min  class CustomLayoutManager : RecyclerView.LayoutManager() {     // Total vertical scroll offset     private var scroll = 0      // Stores position to Rect mapping (item layout bounds)     private val locationRects = SparseArray<Rect>()      // Tracks which items are currently attached (visible)     private val attachedItems = SparseBooleanArray()      // Caches height of views per view type     private val viewTypeHeightMap = ArrayMap<Int, Int>()      // Used for snapping behavior     private var needSnap = false     private var lastDy = 0     private var maxScroll = -1      // Adapter and recycler references     private var adapter: RecyclerView.Adapter<*>? = null     private var recycler: RecyclerView.Recycler? = null      init {         // Enables auto-measuring of children         isAutoMeasureEnabled = true     }      override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {         return RecyclerView.LayoutParams(             ViewGroup.LayoutParams.WRAP_CONTENT,             ViewGroup.LayoutParams.WRAP_CONTENT         )     }      // Save adapter reference when changed     override fun onAdapterChanged(oldAdapter: RecyclerView.Adapter<*>?, newAdapter: RecyclerView.Adapter<*>?) {         super.onAdapterChanged(oldAdapter, newAdapter)         this.adapter = newAdapter     }      // Lays out children when layout is first created or invalidated     override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {         this.recycler = recycler         if (state.isPreLayout) return          // Calculate item positions         buildLocationRects()          // Remove current views and layout visible ones         detachAndScrapAttachedViews(recycler)         layoutItemsOnCreate(recycler)     }      // Pre-calculates layout bounds for each item     private fun buildLocationRects() {         locationRects.clear()         attachedItems.clear()          var tempPosition = paddingTop         val itemCount = itemCount          for (i in 0 until itemCount) {             val viewType = adapter!!.getItemViewType(i)             val itemHeight: Int              // Reuse height if cached             if (viewTypeHeightMap.containsKey(viewType)) {                 itemHeight = viewTypeHeightMap[viewType]!!             } else {                 val itemView = recycler!!.getViewForPosition(i)                 addView(itemView)                 measureChildWithMargins(itemView, View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)                 itemHeight = getDecoratedMeasuredHeight(itemView)                 viewTypeHeightMap[viewType] = itemHeight             }              // Create bounding rect for item             val rect = Rect(paddingLeft, tempPosition, width - paddingRight, tempPosition + itemHeight)             locationRects.put(i, rect)             attachedItems.put(i, false)             tempPosition += itemHeight         }          // Compute max scroll range         maxScroll = if (itemCount == 0) 0 else {             computeMaxScroll()             maxScroll         }     }      // Finds the first visible item in viewport     fun findFirstVisibleItemPosition(): Int {         val displayRect = Rect(0, scroll, width, height + scroll)         for (i in 0 until locationRects.size()) {             if (Rect.intersects(displayRect, locationRects[i]) && attachedItems[i]) {                 return i             }         }         return 0     }      // Calculates how far we can scroll     private fun computeMaxScroll() {         maxScroll = locationRects[locationRects.size() - 1].bottom - height         if (maxScroll < 0) {             maxScroll = 0             return         }          // Add extra snap distance if needed         var screenFilledHeight = 0         for (i in itemCount - 1 downTo 0) {             val rect = locationRects[i]             screenFilledHeight += rect.bottom - rect.top             if (screenFilledHeight > height) {                 val extraSnapHeight = height - (screenFilledHeight - (rect.bottom - rect.top))                 maxScroll += extraSnapHeight                 break             }         }     }      // Lays out visible items during initial layout     private fun layoutItemsOnCreate(recycler: RecyclerView.Recycler) {         val displayRect = Rect(0, scroll, width, height + scroll)         for (i in 0 until itemCount) {             val thisRect = locationRects[i]             if (Rect.intersects(displayRect, thisRect)) {                 val childView = recycler.getViewForPosition(i)                 addView(childView)                 measureChildWithMargins(childView, View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)                 layoutItem(childView, thisRect)                 attachedItems.put(i, true)                  // Set pivot for animation                 childView.pivotY = 0f                 childView.pivotX = (childView.measuredWidth / 2).toFloat()                  if (thisRect.top - scroll > height) break             }         }     }      // Updates layout during scroll     private fun layoutItemsOnScroll() {         val displayRect = Rect(0, scroll, width, height + scroll)         var firstVisible = -1         var lastVisible = -1          // Detach non-visible views         for (i in childCount - 1 downTo 0) {             val child = getChildAt(i) ?: continue             val position = getPosition(child)             if (!Rect.intersects(displayRect, locationRects[position])) {                 removeAndRecycleView(child, recycler!!)                 attachedItems.put(position, false)             } else {                 // Keep visible                 lastVisible = maxOf(lastVisible, position)                 firstVisible = if (firstVisible == -1) position else min(firstVisible, position)                 layoutItem(child, locationRects[position])             }         }          // Layout new visible views above         if (firstVisible > 0) {             for (i in firstVisible - 1 downTo 0) {                 if (Rect.intersects(displayRect, locationRects[i]) && !attachedItems[i]) {                     reuseItemOnScroll(i, true)                 } else break             }         }          // Layout new visible views below         for (i in lastVisible + 1 until itemCount) {             if (Rect.intersects(displayRect, locationRects[i]) && !attachedItems[i]) {                 reuseItemOnScroll(i, false)             } else break         }     }      // Reuse a view for given position     private fun reuseItemOnScroll(position: Int, addViewFromTop: Boolean) {         val scrap = recycler!!.getViewForPosition(position)         measureChildWithMargins(scrap, 0, 0)         scrap.pivotY = 0f         scrap.pivotX = (scrap.measuredWidth / 2).toFloat()          if (addViewFromTop) addView(scrap, 0) else addView(scrap)         layoutItem(scrap, locationRects[position])         attachedItems.put(position, true)     }      // Lays out a single item with scale/alpha effects     private fun layoutItem(child: View, rect: Rect) {         val topDistance = scroll - rect.top         val itemHeight = rect.bottom - rect.top         val layoutTop: Int         val layoutBottom: Int          // Apply animation if item is sliding into view         if (topDistance in 1 until itemHeight) {             val rate1 = topDistance.toFloat() / itemHeight             val rate2 = 1 - rate1 * rate1 / 3             val rate3 = 1 - rate1 * rate1             child.scaleX = rate2             child.scaleY = rate2             child.alpha = rate3             layoutTop = 0             layoutBottom = itemHeight         } else {             child.scaleX = 1f             child.scaleY = 1f             child.alpha = 1f             layoutTop = rect.top - scroll             layoutBottom = rect.bottom - scroll         }          layoutDecorated(child, rect.left, layoutTop, rect.right, layoutBottom)     }      override fun canScrollVertically(): Boolean = true      // Handles vertical scroll     override fun scrollVerticallyBy(dy: Int, recycler: RecyclerView.Recycler, state: RecyclerView.State): Int {         if (itemCount == 0 || dy == 0) return 0          var travel = dy         // Prevent scrolling beyond bounds         if (scroll + dy < 0) {             travel = -scroll         } else if (scroll + dy > maxScroll) {             travel = maxScroll - scroll         }          scroll += travel         lastDy = dy          if (!state.isPreLayout && childCount > 0) {             layoutItemsOnScroll()         }          return travel     }      // Attach snap helper when attached to RecyclerView     override fun onAttachedToWindow(view: RecyclerView) {         super.onAttachedToWindow(view)         StartSnapHelper().attachToRecyclerView(view)     }      // Track snap need     override fun onScrollStateChanged(state: Int) {         if (state == RecyclerView.SCROLL_STATE_DRAGGING) {             needSnap = true         }         super.onScrollStateChanged(state)     }      // Get height needed to snap to next item     val snapHeight: Int         get() {             if (!needSnap) return 0             needSnap = false              val displayRect = Rect(0, scroll, width, height + scroll)             for (i in 0 until itemCount) {                 val itemRect = locationRects[i]                 if (displayRect.intersect(itemRect)) {                     return if (lastDy > 0 && i < itemCount - 1) {                         locationRects[i + 1].top - displayRect.top                     } else {                         itemRect.top - displayRect.top                     }                 }             }             return 0         }      // Find view to snap to     fun findSnapView(): View? = if (childCount > 0) getChildAt(0) else null } 


Step 3: Create a Custom Snap Helper for the Layout Manager

Navigate to app > java > {package-name}, right click and select New > Java/Kotlin Class and set the name as StartSnapHelper.

Now add the following code to the file.

StartSnapHelper.java
package org.geeksforgeeks.demo;  import android.view.View; import androidx.annotation.NonNull; import androidx.recyclerview.widget.LinearSnapHelper; import androidx.recyclerview.widget.RecyclerView;  /**  * A custom SnapHelper that snaps the top of an item to the top of the RecyclerView  * using the CustomLayoutManager's logic.  */ public class StartSnapHelper extends LinearSnapHelper {      /**      * Calculates how much more the RecyclerView should scroll to align the targetView properly.      *      * @param layoutManager The LayoutManager being used by the RecyclerView.      * @param targetView The view that needs to be snapped into position.      * @return An array with two elements: horizontal and vertical distances to scroll.      */     @Override     public int[] calculateDistanceToFinalSnap(@NonNull RecyclerView.LayoutManager layoutManager,                                               @NonNull View targetView) {         int[] out = new int[2];          // No horizontal snapping, so set X distance to 0         out[0] = 0;          // Ask the CustomLayoutManager how far we should scroll vertically to snap         out[1] = ((CustomLayoutManager) layoutManager).getSnapHeight();          return out;     }      /**      * Finds the view that should be snapped to after scroll/fling ends.      *      * @param layoutManager The LayoutManager used by RecyclerView.      * @return The View to snap to, or null if no snapping is needed.      */     @Override     public View findSnapView(RecyclerView.LayoutManager layoutManager) {         // Delegate to CustomLayoutManager's snap logic         CustomLayoutManager custLayoutManager = (CustomLayoutManager) layoutManager;         return custLayoutManager.findSnapView();     } } 
StartSnapHelper.kt
package org.geeksforgeeks.demo  import android.view.View import androidx.recyclerview.widget.LinearSnapHelper import androidx.recyclerview.widget.RecyclerView  /**  * A custom SnapHelper that snaps the top of an item to the top of the RecyclerView.  * It works in combination with a CustomLayoutManager to determine the exact snap behavior.  */ class StartSnapHelper : LinearSnapHelper() {      /**      * Calculates the distance needed to scroll in order to snap the target view into position.      *      * @param layoutManager The LayoutManager used by the RecyclerView.      * @param targetView The view that we want to snap.      * @return An IntArray with horizontal and vertical distances to scroll.      */     override fun calculateDistanceToFinalSnap(         layoutManager: RecyclerView.LayoutManager,         targetView: View     ): IntArray {         val out = IntArray(2)          // No horizontal snapping needed, so X offset is 0         out[0] = 0          // Get vertical snap offset from the CustomLayoutManager         out[1] = (layoutManager as CustomLayoutManager).snapHeight          return out     }      /**      * Finds the view that should be snapped to the top after scroll/fling.      *      * @param layoutManager The LayoutManager used by the RecyclerView.      * @return The View to snap to, or null if none found.      */     override fun findSnapView(layoutManager: RecyclerView.LayoutManager): View? {         val custLayoutManager = layoutManager as CustomLayoutManager         return custLayoutManager.findSnapView()     } } 


Step 4: Working with the item.xml file

Go to the app > res > layout > New > Layout Resource File and name the file as item. Go to the item.xml file and refer to the following code. Below is the code for the item.xml file.

item.xml:

XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:orientation="vertical">      <Button         android:id="@+id/button"         android:layout_width="match_parent"         android:layout_height="60dp"         android:background="@color/white"         android:layout_margin="16dp"         android:text="Click Here" />  </LinearLayout> 


Step 4: Working with the Adapter file

Create a new Java/Kotlin class and name the class as Adapter. Go to the Adapter file and refer to the following code.

Adapter.java
package org.geeksforgeeks.demo;  import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.Toast;  import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView;  public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {      private final int totalCount;      public Adapter(int totalCount) {         this.totalCount = totalCount;     }      @NonNull     @Override     public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {         View view = LayoutInflater.from(parent.getContext())                 .inflate(R.layout.item, parent, false);         return new ViewHolder(view);     }      @Override     public void onBindViewHolder(@NonNull ViewHolder holder, int position) {         holder.button.setText("Button " + position);         holder.button.setOnClickListener(v ->             Toast.makeText(holder.itemView.getContext(), "Clicked : " + position, Toast.LENGTH_LONG).show()         );     }      @Override     public int getItemCount() {         return totalCount;     }      public static class ViewHolder extends RecyclerView.ViewHolder {         Button button;          public ViewHolder(@NonNull View itemView) {             super(itemView);             button = itemView.findViewById(R.id.button);         }     } } 
Adapter.kt
package org.geeksforgeeks.demo  import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button import android.widget.Toast import androidx.recyclerview.widget.RecyclerView  class Adapter(     private val totalCount: Int ) : RecyclerView.Adapter<Adapter.ViewHolder>() {      override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {         val view: View = LayoutInflater.from(parent.context).inflate(R.layout.item, parent, false)         return ViewHolder(view)     }      override fun onBindViewHolder(holder: ViewHolder, position: Int) {         holder.button.text = "Button $position"         holder.button.setOnClickListener {             Toast.makeText(                 holder.itemView.context,                 "Clicked : $position",                 Toast.LENGTH_LONG             ).show()         }     }      override fun getItemCount(): Int {         return totalCount     }      inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {         var button: Button = itemView.findViewById(R.id.button)     } } 


Step 5: Working with the activity_main.xml file

Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file. 

activity_main.xml:

XML
<?xml version="1.0" encoding="utf-8"?> <LinearLayout     xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     android:orientation="vertical"     tools:context=".MainActivity">      <androidx.recyclerview.widget.RecyclerView         android:id="@+id/rcv"         android:layout_width="match_parent"         android:layout_height="match_parent" />  </LinearLayout> 


Step 6: Working with the MainActivity file

Go to the MainActivity file and refer to the following code. Below is the code for the MainActivity file. Comments are added inside the code to understand the code in more detail.

MainActivity.java
package org.geeksforgeeks.demo;  import android.os.Bundle;  import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.RecyclerView;  public class MainActivity extends AppCompatActivity {     private RecyclerView recyclerView;      @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);                  recyclerView = findViewById(R.id.rcv);          // Set the custom layout manager (handles fade and shrink)         recyclerView.setLayoutManager(new CustomLayoutManager());          // Set the adapter with 50 items         recyclerView.setAdapter(new Adapter(50));     } } 
MainActivity.kt
package org.geeksforgeeks.demo  import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.RecyclerView  class MainActivity : AppCompatActivity() {     private lateinit var recyclerView: RecyclerView      override fun onCreate(savedInstanceState: Bundle?) {         super.onCreate(savedInstanceState)         setContentView(R.layout.activity_main)         recyclerView = findViewById(R.id.rcv)          // We have used this to add fade and shrink method         recyclerView.setLayoutManager(CustomLayoutManager())         recyclerView.setAdapter(Adapter(50))     } } 


Output:




Next Article
How to Animate RecyclerView Items in Android?

A

annianni
Improve
Article Tags :
  • Android
  • Android-Animation

Similar Reads

  • How to Add Drag And Drop Feature in Android RecyclerView?
    Drag And Drop feature is very helpful. It is very simple and easy to implement. It is used in many apps that are famous, and if we're doing some project it is very convenient to implement it. You should know the RecyclerAdapter Class. A sample video is given below to get an idea about what we are go
    4 min read
  • How to Animate RecyclerView Items in Android?
    RecyclerView Item animation is one of the modern features that we can add to our Android app, the basic working of this is when any user opens our app then the data items that are present in recycler view will animate and then it will show to the user.it is so easy to implement also it can enhance t
    5 min read
  • How to add fading TextView animation in Android
    TextView is the basic building block of user interface components. It is used to set the text and display it to the user. It is a very basic component and used a lot. A Fading TextView is a TextView that changes its content automatically every few seconds. If we want to design a beautiful interface
    1 min read
  • How to Add Dividers in Android RecyclerView?
    In the article Android RecyclerView in Kotlin, it's been demonstrated how to implement the Recycler View in Android. But in the case of User Experience, the items need to be distinguished with the divider and proper padding and margins in each item. In this case, the Recycler View Item Decoration co
    9 min read
  • How to add Lottie Animation in an Android app
    This article is about enhancing the User Interface of the mobile application by adding Lottie animation files into our mobile app. The Lottie animations are free to use vector animation files. These animation files can be found at the official site here. Many famous applications use this such as Ube
    2 min read
  • How to insert Slide From Bottom animation in RecyclerView in Android
    In this article, the animation that makes the items slide from the bottom is added in the recycler view. Here we don`t use any other library to add the animation. Adding animations make the application attractive and give a better user experience. Approach:Step 1: Create "anim" resource directory. R
    2 min read
  • How to Disable RecyclerView Scrolling in Android?
    RecyclerView is a view group used for displaying data from arrays and databases. RecyclerView basically is a list of items from the data. RecyclerView is often referred to as a successor of GridView and ListView. More about RecyclerView could be found at RecyclerView in Android with Example. Recycle
    3 min read
  • How to add Bullet list in a RecyclerView in Android?
    Recycler View allows us to show a list of items but to convert our list into the bulleted list we have to do some extra work. You can do this task by following these simple steps given below:- Add the support Library in build.gradle file for Recycler View in the dependencies section.  [GFGTABS] XML
    2 min read
  • How to Build a Facebook Like Custom RecyclerView in Android?
    We have seen implementing RecyclerView in Android with simple data inside our app. In this article, we will take a look at the implementation of Facebook like Custom RecyclerView in Android. What we are going to build in this article? We will be building a simple application in which we will display
    9 min read
  • How to Use View Binding in RecyclerView Adapter Class in Android?
    View Binding is a part of Android Jetpack which provides the views to bind with the classes by replacing the findViewById() method in a null safe way. In this article, we will see its implementations in the Adapter class of RecyclerView. Note that we are going to implement this project using the Kot
    5 min read
geeksforgeeks-footer-logo
Corporate & Communications Address:
A-143, 7th Floor, Sovereign Corporate Tower, Sector- 136, Noida, Uttar Pradesh (201305)
Registered Address:
K 061, Tower K, Gulshan Vivante Apartment, Sector 137, Noida, Gautam Buddh Nagar, Uttar Pradesh, 201305
GFG App on Play Store GFG App on App Store
Advertise with us
  • Company
  • About Us
  • Legal
  • Privacy Policy
  • In Media
  • Contact Us
  • Advertise with us
  • GFG Corporate Solution
  • Placement Training Program
  • Languages
  • Python
  • Java
  • C++
  • PHP
  • GoLang
  • SQL
  • R Language
  • Android Tutorial
  • Tutorials Archive
  • DSA
  • Data Structures
  • Algorithms
  • DSA for Beginners
  • Basic DSA Problems
  • DSA Roadmap
  • Top 100 DSA Interview Problems
  • DSA Roadmap by Sandeep Jain
  • All Cheat Sheets
  • Data Science & ML
  • Data Science With Python
  • Data Science For Beginner
  • Machine Learning
  • ML Maths
  • Data Visualisation
  • Pandas
  • NumPy
  • NLP
  • Deep Learning
  • Web Technologies
  • HTML
  • CSS
  • JavaScript
  • TypeScript
  • ReactJS
  • NextJS
  • Bootstrap
  • Web Design
  • Python Tutorial
  • Python Programming Examples
  • Python Projects
  • Python Tkinter
  • Python Web Scraping
  • OpenCV Tutorial
  • Python Interview Question
  • Django
  • Computer Science
  • Operating Systems
  • Computer Network
  • Database Management System
  • Software Engineering
  • Digital Logic Design
  • Engineering Maths
  • Software Development
  • Software Testing
  • DevOps
  • Git
  • Linux
  • AWS
  • Docker
  • Kubernetes
  • Azure
  • GCP
  • DevOps Roadmap
  • System Design
  • High Level Design
  • Low Level Design
  • UML Diagrams
  • Interview Guide
  • Design Patterns
  • OOAD
  • System Design Bootcamp
  • Interview Questions
  • Inteview Preparation
  • Competitive Programming
  • Top DS or Algo for CP
  • Company-Wise Recruitment Process
  • Company-Wise Preparation
  • Aptitude Preparation
  • Puzzles
  • School Subjects
  • Mathematics
  • Physics
  • Chemistry
  • Biology
  • Social Science
  • English Grammar
  • Commerce
  • World GK
  • GeeksforGeeks Videos
  • DSA
  • Python
  • Java
  • C++
  • Web Development
  • Data Science
  • CS Subjects
@GeeksforGeeks, Sanchhaya Education Private Limited, All rights reserved
We use cookies to ensure you have the best browsing experience on our website. By using our site, you acknowledge that you have read and understood our Cookie Policy & Privacy Policy
Lightbox
Improvement
Suggest Changes
Help us improve. Share your suggestions to enhance the article. Contribute your expertise and make a difference in the GeeksforGeeks portal.
geeksforgeeks-suggest-icon
Create Improvement
Enhance the article with your expertise. Contribute to the GeeksforGeeks community and help create better learning resources for all.
geeksforgeeks-improvement-icon
Suggest Changes
min 4 words, max Words Limit:1000

Thank You!

Your suggestions are valuable to us.

What kind of Experience do you want to share?

Interview Experiences
Admission Experiences
Career Journeys
Work Experiences
Campus Experiences
Competitive Exam Experiences