react-native-swiper ajax异步获取图片 无法自动轮播 指示点一直是第一个

前因:最近在用React-native 做一个APP,其中有一个新闻页面用到了轮播图,而且要求轮播图的图片都是异步获取的,经过测试,发现只有静态写死的一组图片或者一组文本,才能正常轮播,ajax获取到的无法正常轮播,作死就这样开始了。。。

坑:在父级View容器flex:1时,Swiper的高度是谜一样的存在,平白的多出了不少高度占用了很大空间,给Swiper设置了style不管用,给指示点加样式也不起效,最后,直接给父级View容器加个高度解决问题。 

PS:这边是Swiper组件属性介绍的传送门:https://blog.csdn.net/hzxOnlineOk/article/details/104019665

今天学习了轮播图的使用,上网查阅了一下,发现有react-native-swiper和React-Native-Viewpager(https://blog.csdn.net/zhukui66/article/details/51077592)两种封装的比较好的第三方组件,对比了下文档,觉得react-native-swiper功能更加完善,而且文档说明比较全面,所以只用了react-native-swiper,下面介绍下react-native-swiper的使用。该组件同时支持android和iOS。
react-native-swiper的github地址

使用说明:

  1. 先安装React-native-swiper
    npm install react-native-swiper --save
  2. 导入Swiper
    import Swiper from ‘react-native-swiper’;
    3.使用Swiper

 

<Swiper
    style={styles.swiper}
    height={200}
    horizontal={true}
    paginationStyle={{bottom: 10}}
    showsButtons={false}>
    <Image source={require('./js/img/a.jpg')} style={styles.img}/>
    <Image source={require('./js/img/b.jpg')} style={styles.img}/>
    <Image source={require('./js/img/c.jpg')} style={styles.img}/>
</Swiper>

const styles = StyleSheet.create({

    swiper: {},
    img: {
        width: dimensions.width,
        height: 200,
    }
});

4.相关属性和方法介绍

 

<Swiper
    style={styles.swiper}          //样式
    height={200}                   //组件高度
    loop={true}                    //如果设置为false,那么滑动到最后一张时,再次滑动将不会滑到第一张图片。
    autoplay={true}                //自动轮播
autoplayTimeout={4}                //每隔4秒切换
    horizontal={true}              //水平方向,为false可设置为竖直方向
    paginationStyle={{bottom: 10}} //小圆点的位置:距离底部10px
    showsButtons={false}           //为false时不显示控制按钮
    showsPagination={false}       //为false不显示下方圆点
    dot={<View style={{           //未选中的圆点样式
    backgroundColor: 'rgba(0,0,0,.2)',
    width: 18,
    height: 18,
    borderRadius: 4,
    marginLeft: 10,
    marginRight: 9,
    marginTop: 9,
    marginBottom: 9,
}}/>}
    activeDot={<View style={{    //选中的圆点样式
    backgroundColor: '#007aff',
    width: 18,
    height: 18,
    borderRadius: 4,
    marginLeft: 10,
    marginRight: 9,
    marginTop: 9,
    marginBottom: 9,
}}/>}

>
    <Image source={require('./js/img/a.jpg')} style={styles.img}/>
    <Image source={require('./js/img/b.jpg')} style={styles.img}/>
    <Image source={require('./js/img/c.jpg')} style={styles.img}/>
</Swiper>

image.png

 

image.png

 

image.png

 



作者:现实梦想_96b0
链接:https://www.jianshu.com/p/8905d988d1db
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

 

 

经排查,发现this.state.list在初始化时是一个空数组[],在Swiper组件内通过list&&list.map去遍历,这会导致Swiper组件初始化时,采用list的初始化值也就是空数组[],Swiper组件默认它不存在“滑动子元素(slider)” 也就是slider数为0

 

解决:将list移动到Swiper组件外面进行判断,也就是list.length ? <Component/> : null,由于js的0代表false,因此会在初始化时不渲染Swiper组件,因此避免了Swiper在list没有获取到数据的情况下事先初始化,代码如下:

<View style={styles.headImage}>
	{
		list.length ? <Swiper style={styles.wrapper} height={200} horizontal={true} autoplay autoplayTimeout={1}>
			{
				list.slice(0, 3).map((item, index) => {
					return (
						<TouchableOpacity onPress={() => this._onPressButton(item.id, item)}>
												<View style={styles.headImage}>
													<ImageAction key={index} style={styles.headImage} reqUrl={api.getImage} reqParams={[item.id, "newsLogo"]} />
													<View style={styles.slogan}>
														<Text style={styles.sloganTitle} numberOfLines={1}>{item.title}</Text>
													</View>
												</View>
											</TouchableOpacity>
										)
									})
								}
							</Swiper> : null
						}
					</View>

 

这是原故障完整代码:

import React from 'react';
import { Text, View, TouchableOpacity, ScrollView, Image } from 'react-native';
import Swiper from 'react-native-swiper';
import OAColor from '../../theme/OAColor';
import BaseScene from "../../base/BaseScene";
import RefreshPageContainer from '../../base/RefreshPageContainer';
import { ImageAction } from '../../components';

import { post } from '../../common';
import api from '../../services/app';
import styles from './styles/private-styles';

type IProps = {};
type IState = {};

export default class PrivateIndex extends BaseScene<IProps, IState> {
	constructor(props: Props) {
		super(props);
		mb(this).init(props, {
			list: [],
			pageNum: 1,
			pageSize: 3,
		});
	}

	componentWillMount() {
		super.showNavTitle("私募圈");
		this.getNewsFn()
	}

	getNewsFn = () => {
		const { pageNum, pageSize } = this.state;
		const reqUrl = api.getBestNewNewsList;
		const reqParam = {
			"params": [
				{}, pageNum, pageSize
			]
		};
		post(reqUrl, reqParam)
			.then(res => {
				this.setState({ list: res.rows })
			})
			.catch(error => {
				MOALog.info('==>error', error);
			});
	};

	render() {
		const { list } = this.state;

		return (
			<View style={{ flex: 1 }}>
				<ScrollView style={{ flex: 1 }}>
					<View style={styles.headImage}>
						<Swiper style={styles.wrapper} height={200} horizontal={true} autoplay autoplayTimeout={1}>
							{
								list ? list.map((item, index) => {
									if (index < 3)
										return (
											<TouchableOpacity onPress={() => this._onPressButton(item.id, item)}>
												<View style={styles.headImage}>
													<ImageAction key={index} style={styles.headImage} reqUrl={api.getImage} reqParams={[item.id, "newsLogo"]} />
													<View style={styles.slogan}>
														<Text style={styles.sloganTitle} numberOfLines={1}>{item.title}</Text>
													</View>
												</View>
											</TouchableOpacity>
										)
								}) : ['', '', ''].map(it => {
									return (
										<Image source={require('./img/private.png')} style={{ width: '100%', height: 150 }} />
									)
								})
							}
						</Swiper>

					</View>

					<RefreshPageContainer
						style={{ marginTop: 10, backgroundColor: OAColor.barTint }}
						api={api.getBestNewNewsList}
						renderItem={this.renderMainItem}
						pager={true}
						pageSize={6}
						mutilParams={[{}]}
						dataHandler={(rows, pageNum) => {
							return pageNum === 1 ? rows.slice(3) : rows;
						}}
						showSeparatorComponent={false}
						pageStatusStyle={{ marginTop: 45 }}
					/>
				</ScrollView>
			</View>
		)
	}

	renderMainItem = ({ item }) => {
		return (
			<TouchableOpacity onPress={() => this._onPressButton(item.id, item)}>
				<View style={styles.mainItemContainer}>
					<View style={styles.items}>
						<Text numberOfLines={2} style={{ fontSize: 16, color: '#262626' }}>{item.title}</Text>
						<Text style={{ fontSize: 12, color: OAColor.descText }}>{item.createTime}</Text>
					</View>
					<ImageAction style={styles.rightImage} reqUrl={api.getImage} reqParams={[item.id, "newsLogo"]} />
				</View>
			</TouchableOpacity>
		)
	};

	_onPressButton = (id, item) => {
		mb(this).getNavigator().push('PrivateDetailScene', { id: item.id, item });
	}
}

 

 

这是解决完整代码: 

import React from 'react';
import { Text, View, TouchableOpacity, ScrollView, Image } from 'react-native';
import Swiper from 'react-native-swiper';
import OAColor from '../../theme/OAColor';
import BaseScene from "../../base/BaseScene";
import RefreshPageContainer from '../../base/RefreshPageContainer';
import { ImageAction } from '../../components';

import { post } from '../../common';
import api from '../../services/app';
import styles from './styles/private-styles';

type IProps = {};
type IState = {};

export default class PrivateIndex extends BaseScene<IProps, IState> {
	constructor(props: Props) {
		super(props);
		mb(this).init(props, {
			list: [],
			pageNum: 1,
			pageSize: 3,
		});
	}

	componentWillMount() {
		super.showNavTitle("私募圈");
		this.getNewsFn()
	}

	getNewsFn = () => {
		const { pageNum, pageSize } = this.state;
		const reqUrl = api.getBestNewNewsList;
		const reqParam = {
			"params": [
				{}, pageNum, pageSize
			]
		};
		post(reqUrl, reqParam)
			.then(res => {
				this.setState({ list: res.rows })
			})
			.catch(error => {
				MOALog.info('==>error', error);
			});
	};

	render() {
		const { list } = this.state;

		return (
			<View style={{ flex: 1 }}>
				<ScrollView style={{ flex: 1 }}>
					<View style={styles.headImage}>
						{
							list.length ? <Swiper style={styles.wrapper} height={200} horizontal={true} autoplay autoplayTimeout={1}>
								{
									list.slice(0, 3).map((item, index) => {
										return (
											<TouchableOpacity onPress={() => this._onPressButton(item.id, item)}>
												<View style={styles.headImage}>
													<ImageAction key={index} style={styles.headImage} reqUrl={api.getImage} reqParams={[item.id, "newsLogo"]} />
													<View style={styles.slogan}>
														<Text style={styles.sloganTitle} numberOfLines={1}>{item.title}</Text>
													</View>
												</View>
											</TouchableOpacity>
										)
									})
								}
							</Swiper> : null
						}


					</View>

					<RefreshPageContainer
						style={{ marginTop: 10, backgroundColor: OAColor.barTint }}
						api={api.getBestNewNewsList}
						renderItem={this.renderMainItem}
						pager={true}
						pageSize={6}
						mutilParams={[{}]}
						dataHandler={(rows, pageNum) => {
							return pageNum === 1 ? rows.slice(3) : rows;
						}}
						showSeparatorComponent={false}
						pageStatusStyle={{ marginTop: 45 }}
					/>
				</ScrollView>
			</View>
		)
	}

	renderMainItem = ({ item }) => {
		return (
			<TouchableOpacity onPress={() => this._onPressButton(item.id, item)}>
				<View style={styles.mainItemContainer}>
					<View style={styles.items}>
						<Text numberOfLines={2} style={{ fontSize: 16, color: '#262626' }}>{item.title}</Text>
						<Text style={{ fontSize: 12, color: OAColor.descText }}>{item.createTime}</Text>
					</View>
					<ImageAction style={styles.rightImage} reqUrl={api.getImage} reqParams={[item.id, "newsLogo"]} />
				</View>
			</TouchableOpacity>
		)
	};

	_onPressButton = (id, item) => {
		mb(this).getNavigator().push('PrivateDetailScene', { id: item.id, item });
	}
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hzxOnlineOk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值