Convert Figma logo to code with AI

Flipkart logorecyclerlistview

High performance listview for React Native and web!

5,270
428
5,270
259

Top Related Projects

34,636

An image loading and caching library for Android focused on smooth scrolling

17,070

An Android library for managing images and the memory they use.

18,710

A powerful image downloading and caching library for Android

An Android Animation library which easily add itemanimator to RecyclerView items.

8,512

Epoxy is an Android library for building complex screens in a RecyclerView

Flexible multiple types for Android RecyclerView.

Quick Overview

RecyclerListView is a high-performance ListView for React Native and web platforms. It provides a virtualized list implementation with features like dynamic rendering, view recycling, and optimized memory usage, making it ideal for rendering large lists of data efficiently.

Pros

  • High performance and efficient memory usage
  • Cross-platform support (React Native and Web)
  • Customizable layouts and advanced features like sticky headers
  • Active maintenance and community support

Cons

  • Learning curve for developers new to virtualized lists
  • May require additional setup compared to simpler list components
  • Limited built-in layout options compared to some alternatives
  • Performance benefits may be less noticeable for smaller lists

Code Examples

  1. Basic usage with default layout:
import { RecyclerListView, DataProvider, LayoutProvider } from "recyclerlistview";

const dataProvider = new DataProvider((r1, r2) => r1 !== r2);
const layoutProvider = new LayoutProvider(
  index => 0,
  (type, dim) => {
    dim.width = width;
    dim.height = 100;
  }
);

<RecyclerListView
  layoutProvider={layoutProvider}
  dataProvider={dataProvider.cloneWithRows(data)}
  rowRenderer={(type, data) => <YourRowComponent data={data} />}
/>
  1. Using a grid layout:
const layoutProvider = new LayoutProvider(
  index => 0,
  (type, dim) => {
    dim.width = width / 3;
    dim.height = 100;
  }
);

<RecyclerListView
  layoutProvider={layoutProvider}
  dataProvider={dataProvider.cloneWithRows(data)}
  rowRenderer={(type, data) => <YourGridItemComponent data={data} />}
/>
  1. Implementing sticky headers:
import { StickyContainer, RecyclerListView } from "recyclerlistview";

<StickyContainer stickyHeaderIndices={[0, 10, 20]}>
  <RecyclerListView
    // ... other props
    renderAheadOffset={250}
  />
</StickyContainer>

Getting Started

  1. Install the package:

    npm install recyclerlistview
    
  2. Import and use in your React Native or Web project:

    import { RecyclerListView, DataProvider, LayoutProvider } from "recyclerlistview";
    
    // Set up data provider
    const dataProvider = new DataProvider((r1, r2) => r1 !== r2);
    
    // Set up layout provider
    const layoutProvider = new LayoutProvider(
      index => 0,
      (type, dim) => {
        dim.width = width;
        dim.height = 100;
      }
    );
    
    // Use in your component
    function MyList({ data }) {
      return (
        <RecyclerListView
          layoutProvider={layoutProvider}
          dataProvider={dataProvider.cloneWithRows(data)}
          rowRenderer={(type, data) => <YourRowComponent data={data} />}
        />
      );
    }
    

Competitor Comparisons

34,636

An image loading and caching library for Android focused on smooth scrolling

Pros of Glide

  • Specialized for image loading and caching, offering efficient memory management
  • Supports various image formats and sources (URLs, local files, resources)
  • Extensive customization options for image transformations and placeholders

Cons of Glide

  • Limited to image handling, unlike RecyclerListView's versatile list rendering
  • May require additional setup for complex list scenarios
  • Potential performance overhead for simple image loading tasks

Code Comparison

RecyclerListView (list rendering):

<RecyclerListView
    layoutProvider={this._layoutProvider}
    dataProvider={this._dataProvider}
    rowRenderer={this._rowRenderer}
/>

Glide (image loading):

Glide.with(context)
    .load(imageUrl)
    .placeholder(R.drawable.placeholder)
    .into(imageView);

Key Differences

RecyclerListView focuses on efficient list rendering with virtualization, while Glide specializes in image loading and caching. RecyclerListView is more suitable for complex, high-performance list views, whereas Glide excels in image-centric applications.

RecyclerListView offers greater control over list item layouts and recycling, making it ideal for heterogeneous lists. Glide, on the other hand, provides a simpler API for image loading tasks with built-in optimizations.

Choose RecyclerListView for complex list requirements and performance-critical scenarios. Opt for Glide when dealing primarily with image loading and caching in your Android application.

17,070

An Android library for managing images and the memory they use.

Pros of Fresco

  • Optimized for image loading and caching, with advanced features like progressive loading and WebP support
  • Supports a wide range of image formats and sources, including network, local storage, and content providers
  • Offers memory management tools to prevent OutOfMemoryErrors

Cons of Fresco

  • Larger library size compared to RecyclerListView, which may impact app size
  • Steeper learning curve due to its extensive feature set
  • Primarily focused on image handling, while RecyclerListView is more versatile for general list rendering

Code Comparison

RecyclerListView:

<RecyclerListView
  layoutProvider={this._layoutProvider}
  dataProvider={this._dataProvider}
  rowRenderer={this._rowRenderer}
/>

Fresco:

<com.facebook.drawee.view.SimpleDraweeView
  android:id="@+id/my_image_view"
  android:layout_width="130dp"
  android:layout_height="130dp"
  fresco:placeholderImage="@drawable/my_drawable"
/>

Summary

RecyclerListView is a lightweight, high-performance list rendering library for React Native, focusing on efficient list virtualization. Fresco, on the other hand, is a powerful image loading and caching library for Android, offering advanced image handling capabilities. While RecyclerListView excels in rendering large lists with minimal memory footprint, Fresco provides robust image management features but comes with a larger library size and steeper learning curve.

18,710

A powerful image downloading and caching library for Android

Pros of Picasso

  • Specialized for image loading and caching, offering optimized performance for image-heavy applications
  • Extensive features like image transformations, placeholder images, and error handling
  • Well-established library with a large community and extensive documentation

Cons of Picasso

  • Limited to image handling, not suitable for general list rendering or complex UI components
  • May require additional libraries for advanced list management in Android applications
  • Less flexibility for custom list item layouts compared to RecyclerListView

Code Comparison

RecyclerListView:

<RecyclerListView
    layoutProvider={this._layoutProvider}
    dataProvider={this._dataProvider}
    rowRenderer={this._rowRenderer}
/>

Picasso:

Picasso.get()
    .load("https://example.com/image.jpg")
    .placeholder(R.drawable.placeholder)
    .error(R.drawable.error)
    .into(imageView);

Summary

RecyclerListView is a high-performance list view library for React Native, focusing on efficient rendering of large lists with complex layouts. Picasso, on the other hand, is an Android-specific image loading and caching library. While both aim to improve performance, they serve different purposes: RecyclerListView for list management and Picasso for image handling. The choice between them depends on the specific needs of your project, with RecyclerListView being more suitable for complex list rendering and Picasso for optimized image loading in Android applications.

An Android Animation library which easily add itemanimator to RecyclerView items.

Pros of recyclerview-animators

  • Offers a wide variety of pre-built animations for RecyclerView items
  • Easy to implement with minimal code changes
  • Supports custom animations for more flexibility

Cons of recyclerview-animators

  • Limited to animation-specific features
  • May have performance impact on large lists with complex animations
  • Less focus on overall RecyclerView optimization

Code Comparison

recyclerview-animators:

val animator = SlideInLeftAnimator()
recyclerView.itemAnimator = animator

recyclerlistview:

<RecyclerListView
  layoutProvider={this._layoutProvider}
  dataProvider={this._dataProvider}
  rowRenderer={this._rowRenderer}
/>

Key Differences

recyclerview-animators focuses specifically on adding animations to RecyclerView items, while recyclerlistview is a more comprehensive solution for efficient list rendering. recyclerlistview offers better performance for large lists and complex layouts, while recyclerview-animators provides an easy way to add visual flair to RecyclerView items.

recyclerview-animators is primarily used in Android development with Kotlin or Java, whereas recyclerlistview is designed for React Native applications. The choice between the two depends on the specific platform and requirements of your project.

8,512

Epoxy is an Android library for building complex screens in a RecyclerView

Pros of Epoxy

  • More comprehensive feature set, including support for complex layouts and animations
  • Better integration with Kotlin and Android Jetpack libraries
  • Extensive documentation and community support

Cons of Epoxy

  • Steeper learning curve due to its complexity
  • Potentially higher memory usage for large lists
  • More setup required for basic use cases

Code Comparison

RecyclerListView:

class SimpleListView : RecyclerListView() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        // Create and return ViewHolder
    }
}

Epoxy:

@EpoxyModelClass(layout = R.layout.item_view)
abstract class ItemModel : EpoxyModelWithHolder<ItemModel.Holder>() {
    @EpoxyAttribute lateinit var title: String
    
    override fun bind(holder: Holder) {
        holder.titleView.text = title
    }
    
    class Holder : EpoxyHolder() {
        lateinit var titleView: TextView
        override fun bindView(itemView: View) {
            titleView = itemView.findViewById(R.id.title)
        }
    }
}

RecyclerListView is simpler and more lightweight, making it easier to set up for basic list views. It's particularly efficient for long, scrollable lists with minimal customization.

Epoxy offers more powerful features and better integration with modern Android development practices, but comes with increased complexity and potential overhead for simpler use cases.

Flexible multiple types for Android RecyclerView.

Pros of MultiType

  • Simpler API and easier to use for basic list scenarios
  • Built-in support for multiple view types without complex setup
  • More lightweight and focused on core functionality

Cons of MultiType

  • Less optimized for large lists and complex scrolling scenarios
  • Fewer built-in performance optimizations compared to RecyclerListView
  • Limited support for advanced features like sticky headers or grid layouts

Code Comparison

MultiType:

class TextItemViewBinder : ItemViewBinder<String, TextItemViewBinder.Holder>() {
  override fun onCreateViewHolder(inflater: LayoutInflater, parent: ViewGroup): Holder {
    return Holder(inflater.inflate(R.layout.item_text, parent, false))
  }
  override fun onBindViewHolder(holder: Holder, item: String) {
    holder.text.text = item
  }
  class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val text: TextView = itemView.findViewById(R.id.text)
  }
}

RecyclerListView:

class TextViewHolder extends BaseViewHolder {
  constructor(view: View) {
    super(view);
    this.textView = view.findViewById(R.id.text);
  }
  bindData(data: any) {
    this.textView.setText(data);
  }
}

const dataProvider = new DataProvider((r1, r2) => r1 !== r2);
const layoutProvider = new LayoutProvider(
  index => 0,
  (type, dim) => {
    dim.width = width;
    dim.height = 40;
  }
);

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

RecyclerListView

npm version appveyor License

If this project has helped you out, please support us with a star :star2:.

This is a high performance listview for React Native and Web with support for complex layouts. JS only with no native dependencies, inspired by both RecyclerView on Android and UICollectionView on iOS.

npm install --save recyclerlistview

For latest beta:
npm install --save recyclerlistview@beta

Note: Documentation will be upgraded soon, for now check code comments for clarity and exploring features. This component is actively tested with React Native Web as well.

Overview and features

RecyclerListView uses "cell recycling" to reuse views that are no longer visible to render items instead of creating new view objects. Creation of objects is very expensive and comes with a memory overhead which means as you scroll through the list the memory footprint keeps going up. Releasing invisible items off memory is another technique but that leads to creation of even more objects and lot of garbage collections. Recycling is the best way to render infinite lists that does not compromise performance or memory efficiency.

Apart from all performance benefits RecyclerListView comes with great features out of the box:

  • Cross Platform, works on Web
  • Supports staggered grid layouts
  • Supports variable height items even if dimensions cannot be predetermined (prop - forceNonDeterministicRendering)
  • Instant layout switching like going from GridView to ListView and vice versa
  • End reach detections
  • Horizontal Mode
  • Viewability Events
  • Initial render offset/index support
  • Footer support
  • Reflow support on container size change with first visible item preservation
  • Scroll position preservation
  • Window scrolling support for web
  • (New) ItemAnimator interface added, customize to your will how RLV handles layout changes. Allows you to modify animations that move cells. You can do things like smoothly move an item to a new position when height of one of the cells has changed.
  • (New) Stable Id support, ability to associate a stable id with an item. Will enable beautiful add/remove animations and optimize re-renders when DataProvider is updated.
  • (New) Sticky recycler items that stick to either the top or bottom.

Why?

RecyclerListView was built with performance in mind which means no blanks while quick scrolls or frame drops. RecyclerListView encourages you to have deterministic heights for items you need to render. This does not mean that you need to have all items of same height and stuff, all you need is a way to look at the data and compute height upfront so that RecyclerListView can compute layout in one pass rather than waiting for the draw to happen. You can still do all sorts of GridViews and ListViews with different types of items which are all recycled in optimal ways. Type based recycling is very easy to do and comes out of the box.

In case you cannot determine heights of items in advance just set forceNonDeterministicRendering prop to true on RecyclerListView. Now, it will treat given dimensions as estimates and let items resize. Try to give good estimates to improve experience.

Demo

Production Flipkart Grocery Demo Video (or try the app): https://youtu.be/6YqEqP3MmoU
Infinite Loading/View Change (Expo): https://snack.expo.io/@naqvitalha/rlv-demo
Mixed ViewTypes: https://snack.expo.io/B1GYad52b
extendedState,stableIDs and ItemAnimator (Expo): https://snack.expo.io/@arunreddy10/19bb8e
Sample project: https://github.com/naqvitalha/travelMate
Web Sample (Using RNW): https://codesandbox.io/s/k54j2zx977, https://jolly-engelbart-8ff0d0.netlify.com/
Context Preservation Sample: https://github.com/naqvitalha/recyclerlistview-context-preservation-demo

Other Video: https://www.youtube.com/watch?v=Tnv4HMmPgMc

Watch Video

Props

PropRequiredParams TypeDescription
layoutProviderYesBaseLayoutProviderConstructor function that defines the layout (height / width) of each element
dataProviderYesDataProviderConstructor function the defines the data for each element
contextProviderNoContextProviderUsed to maintain scroll position in case view gets destroyed, which often happens with back navigation
rowRendererYes(type: string | number, data: any, index: number) => JSX.Element | JSX.Element[] | nullMethod that returns react component to be rendered. You get the type, data, index and extendedState of the view in the callback
initialOffsetNonumberInitial offset you want to start rendering from; This is very useful if you want to maintain scroll context across pages.
renderAheadOffsetNonumberspecify how many pixels in advance you want views to be rendered. Increasing this value can help reduce blanks (if any). However, keeping this as low as possible should be the intent. Higher values also increase re-render compute
isHorizontalNobooleanIf true, the list will operate horizontally rather than vertically
onScrollNorawEvent: ScrollEvent, offsetX: number, offsetY: number) => voidOn scroll callback function that executes as a user scrolls
onRecreateNo(params: OnRecreateParams) => voidcallback function that gets executed when recreating the recycler view from context provider
externalScrollViewNo{ new (props: ScrollViewDefaultProps): BaseScrollView }Use this to pass your on implementation of BaseScrollView
onEndReachedNo() => voidCallback function executed when the end of the view is hit (minus onEndThreshold if defined)
onEndReachedThresholdNonumberSpecify how many pixels in advance for the onEndReached callback
onEndReachedThresholdRelativeNonumberSpecify how far from the end (in units of visible length of the list) the bottom edge of the list must be from the end of the content to trigger the onEndReached callback
onVisibleIndicesChangedNoTOnItemStatusChangedProvides visible index; helpful in sending impression events
onVisibleIndexesChangedNoTOnItemStatusChanged(Deprecated in 2.0 beta) Provides visible index; helpful in sending impression events
renderFooterNo() => JSX.Element | JSX.Element[] | nullProvide this method if you want to render a footer. Helpful in showing a loader while doing incremental loads
initialRenderIndexNonumberSpecify the initial item index you want rendering to start from. Preferred over initialOffset if both specified
scrollThrottleNonumberiOS only; Scroll throttle duration
canChangeSizeNobooleanSpecify if size can change
distanceFromWindowNonumber(Depricated) Use applyWindowCorrection() API with windowShift. Usage?
applyWindowCorrectionNo(offset: number, windowCorrection: WindowCorrection) => void(Enhancement/replacement to distanceFromWindow API) Allows updation of the visible windowBounds to based on correctional values passed. User can specify windowShift; in case entire RecyclerListWindow needs to shift down/up, startCorrection; in case when top window bound needs to be shifted for e.x. top window bound to be shifted down is a content overlapping the top edge of RecyclerListView, endCorrection: to alter bottom window bound for a similar use-case. Usage?
useWindowScrollNobooleanWeb only; Layout Elements in window instead of a scrollable div
disableRecyclingNobooleanTurns off recycling
forceNonDeterministicRenderingNobooleanDefault is false; if enabled dimensions provided in layout provider will not be strictly enforced. Use this if item dimensions cannot be accurately determined
extendedStateNoobjectIn some cases the data passed at row level may not contain all the info that the item depends upon, you can keep all other info outside and pass it down via this prop. Changing this object will cause everything to re-render. Make sure you don't change it often to ensure performance. Re-renders are heavy.
itemAnimatorNoItemAnimatorEnables animating RecyclerListView item cells (shift, add, remove, etc)
styleNoobjectTo pass down style to inner ScrollView
scrollViewPropsNoobjectFor all props that need to be proxied to inner/external scrollview. Put them in an object and they'll be spread and passed down.
layoutSizeNoDimensionWill prevent the initial empty render required to compute the size of the listview and use these dimensions to render list items in the first render itself. This is useful for cases such as server side rendering. The prop canChangeSize has to be set to true if the size can be changed after rendering. Note that this is not the scroll view size and is used solely for layouting.
onItemLayoutNonumberA callback function that is executed when an item of the recyclerListView (at an index) has been layout. This can also be used as a proxy to itemsRendered kind of callbacks.
windowCorrectionConfigNoobjectUsed to specify is window correction config and whether it should be applied to some scroll events

For full feature set have a look at prop definitions of RecyclerListView (bottom of the file). All ScrollView features like RefreshControl also work out of the box.

applyWindowCorrection usage

applyWindowCorrection is used to alter the visible window bounds of the RecyclerListView dynamically. The windowCorrection of RecyclerListView along with the current scroll offset are exposed to the user. The windowCorrection object consists of 3 numeric values:

  • windowShift - Direct replacement of distanceFromWindow parameter. Window shift is the offset value by which the RecyclerListView as a whole is displaced within the StickyContainer, use this param to specify how far away the first list item is from window top. This value corrects the scroll offsets for StickyObjects as well as RecyclerListView.
  • startCorrection - startCorrection is used to specify the shift in the top visible window bound, with which user can receive the correct Sticky header instance even when an external factor like CoordinatorLayout toolbar.
  • endCorrection - endCorrection is used to specify the shift in the bottom visible window bound, with which user can receive correct Sticky Footer instance when an external factor like bottom app bar is changing the visible view bound.

As seen in the example below

Alt Text

Typescript

Typescript works out of the box. The only execption is with the inherited Scrollview props. In order for Typescript to work with inherited Scrollview props, you must place said inherited Scrollview props within the scrollViewProps prop.

<RecyclerListView
  rowRenderer={this.rowRenderer}
  dataProvider={queue}
  layoutProvider={this.layoutProvider}
  onScroll={this.checkRefetch}
  renderFooter={this.renderFooter}
  scrollViewProps={{
    refreshControl: (
      <RefreshControl
        refreshing={loading}
        onRefresh={async () => {
          this.setState({ loading: true });
          analytics.logEvent('Event_Stagg_pull_to_refresh');
          await refetchQueue();
          this.setState({ loading: false });
        }}
      />
    )
  }}
/>

Guides

  • Sample Code
  • Performance
  • Sticky Guide
  • Web Support: Works with React Native Web out of the box. For use with ReactJS start importing from recyclerlistview/web e.g., import { RecyclerListView } from "recyclerlistview/web". Use aliases if you want to preserve import path. Only platform specific code is part of the build so, no unnecessary code will ship with your app.
  • Polyfills Needed: requestAnimationFrame, ResizeObserver

License

Apache v2.0

Contact Us

Please open issues for any bugs that you encounter. You can reach out to me on twitter @naqvitalha or, write to cross-platform@flipkart.com for any questions that you might have.

NPM DownloadsLast 30 Days