如何使用 Animated 使列表 (FlatList) 自动滚动元素? [英] How do I make a list (FlatList) automatically scroll through the elements using Animated?

查看:27
本文介绍了如何使用 Animated 使列表 (FlatList) 自动滚动元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个水平的 FlatList,每次到达末尾时,它都会自动向列表中添加新元素,因此它是一个无限列表.我希望应用程序自己自动滚动列表,而用户仍然必须能够来回滚动.这就是我要远的

export default class ImageCarousel extends Component {构造函数(道具){超级(道具);this.scrollX = 0;this.offset = new Animated.Value(0);this.scrollTo = this.scrollTo.bind(this);this.handleScroll = this.handleScroll.bind(this);this.stopAnimation = this.stopAnimation.bind(this);//监听器调用 scrollToOffset 函数this.offset.addListener(this.scrollTo);}_scroller() {toValue = this.scrollX + 10;//在每个循环中滚动 10 个像素this.animation = Animated.timing(this.offset,{toValue: toValue,duration: 1000,//一个循环需要一秒钟缓动:缓动.线性,});this.animation.start(() => this._scroller());//完成后重复自己}滚动到(e){this.carousel.scrollToOffset({offset: e.value});}句柄滚动(事件){//每次滚动发生时保存 x(水平)值this.scrollX = event.nativeEvent.contentOffset.x;}componentDidMount() {this._scroller();}使成为() {返回 (<查看><平面列表ref={el =>this.carousel = el}数据={someData}renderItem={renderFunction}水平={真}keyExtractor={someKeyFunction}onEndReached={loadMoreElementsFunction}onScroll={this.handleScroll}/></查看>);}}

它的工作原理是它会自动滚动列表,但是问题是我无法手动滚动列表,因为滚动位置会由 scrollTo 侦听器不断更新.我尝试添加一个 onPress 回调以在按下 FlatList 时禁用动画,但是我无法让它工作.

解决方案

  1. 这是我的数据.

<块引用>

块引用

state = {关联: ['https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg','https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg','https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg','https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',],};

<块引用>

  1. 定义 FlatList 引用

flatList = createRef();

<块引用>

  1. FlatList 组件

 

<块引用>

  1. 下一张幻灯片

 _goToNextPage = () =>{if (CurrentSlide >= this.state.link.length-1) CurrentSlide = 0;this.flatList.current.scrollToIndex({索引:++CurrentSlide,动画:真实,});};

<块引用>

  1. 开始和停止间隔

 _startAutoPlay = () =>{this._timerId = setInterval(this._goToNextPage, IntervalTime);};_stopAutoPlay = () =>{如果(this._timerId){clearInterval(this._timerId);this._timerId = null;}};

<块引用>

  1. 相关功能

componentDidMount() {this._stopAutoPlay();this._startAutoPlay();}componentWillUnmount() {this._stopAutoPlay();}_renderItem({item, index}) {return <Image source={{uri: item}} style={styles.sliderItems}/>;}_keyExtractor(项目,索引){返回 index.toString();}

<块引用>

完整代码:

import React, {Component, createRef} from 'react';进口 {文本,看法,滚动视图,图像,样式表,方面,平面列表,来自'反应原生';让 CurrentSlide = 0;让间隔时间 = 4000;导出默认类滑块扩展组件{flatList = createRef();//待办事项 _goToNextPage()_goToNextPage = () =>{if (CurrentSlide >= this.state.link.length-1) CurrentSlide = 0;this.flatList.current.scrollToIndex({索引:++CurrentSlide,动画:真实,});};_startAutoPlay = () =>{this._timerId = setInterval(this._goToNextPage, IntervalTime);};_stopAutoPlay = () =>{如果(this._timerId){clearInterval(this._timerId);this._timerId = null;}};componentDidMount() {this._stopAutoPlay();this._startAutoPlay();}componentWillUnmount() {this._stopAutoPlay();}//待办事项 _renderItem()_renderItem({item, index}) {return <Image source={{uri: item}} style={styles.sliderItems}/>;}//待办事项 _keyExtractor()_keyExtractor(项目,索引){//console.log(item);返回 index.toString();}状态 = {关联: ['https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg','https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',//'https://picsum.photos/200/300','https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg','https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',],};使成为() {返回 (<视图样式={{marginTop: 10, marginBottom: 10}}><平面列表风格={{弹性:1,//TODO 移除额外的全局填充//marginLeft: -size.padding,//marginRight: -size.padding,}}数据={this.state.link}keyExtractor={this._keyExtractor.bind(this)}renderItem={this._renderItem.bind(this)}水平={真}flatListRef={React.createRef()}ref={this.flatList}/></查看>);}}const 样式 = StyleSheet.create({滑块项目:{左边距:5,边距:5,高度:200,宽度:Dimensions.get('window').width,},});

I have a horizontal FlatList, where each time it reaches the end, it automatically adds new elements to the list, so it kind of is an infinite list. I want the app to scroll through the list by itself automatically, while the user must still be able to scroll back and forth. This is what I have to far

export default class ImageCarousel extends Component {
  constructor(props) {
    super(props);

    this.scrollX = 0;
    this.offset = new Animated.Value(0);
    this.scrollTo = this.scrollTo.bind(this);
    this.handleScroll = this.handleScroll.bind(this);
    this.stopAnimation = this.stopAnimation.bind(this);
    // Listener to call the scrollToOffset function
    this.offset.addListener(this.scrollTo);
  }

  _scroller() {
    toValue = this.scrollX + 10; // Scroll 10 pixels in each loop
    this.animation = Animated.timing(
      this.offset,
      {
        toValue: toValue,
        duration: 1000, // A loop takes a second
        easing: Easing.linear,
      }
    );
    this.animation.start(() => this._scroller()); //Repeats itself when done
  }

  scrollTo(e) {
    this.carousel.scrollToOffset({offset: e.value});
  }

  handleScroll(event) {
    // Save the x (horizontal) value each time a scroll occurs
    this.scrollX = event.nativeEvent.contentOffset.x;
  }

  componentDidMount() {
    this._scroller();
  }
  render() {
    return (
      <View>
        <FlatList
          ref={el => this.carousel = el}
          data={someData}
          renderItem={renderFunction}
          horizontal={true}
          keyExtractor={someKeyFunction}
          onEndReached={loadMoreElementsFunction}
          onScroll={this.handleScroll}
        />
      </View>
    );
  }
}

It works in the sense that it is automatically scrolling through the list, the problem however, is I cannot manually scroll through the list, since the scroll position is constantly updated by the scrollTo listener. I have tried to add an onPress callback to disable the animation when the FlatList is pressed, I have however not been able to get it to work.

解决方案

  1. This is my Data.

Blockquote

state = { 
link: [
  'https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',
  'https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',
  'https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',
  'https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',
],};

  1. Define FlatList Ref

flatList = createRef();

  1. FlatList component

   <FlatList
      style={{flex: 1}}
      data={this.state.link}
      keyExtractor={this._keyExtractor.bind(this)}
      renderItem={this._renderItem.bind(this)}
      horizontal={true}
      flatListRef={React.createRef()}
      ref={this.flatList}
    />

  1. Next slide

  _goToNextPage = () => {
     if (CurrentSlide >= this.state.link.length-1) CurrentSlide = 0;
     this.flatList.current.scrollToIndex({
     index: ++CurrentSlide,
     animated: true,
    });
  };

  1. Start and stop Interval

  _startAutoPlay = () => {
    this._timerId = setInterval(this._goToNextPage, IntervalTime);
  };



_stopAutoPlay = () => {
    if (this._timerId) {
      clearInterval(this._timerId);
      this._timerId = null;
    }
  };

  1. Associated function

componentDidMount() {
   this._stopAutoPlay();
   this._startAutoPlay();
}

componentWillUnmount() {
   this._stopAutoPlay();
}

_renderItem({item, index}) {
    return <Image source={{uri: item}} style={styles.sliderItems} />;
 }

_keyExtractor(item, index) {
    return index.toString();
 }

Full Code:

import React, {Component, createRef} from 'react';
import {
  Text,
  View,
  ScrollView,
  Image,
  StyleSheet,
  Dimensions,
  FlatList,
} from 'react-native';

let CurrentSlide = 0;
let IntervalTime = 4000;

export default class Slider extends Component {
  flatList = createRef();

  // TODO _goToNextPage()
  _goToNextPage = () => {
    if (CurrentSlide >= this.state.link.length-1) CurrentSlide = 0;

    this.flatList.current.scrollToIndex({
      index: ++CurrentSlide,
      animated: true,
    });
  };

  _startAutoPlay = () => {
    this._timerId = setInterval(this._goToNextPage, IntervalTime);
  };

  _stopAutoPlay = () => {
    if (this._timerId) {
      clearInterval(this._timerId);
      this._timerId = null;
    }
  };


  componentDidMount() {
    this._stopAutoPlay();
    this._startAutoPlay();
  }

  componentWillUnmount() {
    this._stopAutoPlay();
  }

  // TODO _renderItem()
  _renderItem({item, index}) {
    return <Image source={{uri: item}} style={styles.sliderItems} />;
  }

  // TODO _keyExtractor()
  _keyExtractor(item, index) {
    // console.log(item);
    return index.toString();
  }
  state = {
    link: [
      'https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',
      'https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',
    //   'https://picsum.photos/200/300',
      'https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',
      'https://image.shutterstock.com/image-vector/online-exam-computer-web-app-260nw-1105800884.jpg',
    ],
  };

  render() {
    return (
      <View style={{marginTop: 10, marginBottom: 10}}>
        <FlatList
          style={{
            flex: 1,
            // TODO Remove extera global padding
            // marginLeft: -size.padding,
            // marginRight: -size.padding,
          }}
          data={this.state.link}
          keyExtractor={this._keyExtractor.bind(this)}
          renderItem={this._renderItem.bind(this)}
          horizontal={true}
          flatListRef={React.createRef()}
          ref={this.flatList}
        />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  sliderItems: {
    marginLeft: 5,
    marginRight: 5,
    height: 200,
    width: Dimensions.get('window').width,
  },
});

这篇关于如何使用 Animated 使列表 (FlatList) 自动滚动元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆