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)