Open vijay-dadhich09 opened 6 years ago
You can put the Accordion
component inside a ScrollView
and capture the ScrollView
's onContentSizeChange
event to get the full height of your Accordion
.
i.e:
<ScrollView onContentSizeChange={(width, height) => console.log(width, height)}>
<Accordion
activeSection={this.state.activeSection}
sections={this.props.sections}
renderHeader={this._renderHeader}
renderContent={this._renderContent}
/>
</ScrollView>
When the activeSection
changes (show/hide content) it fires the onContentSizeChange
where you can get the width
and height
of your Accordion
.
Hey @vijay-dadhich09 sorry for late follow up. What's your use case for this behavior? What are you trying to achieve by getting the expanded height?
Hi iRoachie thanks for the reply. Actually, I have number of accordions in a scrollview component and the requirement is to scroll up bottom positions accordions after expend because when user clicks on the bottom accordion the expended area not showing in the scroll view that need to scroll up according to expended height. So, I think I need two things one is expended height and other things is current y position of the clicked accordion. If I can get both of the values then I can build my logic to scroll up scrollView. Hope you get the requirement.
Maybe dupe of #86?
Ho sir #86? is not related to my issue. I make it thinks more simple. How to ScrollToTop expended accordion. As soon as expend a accordion it move to top of the scrollView.
Sorry for late reply, Does @JoseVf solution work for you?
Hi, @iRoachie! I think I have the same problem as @vijay-dadhich09, so I could say that #86 is not a solution. An example: We have an Accordion with 5 sections. The 4th section, in fact, is an Accordion itself. In this case, when we expand a section of this last accordion, some content doesn't appear. I think that it happends because the sections of the secondary accordion is hiden under the 5th section, which doesn't move down.
How we can see, in the third image bellow, SIGNATURE 2
disappears (by the way there is more content to show when tapping SIGNATURE 1
)
SIGNATURES
is the last section (5th section of the outer Accordion in the example above).(first view)
(showing sections of the 4th section accordion)
(some content disappears "under" the next section of the outer accordion)
Use flatlist inside accordion to solve the issue. Flatlist will automatically generate scroll view when new content is added to it..
If you need full height of a flat list inside accordion view then you have to re-render the accordion view.Using accordion with react-native-collapsible will not dynamically change its content height.Insted a scroll view will appear.I solved it by setting a flag and re-rendering the view of accordion.
This is my flatlist.
<FlatList
data={section.content}
renderItem={this.renderItem}
extraData={this.state.refresh}
ListEmptyComponent={this.ListEmptyView}
/>
I re-rendered my accordion view like this when i add new content to flatlist.
{this.state.refresh ? (
<View style={styles.flatlistMainContainer}>
<Accordion
sections={this.state.accordionArray}
activeSections={this.state.activeSections}
renderHeader={this.renderAccordionHeader}
renderContent={this.renderAccordionItem}
onChange={this._updateSections}
touchableComponent={TouchableOpacity}
/>
</View>
) : null}
When i make any change in its content dynamically i will set the flag as :
this.setState({ refresh: false }, () => {
this.setState({ refresh: true });
});
By doing like this component refresh its content height.
`import React, { useEffect, useRef, useState } from 'react'; import { Animated, ScrollView, StyleSheet, View } from 'react-native'; import { Text } from 'react-native-paper'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import { TouchableOpacity } from 'react-native'; import theme from '../../styles/theme';
type Props = { title: string; count: number; isExpanded: boolean; onToggle: () => void; renderBadge: (value: number) => React.ReactNode; children: React.ReactNode; };
const Accordion = ({ title, count, children, renderBadge, isExpanded, onToggle }: Props) => { const [collapsableHeight, setCollapsableHeight] = useState(0); const animatedController = useRef(new Animated.Value(0)).current;
const bodyHeight = animatedController.interpolate({
inputRange: [0, 1],
outputRange: [0, collapsableHeight],
});
const handleOnContentSizeChange = (width: number, height: number) => {
setCollapsableHeight(height);
};
useEffect(() => {
Animated.timing(animatedController, {
duration: 400,
toValue: isExpanded ? 1 : 0,
useNativeDriver: false,
}).start();
}, [isExpanded]);
return (
<View>
<View style={styles.container}>
<TouchableOpacity activeOpacity={0.7} onPress={onToggle} style={styles.header}>
<View style={styles.headerContent}>
{renderBadge(count)}
<Text style={styles.title}>{title}</Text>
</View>
<MaterialCommunityIcons
name={isExpanded ? "chevron-up" : "chevron-down"}
size={24}
color="#1976D2"
/>
</TouchableOpacity>
</View>
<Animated.View style={[styles.body, { maxHeight: bodyHeight }]}>
<ScrollView onContentSizeChange={handleOnContentSizeChange}>
{children}
</ScrollView>
</Animated.View>
</View>
);
};
const styles = StyleSheet.create({ container: { borderBottomWidth: 1, borderColor: 'lightgray', marginRight: 16, marginLeft: 16, }, header: { minHeight: 41, backgroundColor: 'white', borderRadius: 4, flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, headerContent: { flexDirection: 'row', alignItems: 'center', }, title: { fontSize: 14, fontWeight: '600', fontFamily: theme.Roboto }, count: { fontSize: 18, fontWeight: '500', marginLeft: 10, }, body: { backgroundColor: 'white', borderRadius: 4, overflow: 'hidden', }, });
export default Accordion; `
This is my custom animated Accordion. Please use this to avoid third party integration 😎
Hi How can i get expended height of the accordion when tap on the header. I am trying to get using onChange but it only return index.