Skip to main content

RecyclableList

High performance list view designed to work with high amount of items. RecyclableList reusing views that are no longer visible to render items instead of creating new view object.

Usage

import * as React from 'react';
import { Dimensions } from 'react-native';
import {
App,
Screen,
Image,
Text,
Pressable,
RecyclableList,
RecyclableListDataProvider,
RecyclableListLayoutProvider,
StyleSheet,
} from '@flexn/create';

const MARGIN_GUTTER = 20;
const ITEMS_IN_VIEWPORT = 3;

const { width } = Dimensions.get('window');

const dimensions = {
layout: { width: width / ITEMS_IN_VIEWPORT, height: 270 },
item: { width: width / ITEMS_IN_VIEWPORT - MARGIN_GUTTER, height: 250 },
};

function generateData(items = 50) {
const data: { backgroundImage: string, title: string }[] = [];
for (let index = 0; index < items; index++) {
data.push({
backgroundImage: `https://placekitten.com/${dimensions.item.width}/${dimensions.item.height + index}`,
title: 'Kitten name',
});
}

return data;
}

const MyComponent = () => {
const [dataProvider] = React.useState(
new RecyclableListDataProvider((r1, r2) => r1 !== r2).cloneWithRows(generateData())
);

const layoutProvider = React.useRef(
new RecyclableListLayoutProvider(
() => '_',
(_: string | number, dim: { width: number, height: number }) => {
dim.width = dimensions.layout.width;
dim.height = dimensions.layout.height;
}
)
).current;

return (
<App>
<Screen style={styles.recyclerContainer}>
<RecyclableList
dataProvider={dataProvider}
layoutProvider={layoutProvider}
rowRenderer={(_type: string | number, data: any, index: number, repeatContext: any) => {
return (
<Pressable
style={[
styles.recyclerItem,
{
width: dimensions.item.width,
height: dimensions.item.height,
},
]}
repeatContext={repeatContext}
onPress={() => {
console.log('Pressed!');
}}
>
<Image
source={{ uri: data.backgroundImage }}
style={{ width: '100%', height: '80%' }}
/>
<Text style={styles.recyclerItemText} numberOfLines={1}>
{data.title}
</Text>
</Pressable>
);
}}
horizontal
isHorizontal
style={styles.recycler}
scrollViewProps={{
showsHorizontalScrollIndicator: false,
}}
/>
</Screen>
</App>
);
};

const styles = StyleSheet.create({
recyclerContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
recycler: {
width: '100%',
height: 270,
},
recyclerItem: {
margin: 5,
justifyContent: 'flex-end',
alignItems: 'center',
},
recyclerItemText: {
color: '#000000',
fontSize: 14,
},
});

export default MyComponent;

Props

Since as core of RecyclableList Flexn Create using open source library, full API reference can be found at https://github.com/Flipkart/recyclerlistview#props. However this version is optimized to work with multiplatform environment and our Focus Manager so it has some API changes which is described below.

rowRenderer

Required

Type: (type: string | number, data: any, index: number, repeatContext: any) => JSX.Element | JSX.Element[] | null

Method which returns component to be rendered. It's important to note that repeatContext(last parameter of the function) always must be passed down to Pressable or TouchableOpacity component in your return.

<RecyclableList
rowRenderer={(_type: string | number, data: any, index: number, repeatContext: any) => {
return <TouchableOpacity repeatContext={repeatContext} />;
}}}
/>

focusOptions

Android TV Fire TV Apple TV

Type: RecyclerFocusOptions

Property which holds following related properties:

forbiddenFocusDirections

Type: ForbiddenFocusDirections[]

Can contain one or more directions. When RecyclableList has focus and direction is set an example to down then RecyclableList will never lose focus despite the fact we're pressing down button on our remote.