leecade / leecade/react-native-swiper
In the flatlist of various bugs
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 10.5k
- Forks
- 2.3k
- PR merge metrics
- No merged PRs in 30d
Description
Which OS ?
windows10 / android
Version
Which versions are you using:
@^0.44.0
- react-native-swiper v?
- react-native v0.?.?
@^1.5.12
Expected behaviour
Actual behaviour
1, when the slide out of a screen in the return, swiper is not smooth
2, when triggering flatlist onEndReached function, swiper becomes not smooth
How to reproduce it>
To help us, please fork this component, modify one example in examples folder to reproduce your issue and include link here.
My solution and the problem
I re-encapsulate a carousel component with scrollview, which he can run. But he is not perfect, react-native-swiper should be how to change can be used in navigation or flatlist
///*****************
/*
- @Author: AI
- @Date: 2017-09-15 11:04:59
- @Last Modified by: AI
- @Last Modified time: 2017-09-15 12:07:32
*/
'use strict'
import React, { Component } from 'react'
import {
AppRegistry,
StyleSheet,
Text,
View,
ScrollView
} from 'react-native'
import {observable, action} from 'mobx'
import {observer} from 'mobx-react/native'
import { common } from '../common/common'
class SwiperMobx {
@observable currentPage = 1
@action _upData(data) {
for(let item in data) {this[item] = data[item]}
}
}
let width = null
// 注意,这个组件依赖于common模块中的设备宽度数据,如果要分离为单独的组件需做处理
// 组件配置
// time {number} 轮播时间间隔,秒为单位
// style {obj} 轮播图整体盒子的样式,一般设置宽高,宽度默认100%
// width {number} 轮播图轮播的宽度,重要参数,默认为屏幕宽度,也可以自定义
// data {any} 要渲染的数据源,只支持数组,必须的参数
// dotColor {string} 没选中的指示点的颜色
// dotSelectColor {string} 选中的指示点的颜色
// dotPosition {string} 指示点的位置,支持justifyContent的选项配置 flex-start,center,space-between等
// dotBoxStyle {obj} 指示点盒子的样式,已经有一部分默认样式,一般设置高度和背景色浮层
//_renderRow {function} 要渲染的每个轮播子项的结构,重要参数,没有默认值,需要自定义,有两个参数为{item,index} 每一项数据及对应的索引
@observer
export default class Swiper extends Component{
constructor(props){
super(props)
this.sta = new SwiperMobx()
}
componentDidMount() {
}
componentWillUnmount() {
this.timer && clearInterval(this.timer)
}
// 开启定时器
_startTimer() {
// 拿到scrollView
let scrollView = this.scrollView,
length = this.props.data.length
// 添加定时器
this.timer = setInterval(() => {
let tempPage
if (this.sta.currentPage >= length) {
tempPage = 1
} else {
tempPage = this.sta.currentPage+1
}
// 更新状态机
this.sta._upData( {
currentPage: tempPage
})
// 改变scrollView的偏移量
let offSet = tempPage * width
scrollView.scrollTo({x: offSet, y: 0, animated: true})
}, this.props.time*1000 || 2000)
}
// 当一帧滚动结束的时候会调用此方法,手动滚动时触发
_onAnimationEnd(e) {
// 获取偏移量
let offset = e.nativeEvent.contentOffset.x,
page = Math.floor(offset / width),
length = this.props.data.length
if(page === length + 1){
// 到了轮播图的最后
this.scrollView.scrollTo({x: width, y: 0, animated: true})
page = 1
} else if(page === 0) {
this.scrollView.scrollTo({x: width*length, y: 0, animated: true})
page = length
}
// 更新状态机,重新绘制UI
this.sta._upData({
currentPage: page
})
}
_onScrollBeginDrag() {
// 清除定时器
clearInterval(this.timer)
}
_onScrollEndDrag() {
// 重新开启定时器
this._startTimer()
}
// 返回所有图片
_renderAllImages() {
if(this.props.data.length <= 0){
return
}
this.timer ? null : this._startTimer()
width = this.props.width || common.ScrollWidth
let imgArr = this.props.data.slice(),
length = imgArr.length,
imgItems = []
imgArr.push(imgArr[0])
imgArr = [imgArr[length - 1]].concat(imgArr)
imgArr.map((item, index) => {
imgItems.push(
this.props._renderRow(item, index)
)
})
return imgItems
}
// 设置小圆点
_renderAllCycle() {
if(this.props.data.length <= 0){
return
}
const { dotColor, dotSelectColor, dotPosition } = this.props
let imgArr = this.props.data.slice(),
length = imgArr.length,
cycleItems = [],
colorStyle
imgArr.map((item, index) => {
colorStyle = (index+1 === this.sta.currentPage) ? {color: dotSelectColor || 'gray'} : {color: dotColor || 'white'}
cycleItems.push(
<Text key={index} style={[{fontSize: 30}, colorStyle,]}>•
)
})
return cycleItems
}
render() {
const { data, _renderRow, width, dotPosition, style, dotBoxStyle } = this.props
return (
<View style={[styles.container,style,width && {width: width}]}>
<ScrollView
ref = {ref => this.scrollView = ref}
horizontal={true}
pagingEnabled={true}
showsHorizontalScrollIndicator={false}
style={styles.scrollViewStyle}
onMomentumScrollEnd={(e)=>this._onAnimationEnd(e)}
onScrollBeginDrag={this._onScrollBeginDrag.bind(this)}
onScrollEndDrag={this._onScrollEndDrag.bind(this)}
>
{this._renderAllImages()}
</ScrollView>
<View style={[styles.cycleStyle,dotBoxStyle,{justifyContent: dotPosition}]}>
{this._renderAllCycle()}
</View>
</View>
)
}
}
// 设置样式
const styles = StyleSheet.create({
container: {
width: '100%',
},
scrollViewStyle: {
backgroundColor: '#f3f3f3',
width: '100%',
},
cycleStyle: {
width: '100%',
height: 30,
position: 'absolute',
bottom: 0,
paddingHorizontal: 10,
flexDirection: 'row',
alignItems: 'center'
}
})
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the examples folder and the ScrollView-based swiper code shown in the issue, focusing on the interaction with FlatList's onEndReached and navigation. Reproduce the reported stuttering on Windows 10 and Android; done means the swiper remains smooth when slides leave and re-enter the screen or when FlatList reaches the end.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, react-native
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100