我如何处理 onclick 以从 flatlist 项目展开单个元素

How do I handle the onclick to expand a single element from flatlist item

代码非常简单,我正在使用 react-native-collapsible,我需要处理 onclick 来展开我单击的单个项目而不是 flatlist 的每个元素,请不要为此建议手风琴组件,我不认为我需要一个新的组件来做这个。

这是一个包含在平面列表中的平面列表,可折叠是其中的一部分。

<FlatList
  extraData={this.state}
  data={this.state.displayDay} //{DataManager.FavoriteList[moment(this.state.selectedDate).format('YYYY-MM-DD')]}
  renderItem={({ item, index }) => {
    return (
      <View style={{ marginTop: hp("2%") }}>
        <TouchableOpacity
          style={{
            alignSelf: "center",
            width: wp("95.7%"),
            height: 75, //hp('10%'),
            backgroundColor: "#ffffff",
          }}
          onPress={() => this.toggleExpanded()}
        >
          <View
            style={{
              flex: 1,
              flexDirection: "row",
              justifyContent: "space-between",
            }}
          >
            <View style={{ flexDirection: "column", justifyContent: "center" }}>
              <Text
                numberOfLines={2}
                ellipsizeMode="tail"
                style={{
                  marginLeft: wp("5%"),
                  width: wp("55%"), //wp('38.2%'), //151
                  //height: hp('2%'), //19
                  fontSize: rfv(16),
                  fontWeight: "500",
                  fontStyle: "normal",
                  textAlign: "left",
                  color: "#707070",
                }}
              >
                {item.Title}
              </Text>
              <Text
                style={{
                  marginLeft: wp("5%"),
                  fontSize: rfv(14),
                  fontWeight: "normal",
                  fontStyle: "normal",
                  textAlign: "left",
                  color: "#c4c4c4",
                }}
              >{`ID ${item.Id} - ${item.Cliente}`}</Text>
              {!item.IsFavorite ? (
                <Text
                  style={{
                    marginLeft: wp("5%"),
                    fontSize: rfv(14),
                    fontWeight: "normal",
                    fontStyle: "italic",
                    textAlign: "left",
                    color: "#c4c4c4",
                  }}
                >
                  No favorito
                </Text>
              ) : null}
            </View>
            <View style={{ flexDirection: "column", justifyContent: "center" }}>
              <View style={{ flexDirection: "row", marginRight: wp("3.4%") }}>
                <Text
                  style={{
                    fontSize: rfv(18),
                    fontWeight: "300",
                    fontStyle: "normal",
                    textAlign: "right",
                    color: "#707070",
                  }}
                >{`${item.HorasTotales}h`}</Text>
                <Image
                  style={{ marginTop: hp("1%"), marginLeft: wp("3.7%") }}
                  source={
                    this.state.isCollapsed
                      ? Images.expandible
                      : Images.collapsible
                  }
                />
              </View>
            </View>
          </View>
        </TouchableOpacity>
        <Collapsible
          duration={100}
          style={{
            alignSelf: "center",
            width: wp("95.7%"),
            backgroundColor: "#ffffff",
          }}
          collapsed={this.state.isCollapsed}
        >
          <FlatList
            extraData={this.state}
            data={item.ListReportHistoryResponse} //{DataManager.FavoriteList[moment(this.state.selectedDate).format('YYYY-MM-DD')]}
            renderItem={({ item, index }) => {
              return (
                <View>
                  <View style={{ flexDirection: "row" }}>
                    <Text
                      style={{
                        marginLeft: wp("5%"),
                        fontSize: rfv(14),
                        fontWeight: "normal",
                        fontStyle: "normal",
                        textAlign: "left",
                        color: "#717171",
                      }}
                    >
                      Etapa
                    </Text>
                    <Text
                      style={{
                        marginLeft: wp("42.5%"),
                        fontSize: rfv(14),
                        fontWeight: "normal",
                        fontStyle: "normal",
                        textAlign: "left",
                        color: "#717171",
                      }}
                    >
                      Horas
                    </Text>
                  </View>
                  <View style={{ flexDirection: "row" }}>
                    <ModalDropdown
                      adjustFrame={(style) => {
                        style.top =
                          Platform.OS === "ios"
                            ? style.top
                            : style.top - StatusBar.currentHeight;
                        return style;
                      }}
                      dropdownTextStyle={styles.dropdownTextStyle}
                      dropdownTextHighlightStyle={
                        styles.dropdownTextHighlightStyle
                      }
                      dropdownStyle={styles.dropdownStageStyle}
                      defaultValue={item.Etapa}
                      style={styles.dropStageStyle}
                      textStyle={{
                        padding: 0,
                        margin: 0,
                        fontSize: rfv(16),
                        paddingVertical: hp("1.2%"),
                        fontWeight: "normal",
                        fontStyle: "normal",
                        textAlign: "left",
                        color:
                          item.Etapa /*item.ListReportHistoryResponse[index2].Etapa*/ !=
                          "Selecciona una etapa"
                            ? "#1a1a1a"
                            : "#c4c4c4",
                      }}
                      //onSelect={(index, value) => this.setState({SeleccionClientes: value})}
                      //options={Object.keys(this.state.items)}
                      onSelect={(index, value) =>
                        this.onSelectEtapaChange(index, value)
                      }
                      options={DataManager.ListEtapa}
                    />
                    <View style={styles.InputContainerHours}>
                      <Text style={styles.InputTextHours}>
                        {item.HorasTrabajadas}
                      </Text>
                    </View>
                    <TouchableOpacity
                      style={{ marginTop: hp("0.5%"), marginLeft: wp("5.5%") }}
                      onPress={() =>
                        this.onSubstractHourChange(index, item.HorasTrabajadas)
                      }
                    >
                      <Image source={Images.menos_hora} />
                    </TouchableOpacity>
                    <TouchableOpacity
                      style={{ marginTop: hp("0.5%"), marginLeft: wp("2%") }}
                      onPress={() =>
                        this.onAddHourChange(index, item.HorasTrabajadas)
                      }
                    >
                      <Image source={Images.mas_hora} />
                    </TouchableOpacity>
                  </View>
                  <Text
                    style={{
                      fontSize: rfv(14),
                      marginLeft: wp("5%"),
                      fontWeight: "normal",
                      fontStyle: "normal",
                      textAlign: "left",
                      color: "#717171",
                    }}
                  >
                    Observaciones
                  </Text>
                  <Input
                    autoCapitalize="none"
                    maxLength={100}
                    inputContainerStyle={styles.InputContainerComentarioOnBlur}
                    containerStyle={styles.InputComentario}
                    inputStyle={styles.InputTextHoursRInput}
                    placeholderTextColor={"#c4c4c4"}
                    placeholder="(Opcional)"
                    value={item.Title}
                    onChangeText={(value) =>
                      this.onTextObservacionesChange(index, value)
                    }
                  />
                  <TouchableOpacity
                    style={{ alignItems: "flex-end", alignSelf: "flex-end" }}
                    onPress={() => this.onAgregarEtapa(index, "")}
                  >
                    <Text
                      style={{
                        marginRight: wp("3.4%"),
                        marginBottom: hp("3%"),
                        fontSize: rfv(14),
                        fontWeight: "normal",
                        fontStyle: "normal",
                        textAlign: "left",
                        color: "#1062cc",
                      }}
                    >
                      Agregar etapa
                    </Text>
                  </TouchableOpacity>
                </View>
              );
            }}
          />
        </Collapsible>
      </View>
    );
  }}
/>

我认为你在这里犯了一个错误。您所有项目的折叠状态都基于 this.state.isCollapsed

所以这意味着,当你改变你的isCollapsed状态时,你在平面列表中的所有项目都会随之改变。

因此,我的建议是将诸如您的 onclick 项目的 id 置于状态中,并根据该 id 更改每个项目的折叠状态。

像这样:

<TouchableOpacity style={{
  alignSelf: 'center',
  width: wp('95.7%'),
  height: 75,//hp('10%'),
  backgroundColor: "#ffffff",
}} onPress={() => this.setState({clickedItem: item.id})}

那么你的项目在平面列表中

collapsed={this.state.clickedItem !== item.id}

希望有所帮助。

但是你不能根据状态渲染2个不同的视图吗??如果 collapsible 为真,则渲染 viewA else viewB,其中 viewA 是折叠视图,而 viewB 是展开视图。如果没有乱码和使用第三方,那将是简单而直接的