From 19fec3e40c4e406a4329047adeda11a6fafd6b0e Mon Sep 17 00:00:00 2001 From: devbelieve365 <49985143+devbelieve365@users.noreply.github.com> Date: Tue, 5 Nov 2019 10:25:39 +0700 Subject: [PATCH] animated view --- index.js | 108 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 69 insertions(+), 39 deletions(-) diff --git a/index.js b/index.js index d346387..47f6ad8 100644 --- a/index.js +++ b/index.js @@ -1,98 +1,125 @@ -import React from "react"; -import { StyleSheet, Text, View } from "react-native"; - +import React from 'react' +import { StyleSheet, Text, View, Animated } from 'react-native' +const VIEW_MORE_HEIGHT = 33; export default class ReadMore extends React.Component { state = { measured: false, shouldShowReadMore: false, - showAllText: false + showAllText: false, + fullHeight: 0, + height: new Animated.Value(0), + limitedHeight: 0, }; async componentDidMount() { - this._isMounted = true; - await nextFrameAsync(); + this._isMounted = true + await nextFrameAsync() if (!this._isMounted) { - return; + return } // Get the height of the text with no restriction on number of lines - const fullHeight = await measureHeightAsync(this._text); - this.setState({ measured: true }); - await nextFrameAsync(); + const fullHeight = await measureHeightAsync(this._text) + this.setState({measured: true}) + await nextFrameAsync() if (!this._isMounted) { - return; + return } // Get the height of the text now that number of lines has been set - const limitedHeight = await measureHeightAsync(this._text); - + const limitedHeight = await measureHeightAsync(this._text) if (fullHeight > limitedHeight) { + this.state.height.setValue(limitedHeight + VIEW_MORE_HEIGHT) this.setState({ shouldShowReadMore: true }, () => { - this.props.onReady && this.props.onReady(); - }); + this.props.onReady && this.props.onReady() + }) + this.setState({fullHeight: fullHeight + VIEW_MORE_HEIGHT, limitedHeight: limitedHeight + VIEW_MORE_HEIGHT}) } else { - this.props.onReady && this.props.onReady(); + this.props.onReady && this.props.onReady() } + } componentWillUnmount() { - this._isMounted = false; + this._isMounted = false } render() { - let { measured, showAllText } = this.state; - - let { numberOfLines } = this.props; + let { measured, shouldShowReadMore, limitedHeight, showAllText, height } = this.state + let { numberOfLines } = this.props return ( - + { - this._text = text; + this._text = text }} > {this.props.children} - - {this._maybeRenderReadMore()} - - ); + {shouldShowReadMore && + {this._maybeRenderReadMore()} + } + + ) } _handlePressReadMore = () => { - this.setState({ showAllText: true }); + this.setState( + { showAllText: true }, + () => { + Animated.spring( + this.state.height, + { + toValue: this.state.fullHeight + } + ).start(); + } + ) + + }; _handlePressReadLess = () => { - this.setState({ showAllText: false }); + this.setState( + { showAllText: false }, + () => { + Animated.spring( + this.state.height, + { + toValue: this.state.limitedHeight + } + ).start() + } + ) }; _maybeRenderReadMore() { - let { shouldShowReadMore, showAllText } = this.state; + let { shouldShowReadMore, showAllText } = this.state if (shouldShowReadMore && !showAllText) { if (this.props.renderTruncatedFooter) { - return this.props.renderTruncatedFooter(this._handlePressReadMore); + return this.props.renderTruncatedFooter(this._handlePressReadMore) } return ( Read more - ); + ) } else if (shouldShowReadMore && showAllText) { if (this.props.renderRevealedFooter) { - return this.props.renderRevealedFooter(this._handlePressReadLess); + return this.props.renderRevealedFooter(this._handlePressReadLess) } return ( Hide - ); + ) } } } @@ -100,18 +127,21 @@ export default class ReadMore extends React.Component { function measureHeightAsync(component) { return new Promise(resolve => { component.measure((x, y, w, h) => { - resolve(h); - }); - }); + resolve(h) + }) + }) } function nextFrameAsync() { - return new Promise(resolve => requestAnimationFrame(() => resolve())); + return new Promise(resolve => requestAnimationFrame(() => resolve())) } const styles = StyleSheet.create({ button: { - color: "#888", + color: '#888', marginTop: 5 + }, + readMore: { + height: VIEW_MORE_HEIGHT } -}); +})