我如何处理 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 是展开视图。如果没有乱码和使用第三方,那将是简单而直接的
代码非常简单,我正在使用 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 是展开视图。如果没有乱码和使用第三方,那将是简单而直接的