我尝试使用Animated
中的react-native
API。我想制作一个看起来像手风琴的组件(这是为了尝试Animated
API。我知道我可以使用其他手风琴库)。动画有效,但是toValue
不会随着内部内容的高度而扩展。到目前为止,这是我尝试过的操作:
Child.js
import React, { Component } from 'react';
import {
Animated,
View,
} from 'react-native';
class Child extends Component {
constructor(props) {
super(props);
this.state = {
expanded: false,
animation: null,
maxHeight: '',
minHeight: '',
};
}
toggle = () => {
const {
expanded, maxHeight, minHeight,
} = this.state;
const initialValue = expanded ? maxHeight + minHeight : minHeight;
const finalValue = expanded ? minHeight : maxHeight + minHeight;
this.setState(prevState => ({
expanded: !prevState.expanded,
}));
this.state.animation.setValue(initialValue);
Animated.spring(
this.state.animation,
{
toValue: finalValue,
bounciness: 0,
},
).start();
}
setMinHeight = (e) => {
this.setState({
minHeight: e.nativeEvent.layout.height,
animation: new Animated.Value(e.nativeEvent.layout.height),
});
}
setMaxHeight = (e) => {
this.setState({
maxHeight: e.nativeEvent.layout.height,
});
}
render() {
const { header, content } = this.props;
const { animation } = this.state;
return (
<Animated.View style={{
height: animation,
overflow: 'hidden',
width: '100%',
}}
>
<View onLayout={e => this.setMinHeight(e)}>
{header}
</View>
<View onLayout={e => this.setMaxHeight(e)}>
{content}
</View>
</Animated.View>
);
}
}
export default Child;
App.js
import React, { Component, Fragment } from 'react';
import {
ScrollView,
View,
Text,
StyleSheet,
Button,
} from 'react-native';
import { Row } from 'react-native-easy-grid';
// You can import from local files
import Child from './components/Child';
export default class App extends React.Component {
render() {
const header = (
<Button
title="press"
onPress={() => this.toggle.toggle()}
/>
);
const content = (
<Fragment>
<View
style={{
width: 300,
backgroundColor: 'green',
padding: 20,
}}
>
<View style={{ width: 'auto', padding: 10, backgroundColor: 'blue' }}>
<Text>Content1</Text>
<Text>Content2</Text>
<Text>Content3</Text>
// Please try to add more text here
</View>
</View>
</Fragment>
);
return (
<Fragment>
<ScrollView style={[styles.container]}>
<Row style={{ marginTop: 30 }}>
<View style={[styles.view]}>
<Child
content={content}
header={header}
ref={(ref) => { this.toggle = ref; }}
/>
</View>
</Row>
</ScrollView>
</Fragment>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 15,
backgroundColor: 'purple',
},
view: {
flex: 1,
backgroundColor: 'pink',
},
});
我在这里想念什么?任何帮助都将非常有帮助和赞赏。谢谢!
更新
当我尝试将console.log(e.nativeEvent.layout.height)
放在setMaxHeight
内时,有时会显示不同的值。这怎么可能发生?
答案 0 :(得分:0)
正如@hardworker在评论中所说,因此我尝试将验证放在maxHeight和minHeight的setState之前。为了防止在初始渲染后maxHeight和minHeight的状态发生变化。这是工作代码:
setMinHeight = (e) => {
if(this.state.minHeight === '') {
this.setState({
minHeight: e.nativeEvent.layout.height,
animation: new Animated.Value(e.nativeEvent.layout.height),
});
}
}
setMaxHeight = (e) => {
if (this.state.maxHeight === '') {
this.setState({
maxHeight: e.nativeEvent.layout.height,
});
}
}