galgo
galgo

Reputation: 764

React-native image with animated background as loader

I have a flatlist, that renders amongst other things, images with overlay.

I created an animated background that changes color as the image loads (works fine). But I am struggling to make the background disappear once the image is loaded. I tried with onLoad but setting a this.state applies to all images in the list. Also it would be better if the image is hidden until it is loaded. I prefer lazy loading live instead of prefetching them in ComponentWillMount.

Any ideas?

<Image
    source={{uri: image}}
    style={styles.cardImg}
    onLoad={() => this.state.imageLoaded = true}
/>
{!this.state.imageLoaded && (
    <Animated.View
        style={[styles.cardBg, {
            backgroundColor: this._animatedValue.interpolate({
                inputRange: [0, 100],
                outputRange: ['rgba(100,100,100, 0.3)', 'rgba(100,100,100,0.5)']
            })
        }]}
    />
)}

UPDATE

<FlatList
          ref={(ref) => { this.FlatList = ref; }}
          data={this.props.data}
          keyExtractor={(item) => item._id}
          renderItem={this._renderCard.bind(this)}
          onEndThreshold={50}
          onEndReached={this.props.loadMore}
          ListFooterComponent={this._renderFooter}
          showsVerticalScrollIndicator={false}
          style={styles.list}
          extraData={this.state}
          refreshControl={<RefreshControl
                    refreshing={this.props.loading}
                    onRefresh={this.props.onRefresh}
                />}
        />

UPDATE 2

Ideally I'm looking for something along this lines (the code doesn't work):

<Image source={{uri: image}} style={styles.cardImg} onError={(e) => {card.item.media.error = true}}/> 

Upvotes: 5

Views: 5289

Answers (1)

Val
Val

Reputation: 22797

That's where Component shining:

class LoadingImage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      imageLoaded: false
    }
  }

  render() {
    /// delegate every props as Image's props
    return (
      <Image
        {...this.props}
        onLoad={() => this.setState({imageLoaded: true})}
      />
      {!this.state.imageLoaded && (
        <Animated.View
          style={[styles.cardBg, {
            backgroundColor: this._animatedValue.interpolate({
              inputRange: [0, 100],
              outputRange: ['rgba(100,100,100, 0.3)', 
                            'rgba(100,100,100,0.5)']
            })
          }]}
        />
      )}
    );
  }
}

So you can use this LoadingImage in your App.

<LoadingImage
    source={{uri: image}}
    style={styles.cardImg}
/>

Upvotes: 4

Related Questions