Я пытаюсь использовать Animated
API от react-native
.Я хочу сделать компонент, который выглядит как аккордеон (это ради попытки 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
, иногда оно показывает другое значение.Как это могло произойти?