在 React Native 中使用 ScrollTo 的 FlatList

Posted

技术标签:

【中文标题】在 React Native 中使用 ScrollTo 的 FlatList【英文标题】:FlatList with ScrollTo in React Native 【发布时间】:2020-12-28 11:34:57 【问题描述】:

我是 React Native 的新手,我正在尝试在一个带有 Expo 的应用程序中创建一个 FlatList,它将从 Json 中提取某些类别的产品,我设法制作了 FlatList 以及一个用于测试的 Json 模拟,但是我希望通过单击 FlatList 中的任何项目,它将滚动引导到相应的部分,在 html 中使用带有 id 的锚时也是如此。

例如:FlatList 将显示类别:Combo、Side Dishes、Hot Dog 等。对于 FlatList 显示的每个类别,我已经创建了一个 View,它将显示该类别中的产品。

我想做什么:

当您单击 FlatList 显示的类别时,Scroll 会滚动到显示该类别产品的 View,也就是说,如果您单击 Combo,页面将滚动到显示 Combo 类别产品的 View,如果您单击配菜页面滚动,直到显示配菜类别中的产品的视图遵循我的代码:

按照我的代码:(这里可以模拟:https://snack.expo.io/@wendell_chrys/06944b)

import React,  useEffect, useState  from 'react';
import  View, Image, ImageBackground, Text, StyleSheet, ScrollView, Dimensions, FlatList, SafeAreaView, TouchableOpacity  from 'react-native';
import  AppLoading  from 'expo';
import Constants from 'expo-constants';


const DATA = [
  
    id: "1",
    title: "Combos",
    categorie: "section1",
  ,
  
    id: "2",
    title: "Side Dishes",
    categorie: "section2",
  ,
  
    id: "3",
    title: "Hot Dog",
    categorie: "section3",
  ,
  
    id: "4",
    title: "Desserts",
    categorie: "section4",
  ,
  
    id: "5",
    title: "Drinks",
    categorie: "section5",
  ,
];

const renderItem = ( item ) => 

  return (
    <Item
      item=item
    />
  );
;

const Item = ( item, onPress, style ) => (
  <TouchableOpacity onPress=onPress >
    <Text style=styles.itenscategoria>item.title</Text>
  </TouchableOpacity>
);



export default function App() 


  return (
    <View style=styles.container>
      <View style=styles.categories>

      <FlatList
        data=DATA
        horizontal
        showsHorizontalScrollIndicator=false
        renderItem=renderItem
        keyExtractor=(item) => item.id
      />


      </View>
        <ScrollView>
        <View style=styles.section1>
          <Text>Combos</Text>
        </View>

        <View style=styles.section2>
          <Text>Side Dishes</Text>
        </View>

        <View style=styles.section3>
          <Text>Hot Dog</Text>
        </View>

        <View style=styles.section4>
          <Text>Desserts</Text>
        </View>

        <View style=styles.section5>
          <Text>Drinks</Text>
        </View>
      </ ScrollView>

    </View >
    );


const styles = StyleSheet.create(
  container: 
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#000',
    padding: 8,
  ,
  categories: 
    backgroundColor: '#FFFFFF',
    width: '100%',
    height: 50,
    top: 10,
    marginBottom:20,
  ,
  itenscategoria: 
    padding:15,
    border: 1,
    borderRadius:25,
    marginRight:10,
,
  section1: 
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  ,
  section2: 
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  ,
  section3: 
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  ,
  section4: 
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  ,
  section5: 
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  ,
);

【问题讨论】:

【参考方案1】:

您可以使用scrollToIndexFlatList

查看下面的完整代码,或the snack here。

import React,  useEffect, useState, useRef  from 'react';
import  View, Image, ImageBackground, Text, StyleSheet, ScrollView, Dimensions, FlatList, SafeAreaView, TouchableOpacity  from 'react-native';
import  AppLoading  from 'expo';
import Constants from 'expo-constants';

const DATA = [
  
    id: "1",
    title: "Combos",
    categorie: "section1",
  ,
  
    id: "2",
    title: "Side Dishes",
    categorie: "section2",
  ,
  
    id: "3",
    title: "Hot Dog",
    categorie: "section3",
  ,
  
    id: "4",
    title: "Desserts",
    categorie: "section4",
  ,
  
    id: "5",
    title: "Drinks",
    categorie: "section5",
  ,
];

export default function App() 
  const flatListRef = useRef();
  
  const handleItemPress = (index) => 
    flatListRef.current.scrollToIndex( animated: true, index );
  ;

  const renderItem = ( item, index ) => 
    return (
      <Item
        item=item
        onPress=() => handleItemPress(index)
      />
    );
  ;

  const Item = ( item, onPress, style ) => (
    <TouchableOpacity onPress=onPress >
      <Text style=styles.itenscategoria>item.title</Text>
    </TouchableOpacity>
  );

  const renderDetails = ( item, index ) => (
    <View style=styles.section>
      <Text>item.title</Text>
    </View>
  );

  return (
    <View style=styles.container>
      <View style=styles.categories>
        <FlatList
          data=DATA
          horizontal
          showsHorizontalScrollIndicator=false
          renderItem=renderItem
          keyExtractor=(item) => item.id
        />
      </View>
      <FlatList
        ref=flatListRef
        data=DATA
        renderItem=renderDetails
        keyExtractor=(item) => item.id
      />
    </View >
    );


const styles = StyleSheet.create(
  container: 
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#000',
    padding: 8,
  ,
  categories: 
    backgroundColor: '#FFFFFF',
    width: '100%',
    height: 50,
    top: 10,
    marginBottom:20,
  ,
  itenscategoria: 
    padding:15,
    border: 1,
    borderRadius:25,
    marginRight:10,
,
  section: 
    marginTop: 10,
    backgroundColor: '#ccc',
    width: '100%',
    height: 200,
    borderRadius: 10,
  ,
);

【讨论】:

谢谢!但是它在网络版本中不起作用。你知道为什么吗?

以上是关于在 React Native 中使用 ScrollTo 的 FlatList的主要内容,如果未能解决你的问题,请参考以下文章

React:使用 Animate on Scroll 库条件渲染 CSS 类

使用 React-Native-Router-Flux 在 React Native 中嵌套场景

在带有 wix/react-native-navigation 的模态中使用 react-native-gesture-handler (RNGH)

尝试在 create-react-native-app 项目 (expo) 中使用 react-native-fs

React-native:如何在 React-native 中使用(和翻译)带有 jsx 的 typescript .tsx 文件?

如何在 React Native 中使用 React Native Video 显示多个视频? [关闭]