React Native

时间:2016-02-08 09:05:47

标签: image react-native preloading

我正在使用React Native构建我的第一个应用程序,这是一个包含很长图像列表的应用程序。我想在加载图像时显示微调器而不是图像。这听起来微不足道,但我没有找到解决方案。 我认为对于一个微调器,我想使用ActivityIndicatorIOS,但我如何将它与Image组件结合起来?

<Image source={...}>
  <ActivityIndicatorIOS />
</Image>

这是一个正确的方向吗?我错过了什么吗?

5 个答案:

答案 0 :(得分:7)

刚遇到同样的问题。所以基本上你有正确的方法,但指标当然只应在图像加载时呈现。跟踪你需要的状态。为了简单起见,我们假设您只在组件中的图像上保持它在同一组件中的状态。 (很酷的孩子会说你应该使用更高阶的组件,然后通过道具传递状态;)

接下来的想法是,你的图像开始加载和onLoadEnd(或onLoad,但随后微调器卡在错误上,这很好或当然)你重新设置状态。

getInitialState: function(){ return { loading: true }}

render: function(){
    <Image source={...} onLoadEnd={ ()=>{ this.setState({ loading: false }) }>
        <ActivityIndicatorIOS animating={ this.state.loading }/>
    </Image>
}

你也可以从{loading:false}开始,并在onLoadStart上设置为true,但我不确定它的好处是什么。

另外,出于样式原因,您可能需要将指示器放在绝对定位的容器视图中,具体取决于您的布局。但是你明白了。

答案 1 :(得分:3)

我将分享我的解决方案

<View>
    <Image source={{uri: this.state.avatar}} style={styles.maybeRenderImage}
                                   resizeMode={"contain"} onLoadStart={() => this.setState({loading: true})}
                                   onLoadEnd={() => {
                                       this.setState({loading: false})
    }}/>
    {this.state.loading && <LoadingView/>}
</View>

LoadingView.js

export default class LoadingView extends Component {
    render() {
        return (
            <View style={styles.container}>
                <ActivityIndicator size="small" color="#FFD700"/>
            </View>
        );
    }
}
const styles = StyleSheet.create({
    container: {
        position: "absolute",
        left: 0,
        right: 0,
        top: 0,
        bottom: 0,
        opacity: 0.7,
        backgroundColor: "black",
        justifyContent: "center",
        alignItems: "center",
    }
});

答案 2 :(得分:1)

我将仅基于CSS操纵共享我自己的解决方案,我认为这很容易理解,并且代码非常简洁。该解决方案与其他答案有点相似,但是不需要任何组件的绝对位置或创建任何其他组件。

这个想法是根据某些状态变量(在下面的代码段中<ActivityIndicator>)在显示isImageLoaded<View> <Image source={...} onLoad={ () => this.setState({ isImageLoaded: true }) } style={[styles.image, { display: (this.state.isImageLoaded ? 'flex' : 'none') }]} /> <ActivityIndicator style={{ display: (this.state.isImageLoaded ? 'none' : 'flex') }} /> </View> 之间切换。

flex

还应该使用const styles = StyleSheet.create({ image: { flex: 1, } }); 属性设置图像大小(否则图像将不可见):

isImageLoaded

请注意,您不必在构造函数中将false变量初始化为undefined,因为它将具有if值,并且static条件将充当预期的。

答案 3 :(得分:0)

这是一个完整的解决方案,可为自定义图像组件提供一个 loading 活动指示器,该指示器位于图像的 下方。

import React, { Component } from 'react';
import { StyleSheet, View, Image, ActivityIndicator } from 'react-native';

export default class LoadableImage extends Component {
  state = {
    loading: true
  }

  render() {
    const { url } = this.props

    return (
      <View style={styles.container}>
        <Image
          onLoadEnd={this._onLoadEnd}
          source={{ uri: url }}
        />
        <ActivityIndicator
          style={styles.activityIndicator}
          animating={this.state.loading}
        />
      </View>
    )
  }

  _onLoadEnd = () => {
    this.setState({
      loading: false
    })
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  activityIndicator: {
    position: 'absolute',
    left: 0,
    right: 0,
    top: 0,
    bottom: 0,
  }
})

答案 4 :(得分:0)

是, deafultSource loadingIndicatorSource 无法正常工作。图像组件也不能包含子级。试试这个解决方案=> https://stackoverflow.com/a/62510268/11302100