Problem
- Need to show more, expandable, calculate view before see it on view
Solution
-
Step 1: calculate item before animate it
- set position to absolute.
- set opacity to 0.
- set measured=1 and cache it
Step 2: use react-native-animatable to animate item
import * as Animatable from 'react-native-animatable';
import React, {useState} from 'react';
import {Pressable, Text, TextStyle, View, ViewStyle} from 'react-native';
export const ShowMoreDemo = () => {
return (
<View>
<Text>Parent Content 1</Text>
<ShowMore>
<Text>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quisquam rem
ducimus sit ipsa eligendi, beatae tempora ullam obcaecati at ab
consectetur ea eveniet labore non quod fugiat itaque facilis fuga?
</Text>
</ShowMore>
<Text>Parent Content 2</Text>
</View>
);
};
const ShowMore: React.FC = ({children}) => {
// const minHeight = 300;
const [isShowMore, setIsShowMore] = useState(false);
const [measured, setMeasured] = useState(false);
const [contentHeight, setContentHeight] = useState(0);
const [contentStyle, setContentStyle] = useState<ViewStyle>({
opacity: 0,
position: 'absolute',
});
console.log('measured', measured, contentHeight);
return (
<>
<View
style={contentStyle}
onLayout={e => {
if (!measured) {
setContentHeight(e.nativeEvent.layout.height);
setMeasured(true);
}
}}>
{!measured ? (
children
) : (
<Animatable.View
style={
{
backgroundColor: 'red',
height: isShowMore ? contentHeight : 0,
opacity: isShowMore ? 1 : 0,
} as ViewStyle
}
duration={300}
transition={['height', 'opacity']}>
{children}
</Animatable.View>
)}
</View>
<Pressable
style={
{
height: 48,
justifyContent: 'center',
alignItems: 'center',
} as ViewStyle
}
onPress={() => {
setIsShowMore(!isShowMore);
setContentStyle({
opacity: 1,
position: 'relative',
});
}}>
<Text
style={
{
color: '#000',
fontSize: 12,
fontWeight: 'bold',
} as TextStyle
}>
{isShowMore ? 'Show Less' : 'Show More'}
</Text>
</Pressable>
</>
);
};
Top comments (0)