首页 > 解决方案 > 使用 FlatList 显示自定义卡片元素并需要使其可触摸

问题描述

我需要在平面列表中使项目列表可触摸,但不知道如何使各个组件可触摸,因此我可以访问该平面列表项的 id。我需要处理 onPress 以便我可以使用 react navigation 5 将用户发送到不同的屏幕。

我正在使用一组数据来创建一个类似卡片的组件,该组件在平面列表中呈现。

如何使单个列表项可触摸?

这是我正在使用的:

import * as React from "react";
import { View, StyleSheet, FlatList, SafeAreaView } from "react-native";

import BigButton from "../components/BigButton.js";
import HomeScreenImage from "../components/HomeScreenImage.js";
import HomeCard from "../components/Card";

const homeOptions = [
  {
    name: "Beast shedule",
    body: "Create and manage your workout shedule",
    image: require("../assets/images/DoubleBis.jpg"),
    id: "1",
  },
  {
    name: "Pre-Made Workouts",
    body: "Use one of our pre-made workouts",
    image: require("../assets/images/ChickA.jpg"),
    id: "2",
  },
  {
    name: "Statistics",
    body: "Analyse your personal statistics",
    image: require("../assets/images/WorkoutInProgress.jpg"),
    id: "3",
  },
  {
    name: "History",
    body: "Keep track of your workout history",
    image: require("../assets/images/ChickH.jpg"),
    id: "4",
  },
];

const HomeScreen = (props) => {
  return (
    <View style={Styles.containerTop}>
      <View>
        <HomeScreenImage style={Styles.top} />
        <View style={Styles.top}>
          <BigButton title="Train & Track" />
        </View>
      </View>
      <SafeAreaView style={Styles.flatListContainer}>
        <FlatList
          data={homeOptions}
          renderItem={({ item }) => {
            return <HomeCard info={item} />;
          }}
          keyExtractor={(homeOption) => homeOption.id}
          showsVerticalScrollIndicator={false}
        />
      </SafeAreaView>
    </View>
  );
};

const Styles = StyleSheet.create({
  containerTop: {
    flex: 1,
    backgroundColor: "#3E3636",
  },
  top: {
    flex: 1,
    height: "1%",
    alignItems: "center",
    justifyContent: "center",
  },
  flatListContainer: {
    flex: 1,
  },
});

export default HomeScreen;



import React from "react";
import { View, Text, StyleSheet, Dimensions, Image } from "react-native";

const HomeCard = (props) => {
  return (
    <View style={Styles.container}>
      <View style={Styles.cardContainer}>
        <Image style={Styles.imageStyle} source={props.info.image} />

        <View style={Styles.infoStyle}>
          <Text style={Styles.titleStyle}>{props.info.name}</Text>
          <Text style={Styles.bodyTextStyle}>{props.info.body}</Text>
        </View>
      </View>
    </View>
  );
};

const deviceWidth = Math.round(Dimensions.get("window").width);
const offset = 25;
const radius = 20;
const Styles = StyleSheet.create({
  container: {
    width: deviceWidth - 20,
    marginTop: 20,
  },
  cardContainer: {
    margin: 10,
    width: deviceWidth - offset,
    backgroundColor: "#000",
    height: 200,
    borderRadius: radius,
    shadowColor: "#000",
    shadowOffset: {
      width: 5,
      height: 5,
    },
    shadowOpacity: 0.75,
    shadowRadius: 5,
    elevation: 3,
  },
  imageStyle: {
    height: 130,
    width: deviceWidth - 25,
    borderTopLeftRadius: radius,
    borderTopRightRadius: radius,
    opacity: 0.95,
  },
  titleStyle: {
    color: "#F5EDED",
    textAlign: "center",
    fontSize: 20,
    fontWeight: "800",
  },
  bodyTextStyle: {
    fontWeight: "200",
    color: "#F5EDED",
    textAlign: "center",
  },
  infoStyle: {
    marginHorizontal: 10,
    marginVertical: 1,
  },
});

export default HomeCard;

标签: react-nativereact-hooksreact-native-androidreact-navigationreact-native-flatlist

解决方案


你可以用一些可触摸的组件来包装你的卡片,TouchableOpacity例如,在prop上使用naviagtion.navigate('routeName', {params})函数。onPress

const HomeCard = (props) => {
  return (
    <TouchableOpacity onPress={() => navigation.navigate('ReceiverRoute', {image: props.info image, name: props.info.name })}> ///etc any parameters you want
     <View style={Styles.container}>
       <View style={Styles.cardContainer}>
         <Image style={Styles.imageStyle} source={props.info.image} />

         <View style={Styles.infoStyle}>
           <Text style={Styles.titleStyle}>{props.info.name}</Text>
           <Text style={Styles.bodyTextStyle}>{props.info.body}</Text>
         </View>
       </View>
     </View>
   </TouchableOpacity>
  );
};

然后导航到可以接收一些参数的组件。对于更简洁的示例,您可以查看docs。主要想法只是将您的卡片包装成一些可触摸的带有onpress导航的东西。对于navigation道具,您可以将其从父组件传递给您的卡片,也可以使用useNavigation 钩子


推荐阅读