3.3 完善轮播广告——Image组件之前的轮播广告页面显示的是简单的文字和背景色,接下来添加一些好看的图片作为轮播广告。React Native中用于图片显示的组件是Image。Image组件可以显示多种不同类型图片,包括网络图片、静态资源、临时的本地图片,以及本地磁盘上的图片(如相册)等。3.3.1 使用网络图片这里先使用网络图片来看看Image的用法和效果。修改app.js代码如下:
01 export default class app extends Component {02 constructor(props) {03 super(props);04 this.state = {05 advertisements: [ // 轮播广告数组06 { // 数组中的每个成员描述了网络图片的url07 url: 'https://img13.360buyimg.com/cms/jfs/t4090/228/
1399180862/217278/206073fe/5874e621Nc675c6d0.jpg'08 }, {09 url: 'https://img13.360buyimg.com/cms/jfs/t3937/
164/1340098884/295670/ca0ebbaf/58703afbN5336c28d.jpg'10 }, {11 url: 'https://img14.360buyimg.com/cms/jfs/t3190/
189/5382195407/297118/377d637e/586f5b7bN9c81c29c.jpg'12 }13 ],14 };15 }16 17 // 这里省略了没有修改的代码18 19 render() {20 return (21 22 // 这里省略了没有修改的代码23 24 25 horizontal={true}26 showsHorizontalScrollIndicator={false}27 pagingEnabled={true}>28 {this.state.advertisements.map((advertisement,
index) => {29 return (30
{() => Alert.alert('你单击了轮播图', null, null)}>31
Content}32 source={{33 uri: advertisement.url34 }}>
35 36 ); 37 })} 38 39 40 // 这里省略了没有修改的代码 41 42 ); 43 } 44 45 // 这里省略了没有修改的代码 46 } ?注意:当使用新的模块或组件时(例如这里的Image)时,首先必须要在文件头导入该模块或组件import {Image} from 'react-native';,否则会发生无法找到变量Image的错误。 重新加载应用,此时使用网络图片的轮播广告效果如图3.11所示。图3.11 使用网络图片的轮播广告3.3.2 使用本地图片除了使用网络图片,还可以将图片资源下载后添加到ch04项目中,使用本地图片。首先,将上面用到的网络图片下载到本地,重命名为advertisement-image-01.jpg、advertisement-image-02.jpg以及advertisement-image-03.jpg,然后复制至ch04项目文件夹中,效果如图3.12所示。
图3.12 下载并添加图片到ch04项目然后,修改代码中Image引用图片的方式,引用网络图片是设置Image组件source属性的url值,而引用本地图片可以直接设置Image组件的source属性,图片通过require方式加载,修改后的app.js代码如下:
01 export default class app extends Component {02 constructor(props) {03 super(props);04 this.state = {05 advertisements: [ // 轮播广告数组06 {07 image: require('./advertisement-image-01.jpg')08 }, {09 image: require('./advertisement-image-02.jpg')10 }, {11 image: require('./advertisement-image-03.jpg')12 }13 ],14 };15 }16 17 // 这里省略了没有修改的代码18 19 render() {20 return (21 22 // 这里省略了没有修改的代码23 24 25 horizontal={true}26 showsHorizontalScrollIndicator={false}27 pagingEnabled={true}>28 {this.state.advertisements.map((advertisement,
index) => {29 return (30
{() => Alert.alert('你单击了轮播图', null, null)}>31
Content}32 source={advertisement.image}>33
34 35 ); 36 })} 37 38 39 // 这里省略了没有修改的代码 40 41 ); 42 } 43 44 // 这里省略了没有修改的代码 45 } ?提示:引用本地图片资源时,需要格外注意require的图片文件路径,否则会发生找不到图片的错误。以上述代码为例, require('./advertisement-image-01.jpg')引用的文件路径是指,在ch04项目根目录下的advertisement-image-01.jpg。 使用本地图片的效果如图3.13所示。图3.13 使用本地图片的轮播广告3.3.3 添加指示器组件给轮播广告换上了漂亮的图片之后,还差一个效果:当前页面指示器,效果如图3.14所示。从图3.14中可以看出,指示器由圆点组成,圆点的个数即页面的数量,并且与当前页面序号相同的圆点会做颜色区分。(1)在了解了指示器的原理之后,首先定义指示器中圆点的尺寸,修改app.js代码如下:
01 const circleSize = 8;02 const circleMargin = 5;0304 export default class app extends Component {05 // 这里省略了没有修改的代码
(2)在render()函数中的轮播广告中添加指示器组件,代码如下:
01 export default class app extends Component {02 // 这里省略了没有修改的代码03 04 render() {05 const advertisementCount = this.state.advertisements.length;
// 指示器圆点个数06 const indicatorWidth = circleSize * advertisementCount +
circleMargin * advertisementCount * 2; // 计算指示器的宽度07 const left = (Dimensions.get('window').width - indicatorWidth)
/ 2; // 计算指示器最左边的坐标位置08 09 return (10 11 // 这里省略了没有修改的代码12 13 14 horizontal={true}15 showsHorizontalScrollIndicator={false}16 pagingEnabled={true}>17 {this.state.advertisements.map((advertisement,
index) => {18 return (19
{() => Alert.alert('你单击了轮播图', null, null)}>20
Content}21 source={advertisement. image}>22
23 24 ); 25 })} 26 27 28 styles.indicator, { 29 left: left 30 } 31 ]}> 32 {this.state.advertisements.map((advertisement, index) => {33 return (34 style={(index === this.state.currentPage)35 ? styles.circleSelected36 : styles.circle}/>);37 })}38 39 40 // 这里省略了没有修改的代码41 42 );43 }4445 // 这里省略了没有修改的代码46 }
在上述代码中,首先通过指示器圆点的个数计算出了指示器的宽度,然后通过屏幕和指示器的宽度,计算出了指示器最左边的坐标位置。(3)修改样式和布局的代码如下:
01 const styles = StyleSheet.create({02 // 这里省略了没有修改的代码03 indicator: {04 position: 'absolute',05 top: 160,06 flexDirection: 'row'07 },08 circle: {09 width: circleSize,10 height: circleSize,11 borderRadius: circleSize / 2,12 backgroundColor: 'gray',13 marginHorizontal: circleMargin14 },15 circleSelected: {17 width: circleSize,18 height: circleSize,19 borderRadius: circleSize / 2,20 backgroundColor: 'white',21 marginHorizontal: circleMargin22 },23 // 这里省略了没有修改的代码24 });
这里我们使用了一种新的布局方法absolute,即绝对布局。使用绝对布局时,组件的位置和尺寸必须明确定义,例如上述代码中top、left、width以及height。由于绝对布局并没有flex布局自适应屏幕的能力,所以在实际开发中,使用绝对布局组件的以上属性往往是通过计算动态得到的,例如上述代码中,指示器的宽度和最左边的坐标位置都是在获取屏幕宽度后,计算得到的。?提示:在实际开发中,如果使用绝对布局,千万不要将位置和尺寸定义为固定值,否则将无法支持不同屏幕的适配。(4)添加完指示器并配置好样式后,运行效果如图3.15所示。