父组件高度动画为0时子组件不消失
The child component doesn't disappear when the height of the parent component is animated to 0
我想要一个下拉框,它可以通过 increase/decrease 在其框中出现和消失。目前它是通过增加高度来出现的,但是当高度降低时它不会消失。更具体地说,高度正在降低,但作为子组件的文本元素并没有消失。
屏幕组件:
import React, { useState } from 'react'
import {
View,
Text,
StyleSheet,
Dimensions,
ScrollView,
SafeAreaView,
} from 'react-native'
import Panel from '../components/help/Panel'
const { width } = Dimensions.get('window')
export default Help = () => {
return (
<SafeAreaView style={styles.container}>
<ScrollView contentContainerStyle={styles.scrollView}>
<Panel title="Question 1" >
<Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Text>
</Panel>
<Panel title="A Panel with long content text">
<Text>Lorem ipsum...</Text>
</Panel>
<Panel title="Another Panel">
<Text>Lorem ipsum dolor sit amet...</Text>
</Panel>
</ScrollView>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
width: width * .90,
alignSelf: 'center',
},
})
Panel.js
import React, { useState } from 'react'
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Animated,
} from 'react-native'
import { moderateScale } from 'react-native-size-matters'
import Icon from "react-native-vector-icons/AntDesign"
export default Panel = ({ title, children }) => {
const [isExpanded, expand] = useState(false)
const [minHeight, setMinHeight] = useState()
const [maxHeight, setMaxHeight] = useState()
const [animation] = useState(new Animated.Value(0))
const _setMinHeight = e => {
setMinHeight(e.nativeEvent.layout.height)
}
const _setMaxHeight = e => {
setMaxHeight(e.nativeEvent.layout.height)
}
const toggle = () => {
let initialValue = isExpanded ? maxHeight + minHeight : minHeight
let finalValue = isExpanded ? minHeight : maxHeight + minHeight
animation.setValue(initialValue)
Animated.spring(animation,{
toValue: finalValue,
duration: 1500,
}).start(() => {
expand(!isExpanded)
})
}
return (
<View style={[styles.container]}>
<TouchableOpacity
style={styles.questionContainer}
onLayout={_setMinHeight}
onPress={toggle}
>
<Text style={styles.questionText}>{title}</Text>
<Icon
name={isExpanded ? "caretup" : "caretdown"}
size={moderateScale(15)}
style={styles.icon}
/>
</TouchableOpacity>
<Animated.View
style={[styles.answerContainer, { height: animation }]}
onLayout={_setMaxHeight}
>
{children}
</Animated.View>
</View>
)
}
const styles = StyleSheet.create({
container : {
backgroundColor: '#fff',
margin:10,
},
questionContainer : {
flexDirection: 'row',
},
questionText: {
flex: 1,
padding: 10,
color:'#2a2f43',
fontWeight:'bold'
},
icon: {
paddingTop: 10,
},
answerContainer: {
padding: 10,
paddingTop: 0,
overflow:'hidden'
}
})
更新
实际上,高度是不可预测的,我不确定为什么。
我已经研究你的代码很长时间了
这个好一点
他的行为很奇怪,也许是因为他在以循环和不可控的方式更新状态
import React, {Component} from 'react';
import {Animated, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import Icon from 'react-native-vector-icons/index';
import {moderateScale} from 'react-native-size-matters';
export default class PanelClass extends Component {
constructor(props) {
super(props);
this.isExpanded = false;
this.animation = new Animated.Value(15);
}
toggle = () => {
let initialValue = this.isExpanded ? 50 : 15;
let finalValue = this.isExpanded ? 15 : 50;
this.animation.setValue(initialValue);
Animated.spring(this.animation, {
toValue: finalValue,
duration: 1000,
}).start(() => {
this.isExpanded = !this.isExpanded;
});
};
render() {
return (
<View style={[styles.container]}>
<TouchableOpacity
style={styles.questionContainer}
onPress={this.toggle}>
<Text style={styles.questionText}>
{this.props.title}
</Text>
<Icon
name={this.state.isExpanded ? 'caretup' : 'caretdown'}
size={moderateScale(15)}
style={styles.icon}
/>
</TouchableOpacity>
<Animated.View
style={[styles.answerContainer, {height: this.animation}]}
>
{this.props.children}
</Animated.View>
</View>
);
}
}
```
我想要一个下拉框,它可以通过 increase/decrease 在其框中出现和消失。目前它是通过增加高度来出现的,但是当高度降低时它不会消失。更具体地说,高度正在降低,但作为子组件的文本元素并没有消失。
屏幕组件:
import React, { useState } from 'react'
import {
View,
Text,
StyleSheet,
Dimensions,
ScrollView,
SafeAreaView,
} from 'react-native'
import Panel from '../components/help/Panel'
const { width } = Dimensions.get('window')
export default Help = () => {
return (
<SafeAreaView style={styles.container}>
<ScrollView contentContainerStyle={styles.scrollView}>
<Panel title="Question 1" >
<Text> Lorem ipsum dolor sit amet, consectetur adipiscing elit.</Text>
</Panel>
<Panel title="A Panel with long content text">
<Text>Lorem ipsum...</Text>
</Panel>
<Panel title="Another Panel">
<Text>Lorem ipsum dolor sit amet...</Text>
</Panel>
</ScrollView>
</SafeAreaView>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
width: width * .90,
alignSelf: 'center',
},
})
Panel.js
import React, { useState } from 'react'
import {
View,
Text,
StyleSheet,
TouchableOpacity,
Animated,
} from 'react-native'
import { moderateScale } from 'react-native-size-matters'
import Icon from "react-native-vector-icons/AntDesign"
export default Panel = ({ title, children }) => {
const [isExpanded, expand] = useState(false)
const [minHeight, setMinHeight] = useState()
const [maxHeight, setMaxHeight] = useState()
const [animation] = useState(new Animated.Value(0))
const _setMinHeight = e => {
setMinHeight(e.nativeEvent.layout.height)
}
const _setMaxHeight = e => {
setMaxHeight(e.nativeEvent.layout.height)
}
const toggle = () => {
let initialValue = isExpanded ? maxHeight + minHeight : minHeight
let finalValue = isExpanded ? minHeight : maxHeight + minHeight
animation.setValue(initialValue)
Animated.spring(animation,{
toValue: finalValue,
duration: 1500,
}).start(() => {
expand(!isExpanded)
})
}
return (
<View style={[styles.container]}>
<TouchableOpacity
style={styles.questionContainer}
onLayout={_setMinHeight}
onPress={toggle}
>
<Text style={styles.questionText}>{title}</Text>
<Icon
name={isExpanded ? "caretup" : "caretdown"}
size={moderateScale(15)}
style={styles.icon}
/>
</TouchableOpacity>
<Animated.View
style={[styles.answerContainer, { height: animation }]}
onLayout={_setMaxHeight}
>
{children}
</Animated.View>
</View>
)
}
const styles = StyleSheet.create({
container : {
backgroundColor: '#fff',
margin:10,
},
questionContainer : {
flexDirection: 'row',
},
questionText: {
flex: 1,
padding: 10,
color:'#2a2f43',
fontWeight:'bold'
},
icon: {
paddingTop: 10,
},
answerContainer: {
padding: 10,
paddingTop: 0,
overflow:'hidden'
}
})
更新
实际上,高度是不可预测的,我不确定为什么。
我已经研究你的代码很长时间了 这个好一点 他的行为很奇怪,也许是因为他在以循环和不可控的方式更新状态
import React, {Component} from 'react';
import {Animated, StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import Icon from 'react-native-vector-icons/index';
import {moderateScale} from 'react-native-size-matters';
export default class PanelClass extends Component {
constructor(props) {
super(props);
this.isExpanded = false;
this.animation = new Animated.Value(15);
}
toggle = () => {
let initialValue = this.isExpanded ? 50 : 15;
let finalValue = this.isExpanded ? 15 : 50;
this.animation.setValue(initialValue);
Animated.spring(this.animation, {
toValue: finalValue,
duration: 1000,
}).start(() => {
this.isExpanded = !this.isExpanded;
});
};
render() {
return (
<View style={[styles.container]}>
<TouchableOpacity
style={styles.questionContainer}
onPress={this.toggle}>
<Text style={styles.questionText}>
{this.props.title}
</Text>
<Icon
name={this.state.isExpanded ? 'caretup' : 'caretdown'}
size={moderateScale(15)}
style={styles.icon}
/>
</TouchableOpacity>
<Animated.View
style={[styles.answerContainer, {height: this.animation}]}
>
{this.props.children}
</Animated.View>
</View>
);
}
}
```