react-native-collapsible
react-native-collapsible copied to clipboard
How to scroll to perticular header when it is out of screen on expand or collasped.
I am using Accordion to render list of section. I have many section and each has different height, it is working like: At a time any one section will expanded, if i click any other section the it will be expanded and rest of will be collapsed.
I am facing one issue: That is screen jumping issue:
Suppose i have first section having long content area which take more than a screen. and now by keeping first section expanded i will scroll up to second section and tap on it. then first section will collapsed and second will be expanded, beacuse first section has large content and when it is collapsed then second section will scroll up(goes up out of screen beacuse large area of first section has been collapsed)
Now how can i scroll to particular section programatically or is there any way to scroll that section in screen view port.??
Here is GIF
Any idea, helppp?
The same problem here :3 waiting for some answer :3
Put your content in ScrollView Like this
<ScrollView>
<Accordion
sections={SECTIONS}
renderHeader={this._renderHeader.bind(this)}
renderContent={this._renderContent.bind(this)}
/>
</ScrollView>
@karenYerevan: Thanks for response but i had already accordion inside scrollview. Have you able to understand my issue from gif that i have provided?
As far as I know the library doesn't have this functionality built in. I'm just a maintainer on the project not the owner. But it does sound like a nice feature to have. Any ideas?
@jzhw0130 No not able to find exact solution. but i did bit of hack.
How i hacked At a time any one of the section of accordion can be expanded and other will collapsed automatically, so i had store each section screen position at render time(at this time all section will be collapsed). so when i click on particular section then i scroll up to stored location for that section.
About your solution
_renderContent = (section, index) => { return ( <TouchableWithoutFeedback> <View} ... </View> </TouchableWithoutFeedback> ); }
Can you describe how it will fix issue. Will help other folks as well to get and idea.
@jzhw0130 Link not accesable
@jariwalabhavesh
@jzhw0130 Thanks, will try it
@jariwalabhavesh Can you provide the solution when added collapsible in scrollview, I want to solution as your GIF.
i just do not get it , what can touchablewithoutfeedback do to fix the issue? @jariwalabhavesh @jzhw0130
the way i hack it is alittle bit different
i use scrollToEnd
which i detect if the section is the last section or not, if it is true then i will call the method of ScrollView
to scroll to the bottom so it will automatically show the last content. for the rest,
i use the this trick. you know that accordion can return the position of section in scrollview. i use that position to multiply it with the height of the header. so everytime the header is touched. if it is not the last item then it scroll to the multiplied height. it works like charm..
it is not that perfect yet though
Any update on this?
@koswarabilly Hey, can you provide your code? this is what I trying to achieve but so far no luck :/ . thank you very much
@jariwalabhavesh doesn't got it to work with your solution. And the link you posted above (https://drive.google.com/open?id=1Atyn5YRpSHW63sEYxLvgXK9GtvhtXOhx) is protected (no permission to show the file)
@jariwalabhavesh did you get it to work? If yes, how?
@xstable I think solution was provided by @jzhw0130 and link was also shared by him. And i was also not able to get that solution work in my app as well
I have the same Issue like you in your gif. @jzhw0130 Seems only to solve the issue, that the very last entry wouldn't scroll down to the lower bottom
But what I need to solve is that if you open an Accordion with much content, scroll down and open one with few content, the List doesn't scroll the current activated item into view.
@jariwalabhavesh could you show you're hack (to store positions on render time: https://github.com/oblador/react-native-collapsible/issues/86#issuecomment-344169995)
@xstable : I was just tracking render position of each header and storing it. And whenever any header click then i scroll up to it's position.
renderHeader Component
class AccordionHeader extends Component {
setNativeProps(props) {
const { section } = this.props;
this.refs[`COMMON_THREAD_ROW${section.title}`].setNativeProps(props)
}
componentDidMount() {
let { section, i, isActive, setPositionCb } = this.props;
let self = this;
let refName = `COMMON_THREAD_ROW${section.title}`;
setTimeout(() => {
this.refs[refName].measure((fx, fy, width, height, px, py) => {
setPositionCb(i, { width, height, fx, fy, px, py })
})
}, 0);
}
render() {
let { section } = this.props;
return (
<View style={[styles.header, customStyles.header]} ref={`COMMON_THREAD_ROW${section.title}`}>
{/* other stuff */}
</View>
)
}
}
Main Component
class AppTabs extends Component {
constructor(props) {
super(props);
this.state = {
sectionPositions: []
}
this.onChange = this.onChange.bind(this);
this.setPosition = this.setPosition.bind(this);
}
onChange(index) {
let { sectionPositions } = this.state;
let activeSectionPostion = sectionPositions[index];
let py = (activeSectionPostion.py) ? (activeSectionPostion.py) - 50 : 0;
if (scrollToPosition) {
scrollToPosition(0, py, true);
}
}
setPosition(i, positionObj) {
let avalPosition = this.state.sectionPositions;
avalPosition[i] = positionObj;
this.setState({
sectionPositions: avalPosition
})
}
render() {
let { sections } = this.state;
const _renderContent = (section) => {
if (!section.view) { return null }
return (
<View style={styles.content}>
{section.view}
</View>
);
}
return (
<Accordion
sections={sections}
renderHeader={(section, key, active) => {
return <AccordionHeader section={section} i={key} isActive={active} setPositionCb={this.setPosition}/>
}}
renderContent={_renderContent}
onChange={this.onChange}
/>
)
}
}
Please take a look to above code, May be it may help you, It is not exact solution it is hack and sometimes you fill that header are jumping little bit.
@jariwalabhavesh thanks a lot, but I got an error:
undefned is not a function (evaluating '_this2.refs[refName].measure')
You have a clue why measuring not work?
@oblador Is the work for this bug in progress? Would really be great if you could fix this in the main-core so that no workaround is needed.
@xstable It was working fine on my app. but i am using bit older version that is RN 36, I think you should try reference callback instead providing ref name like.
<View style={[styles.header, customStyles.header]} ref={(ref) => this.refArray = ref}
{/* other stuff */}
</View>
Not sure it will work or not i haven't tried it.
@jariwalabhavesh Same error, doesn't work.
Is there an update on this that works with the Acccordion component out of the box? I'd like to avoid a load of extra boilerplate to make it work within a ScrollView. ScrollView has some memory performance issues as well as mentioned in the RN docs.
I got this working by updating the Accordion.js render method with this :
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={containerStyle} {...viewProps}>
{...}
</ScrollView>
it would be cool to be able de customise the container via props, what do you think ? maybe a containerComponent or something
here is my fork : https://github.com/maieonbrix/react-native-collapsible
Solved
1.Just get the active section number in onChange method 2.create variable for 'y' position by multiplying that(active section number) according to the header height 3.scrollTo new 'y' position when onChange happening
<ScrollView ref={(ref) => this.myScroll = ref}> <Accordion sections={SECTIONS} activeSections={this.state.activeSections} renderHeader={this._renderHeader} renderContent={this._renderContent} onChange={this._updateSections} /> </ScrollView>
_updateSections = activeSections => { this.setState({ activeSections }); if (!activeSections.length == 0) { let fy = activeSections * 45 this.myScroll.scrollTo({x: 0, y: fy, animated: true}) } };
Feature coming soon. Here’s a demo:
@iRoachie : Awesome, I will wait for that.
Doing a rewrite of the library to use Flatlist under the hood. Doing stuff like this will be possible now.
Doing a rewrite of the library to use Flatlist under the hood. Doing stuff like this will be possible now.
@iRoachie did the rewritten library available yet? or is it still ongoing?
Still ongoing, unfortunately. Problem I have now is resizing when data inside updates.
Also looking for this to avoid extra boilerplate. Thanks for working on it @iRoachie!
Hi all, How to expand first element. using import AccordionCollapsible from 'react-native-collapsible/Accordion'; <AccordionCollapsible
expandMultiple={true}
sections={dataList}
underlayColor={'transparent'}
activeSections={this.state.activeSections}
renderHeader={this._renderHeader}
renderContent={this._renderContent}
onChange={this._updateSections}
style={userResponsibilitiesStyles.accordianStyle}
/>