react-native-collapsible icon indicating copy to clipboard operation
react-native-collapsible copied to clipboard

Animated height starts at 0 when using collapsedHeight

Open booleanBoy opened this issue 6 years ago • 11 comments

Hello,

As you can see, when using a collapsedHeight and then toggling the collapsible state, the animation always starts at 0 before expanding. collapsibleissue

My code, if it's of interest:

<Collapsible collapsed={isCollapsed} align="top" collapsedHeight={55}>
  <style={styles.interactionWrapper}>
    <GraphNode 
      isFirst={isFirst} 
      isLast={isLast} 
      width={35} 
      height={50} 
      strokeWidth={2} 
      containerLength={containerLength} 
      issueLevel={issueLevel} 
      index={index} 
      isEmail={isEmail} 
      isLetter={isLetter} 
      isEvent={isEvent} 
    />
    <View style={styles.descriptionsWrapper}>
      <Text style={styles.collapsedHeader}>{item.subject}</Text>
      <Text style={[styles.reason]}>{followupDescription}</Text>
      <EmailInteractionDetails 
        item={item} 
        index={index} 
        threadId={threadId}
        entityName={entityName}
        issueLevel={issueLevel}
        showEmail={this.showEmail.bind(this)}
        interactionContextMenuHandler={this.interactionContextMenuHandler.bind(this)} 
        toggleFollowupIsCompleted={this.toggleFollowupIsCompleted.bind(this)}
      />
    </View>
  </View>
</Collapsible>

I've looked through the library code and failed to spot the problem. Frankly, if it was obvious I think more people would have reported it, so far I've only seen it reported in issue #125.

I'm on version 0.12.0 and RN 0.54.2.

Any thoughts? Thanks

booleanBoy avatar Jul 11 '18 12:07 booleanBoy

I am also having this issue. One really awkward workaround is setting the styles attribute height of the Collapsible component, but then you need to update the height every time the component is toggled. However, it ends up being slow, clunky and looking terrible, so a real solution would be great.

reaganmcf avatar Jul 12 '18 23:07 reaganmcf

I can't seem to replicate this issue. It's the second time I've seen someone bring it up, but I'm not sure how to fix cause can't reproduce. Would appreciate if you could reproduce it on https://snack.expo.io

iRoachie avatar Jul 22 '18 17:07 iRoachie

I think this problem exist in only android. iOS works well please fix this issue

yansfil avatar Oct 04 '18 15:10 yansfil

I'm having the same issue, have only tested on Android.

joel-bitar avatar Nov 27 '18 15:11 joel-bitar

@iRoachie Here is a snack to reproduce. Note that the bug only occurs on Android. https://snack.expo.io/@bennyb/collapsible-with-collapsedheight

joel-bitar avatar Nov 27 '18 15:11 joel-bitar

I'm also interested in a solution to this, we are experiencing the same issue on Android.

DaveVanVliet avatar Nov 30 '18 19:11 DaveVanVliet

@joel-bitar if you're overriding the collapsedHeight prop and you still want to be able to click inside the you have to use enablePointerEvents prop as well.

Same example you posted https://snack.expo.io/@roach_iam/collapsible-with-collapsedheight

iRoachie avatar Dec 05 '18 07:12 iRoachie

I have the same issue on Android when using collapsedHeight.

But doesn't it make sense? Just for my understanding: When it is measuring it sets the inner Animated.View to position: 'absolute' and at the same time the wrapping Animated.View doesn't get its style with the height value:

// the style won't be applied to the parent Animated.View during measure
const hasKnownHeight = !measuring && (measured || collapsed);
const style = hasKnownHeight && {
	overflow: 'hidden',
	height: height,
};

const contentStyle: StyleProp<ViewStyle> = {};

if (measuring) {
     // but here we the the inner child Animated.View to position absolute which takes it out of the flow
    contentStyle.position = 'absolute';
    contentStyle.opacity = 0;
} else if (this.props.align === 'center') {

// ...

So actually it has to flicker as the inner child Animated.View is set to position: absolute which takes it out of the layout flow and as we also don't apply the height value to the parent Animated.View it collapses to 0 height during the measuring frame and that causes the flicker. Actually I'm a little bit surprised it works on iOS. But maybe it is more luck than anything else, ... I don't know.

Because based on that I can fix the issue when I do the following (not tested on iOS yet):

  1. Always apply the style to the parent Animated.View, also during measure
  2. Always apply position: absolute to the inner Animated.View. (*)
  3. Disable the opacity: 0 value as it just supports flickering

So finally it would look like that

// 1. Always apply the style to the parent Animated.View
// const hasKnownHeight = !measuring && (measured || collapsed);
const style = {
	overflow: 'hidden',
	height: height, // height value regulates everything we need
};

const contentStyle: StyleProp<ViewStyle> = {};
contentStyle.position = 'absolute'; // 2. Always apply position: absolute

if (measuring) {
    contentStyle.position = 'absolute';
    // contentStyle.opacity = 0; // disable opacity: 0 during measure, as it just causes a visual flicker
} else if (this.props.align === 'center') {

// ...

Then it works.

New edge case: mounting But we have a small issue with this approach when collapsed = false initially as it flickers there once after mount as it doesn't has a proper height in the first frame after mount as it uses the collapsedHeight as the first height value till it measured the content and adjusted the value.

So we need some extra logic for that like measuring in componentDidMount and applying the proper height value and having an initial animation to open the view. (maybe not best idea?)

Or overcome it by doing it the same way how it is current applied till we have measured the content.

I don't have a final solution on that yet, but at least the following approach fixed the issue with the 0 height issue on Android for me in my first test.

(*) This also makes sure the inner content don't reflow when we change the height value.

mimamuh avatar Feb 12 '19 19:02 mimamuh

Hi there! Is there any PR addressing this issue? @booleanBoy did you find a solution?

zabojad avatar May 27 '19 11:05 zabojad

Did anyone solve this? I'm still seeing this issue on the latest release

jackdewhurst avatar Apr 21 '20 19:04 jackdewhurst

same bug, Is there any progress now?

liran avatar Aug 13 '20 00:08 liran