leecade / leecade/react-native-swiper

In the flatlist of various bugs

Open
#571 0 comments 0 reactions 0 assignees View on GitHub

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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.