由于RN在Android平台上不支持gif格式的图片,今天介绍下我们是怎么处理这个问题的。
先来看看我们需要实现的效果,这是一张gif图片,当我们列表上拉加载下一页的时候需要使用这个效果,如下图:
我们的解决方案是:将gif切成15张png的图片,暂且命名为loading1、loading2.... loading15
然后循环的setState修改图片,就像看电影一样,达到动画的效果。
1、在构造方法中初始化图片数组
-
- var loading_imgs = new Array();
-
- const imageLength = 15;
-
- const imageIndex = 0;
-
-
- constructor(props) {
- super(props);
- this.state = {
- dataSource: new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2,}),
- ….
- imageIndex:imageIndex,
- };
-
-
- for( i=1;i<= imageLength;i++){
- let loadingUri = "loading" + i;
- let img = <Image source={{uri:loadingUri}} key={i} style={{width:20,height:20}}/>;
- loading_imgs.push(img);
- }
- }
2、预加载图片数组
为什么要预加载?
刚开始我们做的时候,也没有预加载,只是在构造方法中定义了图片数组loading_imgs,但是在真机上看的时候,发现图片播放的时候第一次会很卡顿,这是因为图片加载到内存需要时间,当我们轮播图片的时候图片还没有加载完毕,在视觉上造成卡顿的效果。
我们是把图片数组初始化在屏幕外面(绝对定位),这种方式不太好。
- render() {
- return (
- <View style={styles.container}>
- <View style={{position:'absolute', top:-1000}}>
- {
- loading_imgs.map((item,i)=> loading_imgs[i])
- }
- </View>
- </View>
- )};
3、轮播图片
定义图片轮播函数_loop
每隔100毫秒切换一张图片
当数据加载完毕,清楚定时任务,并且将图片置为第一张
- 图片轮播函数
- _loop() {
- this.loopCount++;
- if (this.loopCount < loading_imgs.length) {
- this.setState({
- imageIndex: this.loopCount,
- });
- }else {
- this.loopCount = -1;
- }
- }
-
-
- this.timerPic = setInterval(this._loop.bind(this), 100);
-
-
- this.timer1 && clearInterval(this.timer1);
- this.loopCount = -1;
这样我们就实现上gif的效果。
在我们做的过程中也发现了一个RN的组件ActivityIndicator的bug,
- <ActivityIndicator
- animating={true}
- size="small"
- />
当我们给
ActivityIndicator
设置color的时候,在锤子手机上默认color是灰色,当设置为red时,动画效果没有。
在meizu手机上,默认是绿色,设置为red时,效果正常。
在Android平台上,RN的坑不是一点点啊。