首页 > 解决方案 > 如何折叠按在数组上的项目 - 反应原生?

问题描述

我有一张卡片列表,当按下其中任何一张时,我想增加该卡片的高度,所以我使用 layoutAnimation 来处理这种情况,因为当我使用 RN 的 Animated API 时,我在 setNativeDrive "height" 无论如何,就我而言,它会增加列表中每张卡片的高度,

那么我该如何解决呢?

代码片段

现场演示

const OpenedAppointments = ({slideWidth}) => {
  const [currentIndex, setCurrentIndex] = React.useState(null);

  const [cardHeight, setCardHeight] = useState(140);

  const collapseCard = (cardIndex) => {
    setCurrentIndex(cardIndex);
    currentIndex === cardIndex
      ? (LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut),
        Animated.spring(),
        setCardHeight(200))
      : (LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut),
        Animated.spring(),
        setCardHeight(140));
  };

  const renderItems = (item, index) => {
    return (
      <TouchableOpacity
        delayPressIn={0}
        onPress={() => collapseCard(index)}
        key={item.id}>
        <Animated.View
          style={[
            styles.itemContainer,
            {
              height: cardHeight,
            },
          ]}>
          <View style={styles.headerContainer}>
            <View style={styles.imgContainer}>
              <Image
                resizeMode="cover"
                style={styles.img}
                source={{uri: item.vendorInfo.vendorImg}}
              />
            </View>
            <View style={{width: '80%'}}>
              <View style={styles.titleContainer}>
                <Text numberOfLines={1} style={styles.vendorName}>
                  {item.vendorInfo.name}
                </Text>
                <View style={{flexDirection: 'row', alignItems: 'center'}}>
                  <Text style={styles.rateText}>{item.vendorInfo.rate}</Text>
                  <AntDesign name="star" size={18} color="#262626" />
                </View>
              </View>
              <View style={styles.socialContainer}>
                <View
                  style={{
                    width: 32,
                    height: 32,
                    backgroundColor: '#000',
                    borderRadius: 5,
                  }}
                />
              </View>
            </View>
          </View>
          <View style={styles.footer}>
            <Text style={styles.serviceName}>
             
                {item.serviceName}
            </Text>
            <Text style={styles.price}>
              {item.price}
            </Text>
          </View>

// this will appeared when pressed to card "Footer Card"
          <View>
            <View style={styles.line} />
            <View style={styles.editFooter}>
              <View style={styles.dateContainer}>
                <MemoCalender
                  style={styles.calenderIcon}
                  size={26}
                  color="#000"
                />
                <View style={styles.dateBox}>
                  <Text style={styles.dateText}>{item.date}</Text>
                  <Text style={styles.dateText}>{item.time}</Text>
                </View>
              </View>
             
            </View>
          </View>
        </Animated.View>
      </TouchableOpacity>
    );
  };


return(
<>
        {Data.opened.map((item, index) => renderItems(item, index))}
</>
);
}

标签: javascriptreactjsreact-nativeanimationlayout-animation

解决方案


改变这个:

<Animated.View
  style={[
    styles.itemContainer,
    {
      height: cardHeight,
    },
  ]
>
{...}
</Animated.View>

经过

<Animated.View
  style={[
    styles.itemContainer,
    {
      height: currentIndex === index ? cardHeight : 140,
    },
  ]
>
{...}
</Animated.View>

如果您想提高效率,请使用卡片的默认高度,将其定义为常量(例如:const = DEFAULT_CARD_HEIGHT = 140)并在使用 140 作为卡片高度的任何地方使用此常量


推荐阅读