@cawfree/react-native-masonry
v1.0.3 masonry layout react-native react native stippled view pintrest brick and 1 more...
react-native-masonry
A bare-bones masonry layout for react-native.
🚀 Getting Started
You can integrate with your project using npm:
npm install --save @cawfree/react-native-masonry
Alternatively, you can use yarn:
yarn add @cawfree/react-native-masonry
✏️ Example
In this example, we animate an infinite number of red boxes... but in your application, you can place and animate whatever and however you want. :)
import React from 'react';
import {
Animated,
View,
StyleSheet,
ScrollView,
} from 'react-native';
import PropTypes from 'prop-types';
import Masonry from '@cawfree/react-native-masonry';
const styles = StyleSheet.create({
masonry: {
flex: 1,
backgroundColor: 'blue',
},
});
export default class App extends React.Component {
constructor(nextProps) {
super(nextProps);
this.state = ({
fetching: false,
// XXX: Initialize the layout with some values.
items: [
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
],
});
this.__renderItem = this.__renderItem.bind(this);
this.__onScroll = this.__onScroll.bind(this);
this.__onItemPlaced = this.__onItemPlaced.bind(this);
}
// XXX: Render anything you want!
__renderItem(item) {
const height = (item.key * 500) + 100;
const {
opacity,
} = item;
return (
<Animated.View
style={{
flex: 1,
borderWidth: 1,
height,
backgroundColor: 'red',
opacity,
}}
/>
);
}
// XXX: Callback from Masonry when a brick has been placed.
__onItemPlaced(item) {
const {
opacity,
} = item;
Animated.timing(
opacity,
{
toValue: 1,
duration: 1000,
useNativeDriver: true,
},
)
.start();
}
__onScroll(e) {
const {
layoutMeasurement,
contentOffset,
contentSize,
} = e.nativeEvent;
const {
onEndReachedThreshold,
} = this.props;
const {
fetching,
} = this.state;
const thresholdIsReached = (layoutMeasurement.height + contentOffset.y) >= (contentSize.height - onEndReachedThreshold);
if (thresholdIsReached && !fetching) {
this.setState({
// XXX: Add some more items to the list!
items: ([
...this.state.items,
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
{ key: `${Math.random()}`, opacity: new Animated.Value(0) },
]),
});
}
}
render() {
const {
items,
} = this.state;
return (
<Masonry
style={styles.masonry}
items={items}
renderItem={this.__renderItem}
onItemPlaced={this.__onItemPlaced}
ScrollComponent={ScrollView}
useNativeDriver
scrollEventThrottle={400}
onScroll={this.__onScroll}
/>
);
}
}
✌️ License
npm i @cawfree/react-native-masonry
Metadata
- MIT
- Whatever
- Alex Thomas
- released 5/15/2019