学习交流:https://gitee.com/potato512/Learn_ReactNative
react-native学习交流QQ群:806870562
效果图
代码示例
import React,{ Component } from 'react'; import { Dimensions,StyleSheet,View,Text,Alert,TouchableOpacity,Image,Button,ScrollView } from 'react-native'; // 获取屏幕的宽度 let widthScreen = Dimensions.get('window').width; // 定义图片数组 let scrollImages = [ "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=534858419,2528258774&fm=200&gp=0.jpg","https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=124155087,2314196803&fm=27&gp=0.jpg","https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1943249770,628140654&fm=200&gp=0.jpg","https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3237130557,2380283222&fm=200&gp=0.jpg","https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1810050752,207505815&fm=200&gp=0.jpg","https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=4285102968,485584875&fm=200&gp=0.jpg" ]; // 定义垂直滚动视图变量 let scrollViewVertical: ScrollView; type Props = {}; export default class ScrollViewPage extends Component<Props> { state = { // 定义变量,滚动时的当前页码 currentPage:0 }; render() { return( <View style={styles.containerStyle}> <Text style={styles.textStyle}> ScrollView是一个通用的可滚动的容器,你可以在其中放入多个组件和视图,而且这些组件并不需要是同类型的。ScrollView不仅可以垂直滚动,还能水平滚动(通过horizontal属性来设置)。 </Text> <View style={{height:0.5,backgroundColor:"#C0C0C0"}}></View> <Text style={{margin:10,color:"blue"}}>水平滚动</Text> <ScrollView style={styles.scrollStyle} // 水平滚动 horizontal={true}> // 子组件 // 动态设置子组件时须用大括号括起来且以带有返回值的函数形式处理 { // 方法1 // scrollImages.map((imageUrl,imageIndex) => ( // <Image style={styles.imageStyle} source={{uri:imageUrl}} key={imageIndex}/> // )) // 方法2(方法后加了括号()表示立即执行) // (() => { // let result = []; // for (let i = 0; i < scrollImages.length; i++){ // let imageUrl = scrollImages[i]; // result.push(<Image style={styles.imageStyle} source={{uri:imageUrl}} key={i}/>) // } // return result // })() // 方法3(方法后加了括号()表示立即执行) showScrollImage() } </ScrollView> <View style={{height:0.5,color:"orange"}}>垂直滚动</Text> <ScrollView style={styles.scrollStyle} // 垂直滚动 horizontal={false} indicatorStyle={'white'} showsVerticalScrollIndicator={true} // 自动分页(Android无效) pagingEnabled={true} // 开始拖拽 onScrollBeginDrag={() => {console.log("scroll drag begin...")}} // 停止拖拽 onScrollEndDrag={this.scrollDragEnd} // 当滑动后的回调 onMomentumScrollEnd={(event) => { // 获取滑动的偏移量 let offSetY = event.nativeEvent.contentOffset.y; // 通过偏移量和屏幕宽度计算第几页 let page = Math.floor(offSetY/150); // 更新值已获取屏幕更新 this.setState({ currentPage:page }); }} ref={(scrollView) => {scrollViewVertical = scrollView;}}> // 子组件 { scrollImages.map((url,index) => ( <Image style={styles.imageStyle} source={{uri:url}} key={index}/> )) } </ScrollView> // 页码 <View style={{flexDirection:'row',justifyContent:'space-around',alignItems:'center'}}> { showScrollPage(this.state) } </View> <Button onPress={() => {scrollViewVertical.scrollTo({y:0,x:0,animated:true})}} title={"top"} /> <Button onPress={() => {scrollViewVertical.scrollToEnd({animated:true})}} title={"bottom"} /> </View> ) } } const showScrollImage = () => { let images = []; for (let i = 0; i < scrollImages.length; i++) { let url = scrollImages[i]; images.push( <TouchableOpacity onPress={() => {Alert.alert("点击了第" + i + "张图片\n" + url);}} key={i}> <Image style={styles.imageStyle} source={{uri:url}} key={i} /> </TouchableOpacity> ) } return images; }; // 注意,全局函数无法使用this,须在调用时通过传参的形式才能使用currentPage参数 const showScrollPage = (state) => { let pages = []; for (let page = 0; page < scrollImages.length; page++) { let style = (page === state.currentPage) ? {color:'yellow'} :{color:'red'}; pages.push( <Text key={page} style={[{fontSize:20},style]}>●</Text> ); } return pages; }; const scrollDragEnd = () => { console.log('scroll drag end...') }; // 无效,全局函数无法获取this const scrollAnimationEnd = () => { console.log('scroll animation end...'); // 获取滑动的偏移量 let offSetY = scrollViewVertical.nativeEvent.contentOffset.y; // 通过偏移量和屏幕宽度计算第几页 let page = Math.floor(offSetY/scrollViewVertical.nativeEvent.frame.size.height); // 更新值已获取屏幕更新 this.setState({ currentPage:page }); }; const scrollAction = () => { console.log('scrolling...') }; const styles = StyleSheet.create({ containerStyle:{ margin:20,backgroundColor:'#E6E6FA',},textStyle:{ margin:10,color:'green',fontSize:15,scrollStyle:{ margin:10,height:150,backgroundColor:"#FFDEAD",imageStyle:{ margin:10,width:(widthScreen - 80),height:(150 - 20),backgroundColor:"#B0C4DE",} });
注意事项
1、自动分页功能pagingEnabled仅支持iOS,不支持Android;
2、动态设置子组件时,须用大括号括起来且以带有返回值的函数形式处理;示例如下:
{ scrollImages.map((url,index) => ( <Image style={styles.imageStyle} source={{uri:url}} key={index}/> )) }
scrollImages是定义的数据数组
url参数表示scrollImages中的元素
index参数表示scrollImages中的下标
Image表示ScrollView中的子组件是Image组件
{ // 方法后加了括号()表示立即执行 (() => { let result = []; for (let i = 0; i < scrollImages.length; i++){ let imageUrl = scrollImages[i]; result.push(<Image style={styles.imageStyle} source={{uri:imageUrl}} key={i}/>) } return result })() }
3、滚动视图中的页码
定义
state = { // 定义变量,滚动时的当前页码 currentPage:0 };
计算
<ScrollView // 当滑动后的回调 onMomentumScrollEnd={(event) => { // 获取滑动的偏移量 let offSetY = event.nativeEvent.contentOffset.y; // 通过偏移量和屏幕宽度计算第几页 let page = Math.floor(offSetY/150); // 更新值已获取屏幕更新 this.setState({ currentPage:page }); }}> </ScrollView>
使用
// 页码 <View style={{flexDirection:'row',alignItems:'center'}}> { showScrollPage(this.state) } </View>
// 注意,全局函数无法使用this,须在调用时通过传参的形式才能使用currentPage参数 const showScrollPage = (state) => { let pages = []; for (let page = 0; page < scrollImages.length; page++) { let style = (page === state.currentPage) ? {color:'yellow'} :{color:'red'}; pages.push( <Text key={page} style={[{fontSize:20},style]}>●</Text> ); } return pages; };
4、滚动视图的全局变量
定义
let scrollViewVertical: ScrollView;
赋值
<ScrollView ref={(scrollView) => {scrollViewVertical = scrollView;}}> </ScrollView>
使用
<Button onPress={() => {scrollViewVertical.scrollTo({y:0,animated:true})}} title={"top"} />