輪播圖大家都比較熟悉 ,React Native 如何實現一個輪播圖呢?官方是沒有提供輪播圖組件的,但大家一定用過一個庫叫Swiper
,Swiper
主要實現的效果是輪播圖或者左右翻頁的效果。但是如果要實現一些效果很炫酷的輪播圖、左右翻頁效果,Swiper
就不能勝任了。今天就給大家介紹一個非常炫酷的UI庫-react-native-snap-carouse
。
Carouse 介紹
react-native-snap-carouse
是一個Swiper
組件,它提供了預覽、多佈局、視差圖像及處理巨大列表數據的能力。可能這些解釋有點乏力,到底能提供什麼樣的效果呢?請看示例:
效果是不是非常贊?看看如何使用
使用介紹
首先安裝:
$ npm install --save react-native-snap-carousel
然後在頁面中使用Carousel
組件:
import Carousel from 'react-native-snap-carousel';
export class MyCarousel extends Component {
_renderItem ({item, index}) {
return (
<View style={styles.slide}>
<Text style={styles.title}>{ item.title }</Text>
</View>
);
}
render () {
return (
<Carousel
ref={(c) => { this._carousel = c; }}
data={this.state.entries}
renderItem={this._renderItem}
sliderWidth={sliderWidth}
itemWidth={itemWidth}
/>
);
}
}
文章開頭的那幾種效果,主要通過一個layout
屬性來控制:layout
定義Item 的交互動畫和渲染方式,有三種取值,defalut
,stack
,tinder
。但是需要注意的是stack
、tinder
屬性將激活useScrollView
,看名字就知道內部會用ScrollView
實現而不是FlatList
。因此,如果你的數據集很大,那麼這2種佈局將不適合使用,因爲所有項目都將被預先渲染。
分別看一下三種效果:
<Carousel layout={'default'} />
-
<Carousel layout={'stack'} layoutCardOffset={
18} />
,類似iphone
切換應用的效果
-
<Carousel layout={'tinder'} layoutCardOffset={
9} />
, 類似仿探探應用
的卡片滑動效果
感謝React Native出色的Animated API,我們能夠做到所有這些。基本上,我們對當前滾動位置進行插值,並根據此值向每個項目提供一組動畫。但是這些新的佈局只是冰山一角,你可以很輕鬆的實現以下這些效果:
代碼:
import React, { PureComponent } from 'react';
import Carousel, { getInputRangeFromIndexes } from 'react-native-snap-carousel';
export default class MyCustomCarousel extends PureComponent {
_scrollInterpolator (index, carouselProps) {
const range = [3, 2, 1, 0, -1];
const inputRange = getInputRangeFromIndexes(range, index, carouselProps);
const outputRange = range;
return { inputRange, outputRange };
}
_animatedStyles (index, animatedValue, carouselProps) {
const sizeRef = carouselProps.vertical ? carouselProps.itemHeight : carouselProps.itemWidth;
const translateProp = carouselProps.vertical ? 'translateY' : 'translateX';
return {
zIndex: carouselProps.data.length - index,
opacity: animatedValue.interpolate({
inputRange: [2, 3],
outputRange: [1, 0]
}),
transform: [{
rotate: animatedValue.interpolate({
inputRange: [-1, 0, 1, 2, 3],
outputRange: ['-25deg', '0deg', '-3deg', '1.8deg', '0deg'],
extrapolate: 'clamp'
})
}, {
[translateProp]: animatedValue.interpolate({
inputRange: [-1, 0, 1, 2, 3],
outputRange: [
-sizeRef * 0.5,
0,
-sizeRef, // centered
-sizeRef * 2, // centered
-sizeRef * 3 // centered
],
extrapolate: 'clamp'
})
}]
};
}
render () {
return (
<Carousel
// other props
scrollInterpolator={this._scrollInterpolator}
slideInterpolatedStyle={this._animatedStyles}
useScrollView={true}
/>
);
}
}
只給出了部分代碼,全部代碼及文檔請看:https://github.com/archriss/react-native-snap-carousel/blob/master/doc/CUSTOM_INTERPOLATIONS.md
ParallaxImage 組件
Carsousel
庫中還提供了另外一個組件ParallaxImage
,一個知道輪播的當前滾動位置的圖像組件,因此能夠顯示出不錯的視差效果。效果圖如下:
代碼如下:
import Carousel, { ParallaxImage } from 'react-native-snap-carousel';
import { Dimensions, StyleSheet } from 'react-native';
const { width: screenWidth } = Dimensions.get('window')
export default class MyCarousel extends Component {
_renderItem ({item, index}, parallaxProps) {
return (
<View style={styles.item}>
<ParallaxImage
source={{ uri: item.thumbnail }}
containerStyle={styles.imageContainer}
style={styles.image}
parallaxFactor={0.4}
{...parallaxProps}
/>
<Text style={styles.title} numberOfLines={2}>
{ item.title }
</Text>
</View>
);
}
render () {
return (
<Carousel
sliderWidth={screenWidth}
sliderHeight={screenWidth}
itemWidth={screenWidth - 60}
data={this.state.entries}
renderItem={this._renderItem}
hasParallaxImages={true}
/>
);
}
}
const styles = StyleSheet.create({
item: {
width: screenWidth - 60,
height: screenWidth - 60,
},
imageContainer: {
flex: 1,
marginBottom: Platform.select({ ios: 0, android: 1 }), // Prevent a random Android rendering issue
backgroundColor: 'white',
borderRadius: 8,
},
image: {
...StyleSheet.absoluteFillObject,
resizeMode: 'cover',
},
})
以上只是列出了一些主要的效果,但遠不止這些,它提供了很多的屬性
和方法
來方便的創建和操作它們,詳細的文檔請看Github:https://github.com/archriss/react-native-snap-carousel