gpt4 book ai didi

react-native - 当状态/ Prop 改变时, react native 动画部分列表跳到顶部

转载 作者:行者123 更新时间:2023-12-05 05:10:45 27 4
gpt4 key购买 nike

我正在使用部分列表组件在 React native 应用程序中构建一个 View ,它上面还有一个标题,它将显示有关列表的聚合数据。当您滚动时,标题 View 应该随着动画缩小。我的所有动画都运行良好,但是使用 onEndreached 添加无限滚动时会出现问题支柱。当添加新数据或状态/ Prop 更改时,它会跳到列表顶部。

为了使 SectionList 具有动画效果,我使用 Animated.createAnimatedComponent 将其包裹起来创建一个 <AnimatedSectionList />零件。当它被 Animated 包裹时,问题就出现了。

在下面链接的 gif 中,您可以看到当我向下滚动时它会跳到列表的顶部。这是状态发生变化并且我们开始获取更多数据的时候。 https://monosnap.com/file/2aH5iPF2XcygEz381bpHW9QGPGHA2Z

我试过使用 getItemLayout计算列表大小希望因为我读到当 react 不知道列表的高度时,它可能会跳动。

我还尝试使用 scrollTo 加载新数据后滚动到某个部分但这也不管用。我是用 componentDidUpdate 做的生命周期方法,但是 componentDidUpdate当新数据进来时,并没有被一致地调用。

这是我的代码。


const DataItem = [
{ name: "test name", value: "testvalue" },
{ name: "test name", value: "testvalue" },
{ name: "test name", value: "testvalue" },
{ name: "test name", value: "testvalue" },
{ name: "test name", value: "testvalue" }
];

const initialSections = [
{ title: "MY DETAILS", data: DataItem },
{ title: "MY COMMUNITY", data: DataItem },
{ title: "MY FAMILY", data: DataItem }
];

const styles = {
item: {
flex: 1,
height: 50,
marginTop: 1,
backgroundColor: "#dddddd"
},
sectionHeader: {
flex: 1,
height: 20,
marginTop: 1,
backgroundColor: "#00ff00"
}
};



class Edit extends Component {
constructor(props) {
super(props);

this.state = {
scrollEnabled: true,
scrollY: new Animated.Value(0),
sections: initialSections,
refreshing: false
};


_renderSectionHeader(section) {
return (
<View style={styles.sectionHeader}>
<Text> {section.title} </Text>
</View>
);
}

_renderItem(item) {
return (
<View style={styles.item}>
<Text>{item.name}</Text>
</View>
);
}


handleStateButton() {
this.setState({ refreshing: true });
}

fetchMoreData() {
this.setState({ refreshing: true });

const newData = [...this.state.sections, ...initialSections];

setTimeout(
function() {
this.setState({ sections: newData, refreshing: false }); }.bind(this),
2000
);
}

render() {
const backgroundScrollY = this.state.scrollY.interpolate({
inputRange: [0, 224],
outputRange: [0, -50],
extrapolate: "clamp"
});

const backgroundScrollHeight = this.state.scrollY.interpolate({
inputRange: [0, 224],
outputRange: [1, 0.75],
extrapolate: "clamp"
});

const listScrollY = this.state.scrollY.interpolate({
inputRange: [0, 224],
outputRange: [0, -10],
extrapolate: "clamp"
});

const infoOpacity = this.state.scrollY.interpolate({
inputRange: [0, 0.5, 150],
outputRange: [1, 1, 0],
extrapolate: "clamp"
});

const AnimatedSectionList = Animated.createAnimatedComponent(SectionList);

return (
<View
style={{
flex: 1,
// alignItems: "flex-start",
flexDirection: "column"
}}
>
<Animated.View
style={[
{
position: "relative",
// flex: 1,
// alignSelf: "flex-start",
top: 0,
minHeight: 200,
height: 300,
backgroundColor: "#ddee99",
border: "1px solid #0000FF",
justifyContent: "center",
alignItems: "center"
},
{ transform: [{ scaleY: backgroundScrollHeight }] }
]}
>
<Animated.Image
source={{
uri:
"https://images.unsplash.com/photo-1558901591-3a5f333830dd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80"
}}
style={[
{ position: "absolute", backgroundColor: "#cccccc" },
{ transform: [{ translateY: backgroundScrollY }] }
]}
blurRadius={1.5}
/>

<Text>{this.state.refreshing && `Fetching data`}</Text>

<Button onPress={this.fetchMoreData} title="Get More Data" />
<Button onPress={this.handleStateButton} title="Changing State" />
</Animated.View>

<AnimatedSectionList
ref={ref => (this.sectionListRef = ref)}
bounces={false}
scrollEnabled={this.state.scrollEnabled}
style={[
{ position: "relative" },
{ transform: [{ translateY: listScrollY }] }
]}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
{ listener: this._onScroll.bind(this) }
)}
sections={this.state.sections}
renderSectionHeader={({ section }) =>
this._renderSectionHeader(section)
}
ListHeaderComponent={() => (
<View
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
height: 40,
backgroundColor: "#ff00ff"
}}
>
<Text>List Header</Text>
</View>
)}
ListFooterComponent={() => (
<View
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
height: 80,
backgroundColor: "#FF0"
}}
>
<Text>List Footer</Text>
</View>
)}
getItemLayout={this.getItemLayout}
renderItem={({ item }) => this._renderItem(item)}
keyExtractor={(item, index) => index}
stickySectionHeadersEnabled={true}
onEndReachedThreshold={0.75}
onEndReached={d => {
this.fetchMoreData();
}}
/>
</View>
);
}
}


我希望当 state 或 props 发生变化时,列表会保持在当前滚动位置,但相反,它会跳到顶部,从而破坏无限滚动的目的。

如果您对解决此问题的最佳方式有任何想法,我们将不胜感激。

最佳答案

我把

const AnimatedSectionList = Animated.createAnimatedComponent(SectionList);

离开了类(class),停止了跳级

关于react-native - 当状态/ Prop 改变时, react native 动画部分列表跳到顶部,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56334026/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com