react-native中使用ScrollView组件自己封装走马灯

使用ScrollView替代View可以实现安全范围内的滚动

showsVerticalScrollIndicator隐藏滚动条

<ScrollView showsVerticalScrollIndicator={false}></ScrollView>

制作轮播图

import {
  View,
  Text,
  StatusBar,
  SafeAreaView,
  StyleSheet,
  ScrollView,
  Image,
  Dimensions,
} from 'react-native';
const screenWidth = Math.round(Dimensions.get('window').width);

const App = () => {
  const scrollRef = useRef();
  const [currentIndex, setCurrentIndex] = useState(0);

  useEffect(() => {
    //初始化后,页面渲染完,立即滚动到真正的第一页
    setTimeout(() => {
      scrollRef.current.scrollTo({x: screenWidth, y: 0, animated: false});
    }, 0);
  }, [scrollRef]);

  useEffect(() => {
    scrollRef.current.currentIndex = currentIndex;
  }, [currentIndex, scrollRef]);

  //定时器,定时滚动
  useEffect(() => {
    console.log('初始化了定时器');
    setInterval(() => {
      const offset = screenWidth * (scrollRef.current.currentIndex + 2);
      scrollRef.current.scrollTo({x: offset, y: 0, animated: true});
    }, 3000);
  }, [scrollRef]);

  const scrollEnd = useCallback(event => {
    let index = event.nativeEvent.contentOffset.x / screenWidth;
    // index = Math.round(index);
    // console.log(index);
    if (index === 0) {
      setCurrentIndex(() => 3);
      //这是最后一页,应该去到真实的最后一页
      const offset = screenWidth * images.length;
      scrollRef.current.scrollTo({x: offset, y: 0, animated: false});
    } else if (index === 5) {
      setCurrentIndex(() => 0);
      //这是第一页
      const offset = screenWidth;
      scrollRef.current.scrollTo({x: offset, y: 0, animated: false});
    } else {
      setCurrentIndex(() => index - 1);
    }
  }, []);

  return (
    <>
      <StatusBar />
      <SafeAreaView style={S.container}>
        <Header />
        <View style={S.content}>

          <View style={S.scroll}>
            <ScrollView
              ref={scrollRef}
              alwaysBounceVertical={false}
              contentContainerStyle={S.scrollWrap}
              onMomentumScrollEnd={scrollEnd}
              showsHorizontalScrollIndicator={false}
              pagingEnabled={true}>
              {/* 假的最后一张 */}
              <Image style={S.image} source={{uri: images[3]}} />
              {/* 真实的内容 */}
              {images.map((item, index) => (
                <Image key={index} style={S.image} source={{uri: item}} />
              ))}
              {/* 假的第一张 */}
              <Image style={S.image} source={{uri: images[0]}} />
            </ScrollView>
          </View>
          <Text style={{fontSize: 100}}>{currentIndex}</Text>
        </View>
      </SafeAreaView>
    </>
  );
};

样式:

const S = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#f1f1f1',
    overflow: 'hidden',
  },
  content: {
    flex: 1,
    backgroundColor: 'red',
  },
  scroll: {
    width: '100%',
    height: 200,
    backgroundColor: '#fff',
  },
  scrollWrap: {
    width: '600%',
    height: 200,
    flexDirection: 'row',
  },
  image: {
    width: (1 / 6) * 100 + '%',
    height: 200,
  },
});
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值