Giter Site home page Giter Site logo

brh55 / react-native-masonry Goto Github PK

View Code? Open in Web Editor NEW
1.3K 14.0 158.0 1.44 MB

:raised_hands: A pure JS react-native component to render a masonry~ish layout for images with support for dynamic columns, progressive image loading, device rotation, on-press handlers, and headers/captions.

License: MIT License

JavaScript 78.92% Python 4.82% Java 3.93% Objective-C 12.33%
react-native masonry-layout masonry-grid react pinterest-like masonry pinterest

react-native-masonry's Introduction

react-native-masonry

Travis David npm Expo Demo

๐Ÿ™Œ An easy to use, pure JS react-native component to render a masonry~ish layout for remote images

react-native-masonry is built with the following features and functionalities baked in ๐Ÿฐ:

  • Dynamic Column Rendering
  • Progressive Item Loading
  • Device Rotation
  • On-press Handlers
  • Custom Headers & Captions
  • Optimized to Rendering Large List
  • Support for Third-Party Image components
  • Automatic Sizing Based on Available Space

v0.1.0 Demo

Usage

  1. Install the repository
    $ npm install --save react-native-masonry
  2. Add an import to the top of your file
    import Masonry from 'react-native-masonry';
  3. At a minimal, declare the component in the render method prividing data for bricks
    <Masonry
      sorted // optional - Default: false
      columns={4} // optional - Default: 2
      bricks={[
        { uri: 'http://image1.jpg' },
        { uri: 'http://image2.jpg' },
        { uri: 'http://image3.jpg' }
      ]}
    />
  4. Still a bit confused ๐Ÿ˜–, or want to see it in action? No worries, run the example application on your local machine to examine how to get started or try it out on Expo.io.

Component Props

Props Type Description Default
bricks array A list of Object:Bricks to be passed into the row renderer. I.E:,bricks=[{id: 1, uri: 'https://image.jpg', onPress: (brick) => this.redirect(brick.id)}, {id: 2, uri: 'https://hyper.jpg'}] []
columns num Desired number of columns 2
sorted bool Whether to sort bricks according to their index position or allow bricks to fill in as soon as the uri is ready. false
imageContainerStyle object The styles object which is added to the Image component {}
customImageComponent React.Component Use a custom component to be rendered for the Image. This will work properly, as long as the component follows the standard interface of the react-native image component. n/a
customImageProps object Pass along additional properties to a props.customImageComponent. n/a
spacing num Gutter size of the column. The spacing is a multiplier of 1% of the available view. 1
refreshControl React.Component A component to be used as a refresh element for the Masonry component n/a

Brick Properties

"Bricks" are the basic building block of the masonry and are passed into the props.bricks. They essentially represent the items within each column and require a uri property at a minimum. However, you can freely add additional properties to the data property if you need access to certain data within your brick.onPress handler and footer/header renderer. The following properties are available.

Property Type Required Description Example
uri string โœ… The uri of the image location. http://test.com/i.jpeg
key string ๐Ÿšซ Optional item key. By default, uri is used as the key for each item. It's recommended to set a unique key here, but it is not required. The key is required if you need to have image with the same uri more than once in your list. image01
onPress func (brick.data) ๐Ÿšซ A function handler when the brick is pressed. The function will be called with the instance of the brick, which provides it's dimensions, columns, as well as any user defined properties passed into the bricks prop. An image will be wrapped by a TouchableHighlight. onPress: (data) => goTo(data.id)
renderHeader func (brick.data) ๐Ÿšซ A function that is executed ABOVE the brick image, this function must return a React Component. renderHeader() is passed brick.data to allow dynamic content rendering of components. Figure 1
renderFooter func (brick.data) ๐Ÿšซ A function that is executed BELOW the brick image renderFooter() is passed brick.data to allow dynamic content rendering of components. Figure 2

Usage Examples

โ„น๏ธ Figure 1: Brick with renderHeader

Accomplishing a top bar indicating the user's avatar and name

{
  // User defined data
  data: {
    user: {
        name: 'Henry',
        profilePic: 'https://user.jpeg'
    }
  }
  uri: 'https://example.com/mainImage.jpeg',
  renderHeader: (data) => {
    return (
      <View>
          <Image source={{ uri: data.user.profilePic }} style={{ width: 50, height: 50}}>
          <Text>{data.user.name}</Text>
      </View>
    );
  }
}

โ„น๏ธ Figure 2: Brick with .renderFooter

Creating a bottom bar to include additional metadata

{
  data: {
    caption: 'Summer Recipies'
  },
  uri: 'https://example.com/mainImage.jpeg',
  renderFooter: (data) => {
    return (
        <View>
            <Text>{data.caption}</Text>
        </View>
    );
  }
}

โ„น๏ธ Figure 3: Using Third-Party Image Components

How to leverage third-party components like <FastImage> and apply unique properties across all images

import FastImage from 'react-native-fast-image';

const fastProps = {
    onProgress: { e => console.log(e.nativeEvent.loaded / e.nativeEvent.total) },
    resizeMode: FastImage.resizeMode.contain
};

// ... Where Masonry is called
<Masonry
    bricks={data}
    customImageComponent={FastImage}
    customImageProps={fastProps} />

Contribute

๐Ÿ‘ท๐Ÿฝ๐Ÿ‘ท๐Ÿปโ€โ™€๏ธ๐Ÿ•

Pull requests are welcomed, just abide by rules listed within contributing.json.

Beginners

Not sure where to start, or a beginner? Take a look at the issues page for low-hanging or beginner-friendly labels as an easy ways to start contributing.

Contributors

Thank you to all the people who have already contributed to react-native-masonry!

License

MIT ยฉ Brandon Him

react-native-masonry's People

Contributors

asood123 avatar brh55 avatar dependabot[bot] avatar hisener avatar jerolimov avatar kmcgill88 avatar lautarocelerative avatar maboelsoud avatar miduga avatar phuchuynhstrong avatar soukupl avatar srameshr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-masonry's Issues

Add key to column rendering

To provide a stable identity within the columns by default bricks should have id's associated with them, use the URI as a last resort key for each entry.

Spec:

  • Add an id for each "brick"

When i refesh but it not show view

When I run react-native run-android view show colum left and right .but when i click R +R refesh It just show view column Left or column right not show together

All images are not rendered at once.

Number of columns is 2, only one side of the images are rendered sometimes, re-rendering the component fixes the issue for some while, please provide a better solution.

Some images are not showing in Android.

I ran iPhone on simulator, It is well like this.

2018-01-05 1 56 05

But when i ran android device, It is not working like this.

kakaotalk_2018-01-05-14-00-45_photo_5

My Spec.

{
  "main": "node_modules/expo/AppEntry.js",
  "private": true,
  "scripts": {
    "test": "node ./node_modules/jest/bin/jest.js --watch"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@expo/samples": "2.1.1",
    "expo": "^24.0.0",
    "react": "16.0.0",
    "react-native": "https://github.com/expo/react-native/archive/sdk-24.0.0.tar.gz",
    "react-native-masonry": "^0.4.4",
    "react-navigation": "^1.0.0-beta.21"
  },
  "devDependencies": {
    "jest-expo": "^24.0.0"
  }
}

Entire code.

import React from 'react';
import {
    ActivityIndicator,
    Image,
    Platform,
    ScrollView,
    StyleSheet,
    Text,
    TouchableOpacity,
    TextInput,
    View,
} from 'react-native';
import {Ionicons} from '@expo/vector-icons';
import Masonry from 'react-native-masonry';
import {scale, moderateScale, verticalScale} from '../utils/scaling';

export default class HomeScreen extends React.Component {
    static navigationOptions = {
        header: null
    };

    render() {
        return (
            <View style={styles.container}>
                <View style={styles.header}>
                    <View style={styles.headSearch}>
                        <TextInput
                            style={styles.searchTextInput}
                            placeholder="๊ฒ€์ƒ‰"
                            placeholderTextColor="#C2C2C2"
                            underlineColorAndroid='transparent'
                        />
                        <Ionicons style={styles.searchIcon} name="md-search" size={20} color="#C2C2C2"/>
                    </View>
                    <View style={styles.headFilter}>
                        <Image style={styles.filterIcon} source={require('../assets/images/ic_filter.png')}/>
                    </View>
                </View>
                <View style={styles.listWrap}>
                    <Masonry
                        sorted // optional - Default: false
                        columns={2} // optional - Default: 2
                        spacing={2}
                        imageContainerStyle={
                            {borderRadius: 5}
                        }
                        bricks={[
                            {
                                data: {
                                    user: {
                                        name: "mss"
                                    },
                                    content: {
                                        title: '์ œ๋ชฉ์ œ๋ชฉ์ œ๋ชฉ',
                                        subtitle: '์„œ๋ธŒ ํƒ€์ดํ‹€ ์„œ๋ธŒ ํƒ€์ดํ‹€ํ‹€',
                                        distance: 1
                                    }
                                },
                                uri: 'https://s3.ap-northeast-2.amazonaws.com/contents-images/%EB%B0%A9%EC%BD%95%EC%9D%B5%EC%8A%A4%ED%94%84%EB%A0%88%EC%8A%A4+%EC%8B%A0%EC%B4%8C2%ED%98%B8%EC%A0%90+(2).jpg',
                                renderFooter: (data) => {
                                    return (
                                        <View style={styles.card}>
                                            <View style={styles.cardTextTop}>
                                                <Text style={styles.subject}>
                                                    {data.content.title}
                                                </Text>
                                                <Text style={styles.distance}>
                                                    {data.content.distance}km
                                                </Text>
                                            </View>
                                            <View style={styles.cardTextBottom}>
                                                <Text style={styles.subtitle}>
                                                    {data.content.subtitle}
                                                </Text>
                                            </View>
                                        </View>
                                    );
                                }
                            },
                            {
                                data: {
                                    user: {
                                        name: "mss"
                                    },
                                    content: {
                                        title: '์ œ๋ชฉ์ œ๋ชฉ์ œ๋ชฉ',
                                        subtitle: '์„œ๋ธŒ ํƒ€์ดํ‹€ ์„œ๋ธŒ ํƒ€์ดํ‹€ํ‹€',
                                        distance: 1
                                    }
                                },
                                uri: 'https://s3.ap-northeast-2.amazonaws.com/contents-images/%EC%8A%A4%ED%83%80%ED%95%84%EB%93%9C+%ED%95%98%EB%82%A8+(1).png',
                                renderFooter: (data) => {
                                    return (
                                        <View style={styles.card}>
                                            <View style={styles.cardTextTop}>
                                                <Text style={styles.subject}>
                                                    {data.content.title}
                                                </Text>
                                                <Text style={styles.distance}>
                                                    {data.content.distance}km
                                                </Text>
                                            </View>
                                            <View style={styles.cardTextBottom}>
                                                <Text style={styles.subtitle}>
                                                    {data.content.subtitle}
                                                </Text>
                                            </View>
                                        </View>
                                    );
                                }
                            },
                            {
                                data: {
                                    user: {
                                        name: "mss"
                                    },
                                    content: {
                                        title: '์ œ๋ชฉ์ œ๋ชฉ์ œ๋ชฉ',
                                        subtitle: '์„œ๋ธŒ ํƒ€์ดํ‹€ ์„œ๋ธŒ ํƒ€์ดํ‹€ํ‹€',
                                        distance: 1
                                    }
                                },
                                uri: 'http://img.wemep.co.kr/deal/4/261/2102614/dafe87235fb7c30194745e2d70792dae89b24925.jpg',
                                renderFooter: (data) => {
                                    return (
                                        <View style={styles.card}>
                                            <View style={styles.cardTextTop}>
                                                <Text style={styles.subject}>
                                                    {data.content.title}
                                                </Text>
                                                <Text style={styles.distance}>
                                                    {data.content.distance}km
                                                </Text>
                                            </View>
                                            <View style={styles.cardTextBottom}>
                                                <Text style={styles.subtitle}>
                                                    {data.content.subtitle}
                                                </Text>
                                            </View>
                                        </View>
                                    );
                                }
                            },
                            {
                                data: {
                                    user: {
                                        name: "mss"
                                    },
                                    content: {
                                        title: '์ œ๋ชฉ์ œ๋ชฉ์ œ๋ชฉ',
                                        subtitle: '์„œ๋ธŒ ํƒ€์ดํ‹€ ์„œ๋ธŒ ํƒ€์ดํ‹€ํ‹€',
                                        distance: 1
                                    }
                                },
                                uri: 'http://dimg.donga.com/wps/NEWS/IMAGE/2012/04/16/45563305.4.jpg',
                                renderFooter: (data) => {
                                    return (
                                        <View style={styles.card}>
                                            <View style={styles.cardTextTop}>
                                                <Text style={styles.subject}>
                                                    {data.content.title}
                                                </Text>
                                                <Text style={styles.distance}>
                                                    {data.content.distance}km
                                                </Text>
                                            </View>
                                            <View style={styles.cardTextBottom}>
                                                <Text style={styles.subtitle}>
                                                    {data.content.subtitle}
                                                </Text>
                                            </View>
                                        </View>
                                    );
                                }
                            }
                        ]}
                    />
                </View>
            </View>
        );
    }

    // _handleLearnMorePress = () => {
    //   WebBrowser.openBrowserAsync('https://docs.expo.io/versions/latest/guides/development-mode');
    // };
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    },
    listWrap: {
        flex: 1,
        padding: 10
    },


    header: {
        paddingTop: Platform.OS === 'ios' ? 26 : 5,
        paddingLeft: 10,
        paddingRight: 10,
        flexDirection: 'row'
    },
    headSearch: {
        flex: 1
    },
    searchIcon: {
        position: 'absolute',
        left: 24,
        top: 12,
        backgroundColor: 'transparent'
    },
    searchTextInput: {
        backgroundColor: '#F4F4F4',
        paddingLeft: 44,
        borderRadius: 45,
        height: 43,
        borderWidth: 0,
        borderBottomWidth: 0,
        borderColor: '#F4F4F4',
    },
    headFilter: {
        marginLeft: 10,
        paddingTop: 6,
        height: 43
    },
    filterIcon: {
        width: 30,
        height: 27,
    },


    card: {
        paddingTop: scale(6),
        paddingBottom: scale(15),
        paddingLeft: scale(4),
        paddingRight: scale(4)
    },
    cardImage: {
        borderRadius: 5
    },
    cardTextTop: {
        flexDirection: 'row',
        justifyContent: 'center',
        alignContent: 'center'
    },
    subject: {
        flex: 1, fontSize: moderateScale(12)
    },
    distance: {
        fontSize: moderateScale(10), fontWeight: 'bold', color: '#500606'
    },
    cardTextBottom: {
        marginTop: scale(1)
    },
    subtitle: {
        color: '#616161', fontSize: moderateScale(11), fontWeight: '100'
    }
});

Please help..

Can this render video?

i wanted to load videos form server and was wondering if the layout would be able to handle it?

0.4.0 breaks when onPress is attached

Error: Touchable child must either be native or forward setNativeProps to a native component
    at invariant (index.ios.bundle?platform=ios&dev=true&minify=false:1672)
    at ensureComponentIsNative (index.ios.bundle?platform=ios&dev=true&minify=false:45144)
    at Object.componentDidUpdate (index.ios.bundle?platform=ios&dev=true&minify=false:45006)
    at measureLifeCyclePerf (index.ios.bundle?platform=ios&dev=true&minify=false:21786)
    at index.ios.bundle?platform=ios&dev=true&minify=false:21989
    at CallbackQueue.notifyAll (index.ios.bundle?platform=ios&dev=true&minify=false:22299)
    at ReactNativeReconcileTransaction.close (index.ios.bundle?platform=ios&dev=true&minify=false:22318)
    at ReactNativeReconcileTransaction.closeAll (index.ios.bundle?platform=ios&dev=true&minify=false:21590)
    at ReactNativeReconcileTransaction.perform (index.ios.bundle?platform=ios&dev=true&minify=false:21564)
    at ReactUpdatesFlushTransaction.perform (index.ios.bundle?platform=ios&dev=true&minify=false:21559)
index.ios.bundle?platform=ios&dev=true&minify=false:12993 Unhandled JS Exception: Touchable child must either be native or forward setNativeProps to a native component
reactConsoleErrorHandler @ index.ios.bundle?platform=ios&dev=true&minify=false:12993
console.error @ index.ios.bundle?platform=ios&dev=true&minify=false:46242
logToConsole @ index.ios.bundle?platform=ios&dev=true&minify=false:16707
logIfNoNativeHook @ index.ios.bundle?platform=ios&dev=true&minify=false:16690
__callFunction @ index.ios.bundle?platform=ios&dev=true&minify=false:4863
(anonymous) @ index.ios.bundle?platform=ios&dev=true&minify=false:4700
__guard @ index.ios.bundle?platform=ios&dev=true&minify=false:4834
callFunctionReturnFlushedQueue @ index.ios.bundle?platform=ios&dev=true&minify=false:4699
(anonymous) @ debuggerWorker.js:72
2index.ios.bundle?platform=ios&dev=true&minify=false:12985 Touchable child must either be native or forward setNativeProps to a native component

This is in version 0.4.0

Here is my component code:

<Masonry
          bricks={[
            uri: 'some-image-url',
            onPress: () => this.props.navigator.push({ screen: 'myScreen' }), // It breaks if I add this onPress
          ]}
          columns={2}
          sorted
          imageContainerStyle={{ }}
        />

It worked fine on 0.3.0

Add props to define priority arrangement

An API could look something like such:

props.priority or props.arrangement:

  • order / ascending - Default: Placement occurs in sequence (1, 2, 3)
  • vertical - Looks at which column has the least vertical height, and position "brick" within that column
  • reverse / descending - reverse placement in column (3, 2, 1)

Re-add support for local images

Looks like I may have missed it during development of v0.1.0.

Reproduction Instructions:

  • Set Props.bricks = [LocalImages (require('../asset/etc')]
  • Images won't load

Validate:

  • When passed in a local image, it should appear in the columns

The order in which images are rendered is not ordered

Here is the screenshot: https://ibb.co/eEVsFF

const data = [
  {
    id: 3,
    uri: 'https://image.shutterstock.com/z/stock-photo-collage-of-happy-family-resting-at-home-103862393.jpg'
  },
  {
    id: 1,
    uri: 'https://s-media-cache-ak0.pinimg.com/736x/01/c0/1c/01c01c45cb997f16675c5a5825645ceb.jpg'
  },
  {
    id: 2,
    uri: 'https://i.ytimg.com/vi/tYBk4kLHPkk/maxresdefault.jpg'
  },

];

If this is the data, images are rendered in a single column.

Also the images are not ordered according to the array of data source.

Layout Issues When Dynamically Adding Data

As @srameshr pointed out, there is issues when the data is added.

This probably has to do with masonry.js willReceiveNextProps and how masonry does some internal caching to prevent re-resolving bricks. Will need to investigate and figure out what the issue is.

Increase space between Bricks

Hi,
Is there any way to increase space around bricks i.e space between/around each bricks.

masonry column = 2
I tried by changing column.js file
const gutterBase = width / 100;
const gutterSize = gutterBase * 5;

it creates gap between 2 column but the image inside the column is not shown fully.
---Help Wanted.

Migrate to FlatList

As title explains, I will try to get to this when I have time (3 - 4 weeks), but open for grabs as well.

Change child "Row" component to "Column"

As it stands, it doesn't make much sense to call it a "row", when it's actually representing a "column".

Specs:

  • Rename <Row/> to <Column/>

Validation:

  • Search for Row, no matches should be found

Provide lazily load images

Currently, the main caveat of this implementation is fetching the dimensions and passing it to the component. This requires all images to be defined before passing into Row, making it only as efficient as N images.

Specs:

  • Update the row in sequence as the images arrive, if the image in sequence aren't fetched yet, let's pause and do a batch update until it is ready.

Verification:

  • The column shall simultaneously update as images come.

passing image dimensions internally

Lets say we are fetching 100 images. and then let us say i have the data for those image dimensions (ill be creating an API that exposes the image dimensions, that would be much faster than downloading the image and then examining the dimensions once fully downloaded). is there any way i can pass those image dimensions internally so that this module will load faster? (please correct my understanding that this module will just render all the images provided they have been downloaded and cached only)

[VirtualizedList] - Warning: Each child in an array or iterator should have a unique "key" prop.

Hello,
there is a warning in render method of VirtualizedList. Not sure if this is your problem... I wasn't able to find it in code yet. It may be a problem of one of the dependencies... Can you please look at it?
It's only a warning, but still... :)

`
Warning: Each child in an array or iterator should have a unique "key" prop.

Check the render method of VirtualizedList. See https://fb.me/react-warning-keys for more information.
in CellRenderer (at VirtualizedList.js:463)
in VirtualizedList (at FlatList.js:557)
in FlatList (at Column.js:129)
in RCTView (at View.js:113)
in View (at Column.js:121)
in Column (at Masonry.js:118)
in StaticRenderer (at ListView.js:464)
in RCTScrollContentView (at ScrollView.js:707)
in RCTScrollView (at ScrollView.js:800)
in ScrollView (at ListView.js:332)
in ListView (at Masonry.js:113)
in RCTView (at View.js:113)
in View (at Masonry.js:112)
in Masonry (at PageGallery.js:13)
in PageGallery (at App.js:203)
in RCTScrollContentView (at ScrollView.js:707)
in RCTScrollView (at ScrollView.js:800)
in ScrollView (at KeyboardAwareScrollView.js:27)
in KeyboardAwareScrollView (at Content.js:10)
in Content (at connectStyle.js:384)
in Styled(Content) (at App.js:302)
in RCTView (at View.js:113)
in View (at Container.js:19)
in Container (at connectStyle.js:384)
in Styled(Container) (at App.js:252)
in RCTView (at View.js:113)
in View (at index.js:570)
in RCTView (at View.js:113)
in View (at index.js:557)
in Drawer (at index.js:10)
in Drawer (at App.js:234)
in RCTView (at View.js:113)
in View (at Root.js:14)
in Root (at connectStyle.js:384)
in Styled(Root) (at App.js:233)
in App (at registerRootComponent.js:36)
in RootErrorBoundary (at registerRootComponent.js:35)
in ExpoRootComponent (at renderApplication.js:35)
in RCTView (at View.js:113)
in View (at AppContainer.js:100)
in RCTView (at View.js:113)
in View (at AppContainer.js:121)
in AppContainer (at renderApplication.js:34)
`

Image rendering is broken

Hi,

I tried 0.4.4 release, but noticed that the rendering is still broken. I am loading my images via the internet (not local images). Could this be the reason?

image

Images rendered have a bias on the left side

Expected Behavior

I expect Masonry to balance the images loaded on the screen. Balance means equal height on all columns.

Current Behavior

For every Masonry component rendered, I observed a bias toward the first column. It tends to load most of the images on the left side/1st column.

Possible Solution

Maybe do some calculation for final rendering to balance the images so that it does not gravitate toward any specific column

Steps to Reproduce

image
image
image

Context (Environment)

Detailed Description

Possible Implementation

How do I set space between columns?

<Masonry
                            sorted // optional - Default: false
                            columns={2} // optional - Default: 2
                            imageContainerStyle={
                                {borderRadius:5}
                            }
                            bricks={[uri: ....]}
</Masonry>

It's correct. Thank you for good component.

But, I would like to set space between left column and right column.

Is it possible?

Replace _ _ with _ for "private" functions

Out of pure habit -- too much BEM --, "private" functions within components are using double _ (underscores). However, based on typical javascript convention, replace with single _.

Spec:

  • Replace __ with _ for "private" func/var

Validation:

  • Should not be any more __ prepended to a "private" func/var

Render the content header, footer and placeholder before the actual image renders

Love react-native-masonry? Please consider supporting our collective:
๐Ÿ‘‰ https://opencollective.com/react-native-masonry/donate โค๏ธ

There is a considerable delay between Masonry being called and the actual content being rendered.
This occurs even on most light weight data, such as 20 masonry images with each being no more than 200kb and in spite of using FastImage.
Hence, corresponding feature request would be to have a fixed height (before rendering or take image dimensions as props) for each element and show an ActivityInidicator or any placeholder.

Add coveralls

Spec:

  • Integrate coveralls within repository
  • Include coveralls badge on the readme

Validation:

  • Coveralls badge should be populated with code coverage %
  • Coveralls page should be available

Column widths not updated after rotation

To reproduce:

  1. Start app and rotate from portrait to landscape
  2. one column will not be updated while in landscape
  3. Rotate back to portrait and things are fine.

If you are in landscape and toggle a different column size and toggle back to the original size of 2 and continue to rotate things appear to be fine.

I need this functionality and will work on it.

simulator screen shot sep 3 2017 9 14 55 pm
simulator screen shot sep 3 2017 9 06 39 pm

Add dynamic parent view / parent view styled-container

Currently react-native-masonry is under the assumption that the view isn't going to be constrained by padding around it's component main view. However, any padding will result in incorrect calculations of image dimensions. To fix this, dynamically pass the parents available dimensions to the columns to use as a base measurement.

Validate:

  • Add padding around Masonry component
  • It should render properly

Adding onPress support for header and footer

Hi, thanks for the awesome component!

I am working on a project and I want to be able to press on footer as well, but when I add onPress to the footer doesn't work for some reason, can you please help?

Bug fix

BUG:

  • rowHasChanged(r1, r2) -- r1 and r2 are equal despite clones from previous state
  • if we can determine why the row changes are inputting equivalent parameters, we can utilize an equal check against URIs to prevent unnecessary ListView re-renders.

Reproduce:

  • Insert a 4+ bricks with remote URIs
  • Log R1, R2 within the rowHasChanged function, r1 === r2 // True

Validate

  • r1 === r2 // False when state changes from image resolves.

Update example gif in readme

The new example contains some new features. It would be great to update this example with a new gif recording.

Steps:

  1. Run example gif
  2. Record Gif (recommend using record.it)
    • Ensure gif shows column changing, and pushing new data ๐Ÿ‘

Fix resolveBrick() to this.resolveBricks()

Reproduction steps:

  • Pass in images props.bricks, later after Masonry is already mounted
  • Masonry will issue a warning that resolveBricks is not found, this is because resolveBricks is a method within Masonry.

Add TouchableHighlight Support

  • If user provides a props.onPress, the image should invoke the props onPress function with the object in the data array

Performance Issue

I read the code and found the row of ListView is just used as masonry column.
If there are three column on your masonry there will be only three rows in the ListView.
The ListView or ScrollView will remove the views of images out of vision and keep the memory low.
But here it has only limited rows of columns.
As the image number grows your column view will become bigger and bigger and at last it will crash the whole app.

The layout is broken -- kind of

Here is a screenshot:

screen shot 2017-09-07 at 10 48 56 pm

Sometimes the columns are a miss
screen shot 2017-09-07 at 11 58 41 pm

These quirk happen sometimes on navigation. When I navigate to and fro to this page.

In the below image, data is ordered as 5,4,3,2,1. But the list renders them as below.
screen shot 2017-09-08 at 12 08 13 am

<ScrollView style={{ flex: 1, padding: 5 }}>
        <Masonry
          bricks={this.state.contents}
          columns={2}
        />
      </ScrollView>
    );

Add gutterSize props

Allow for adjustment of the gutter size of the columns.

Specs:

  • By specifying masonry.props.gutterSize, it should alter the spacing between the columns

Validation Steps:

  • Add a significant gutterSize
  • Columns should re-render with large spacing

Add renderHeader and renderFooter

This allows users to add captions and style around the image itself. Currently working in branch render-header-footer, expecting to release sometime next week after proper testing is in place.

Header and Footer not rendering

Great library! The demo shots in README show a header and footer for one, which I'm interested in. I started playing with it and realized the header and footer are not being rendered. I ran it locally as well as tried the Expo demo. I am a RN n00b but will see if I can't figure it out. The only warning I saw so far was:
screen shot 2017-09-01 at 5 21 13 pm

Any ideas?

Load image not show

When the first load screen, masonry load image for two column.
But the second and the 3th, masonry load image for left column or right colum

0-sa-d2-75dad76b98f466399a91fc9d7411d81a
0-sa-d3-35c05dd610a524aa08d0e22ee11b9b36

Simplified example renders nothing

I have a suspicion you are assuming existence of the header/footer as your example builds/runs but when I try my simplified code I get nothing rendered.


const onPress = e => console.log(e);
const img1 = 'https://img.buzzfeed.com/buzzfeed-static/static/2014-12/1/15/enhanced/webdr02/enhanced-18393-1417466529-5.jpg';
const img2 = 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSXXTmdaGSOFK8iBeYqoA6_XiQGGWvu6KGnqAxXYyvJA-JKin8ImQ';
const img3 = 'https://img.buzzfeed.com/buzzfeed-static/static/2015-04/3/15/enhanced/webdr06/enhanced-24427-1428089292-2.jpg';

// And tried with flex: 1, I know container is coming up on UI, but no images. 
...render

      <View style={{height: '100%'}}>
        <Masonry
          columns={3}
          bricks={[
            { uri: img1, id: 1, onPress },
            { uri: img2, id: 2, onPress },
            { uri: img3 , id: 3, onPress}
          ]}
          />
      </View>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.