callstack / react-native-pager-view

React Native wrapper for the Android ViewPager and iOS UIPageViewController.
MIT License
2.72k stars 418 forks source link

Automatic height from children? #386

Closed joaomarceloods closed 3 years ago

joaomarceloods commented 3 years ago

Ask your Question

Hi, can PagerView get its height from its children? This is the use case:

So, the wider the screen, the taller the image. A height of 360p for the PagerView works for iPhone 12 Mini, but it's not enough on iPhone 12 Pro Max. So, can PagerView get its height from its children somehow? Demo:

Screen Shot 2021-07-11 at 18 02 02
troZee commented 3 years ago

Hey, Below you can find a code snippet

import PagerView from 'react-native-pager-view';
import React from 'react';
import { ScrollView, View, Image, StyleSheet, Animated } from 'react-native';
import { NavigationPanel } from './component/NavigationPanel';
import { useNavigationPanel } from './hook/useNavigationPanel';

const AnimatedPagerView = Animated.createAnimatedComponent(PagerView);

export const ScrollablePagerViewExample = (): JSX.Element => {
  const { ref, ...navigationPanel } = useNavigationPanel();
  const [height, setHeight] = React.useState(0);

  return (
    <>
      <ScrollView style={styles.flex}>
        {navigationPanel.pages.map(({ key }) => (
          <AnimatedPagerView
            {...navigationPanel}
            ref={ref}
            key={key}
            style={{ height: height }}
          >
            {navigationPanel.pages.map((page) => (
              <View key={`${key}+${page.key}`} style={styles.content}>
                <View
                  onLayout={(e) => {
                    setHeight(e.nativeEvent.layout.height);
                  }}
                  style={{
                    width: '100%',
                    height: 150,
                    marginVertical: 16,
                  }}
                >
                  <Image style={styles.flex} source={page.imgSource} />
                </View>
              </View>
            ))}
          </AnimatedPagerView>
        ))}
      </ScrollView>
      <NavigationPanel {...navigationPanel} />
    </>
  );
};

const styles = StyleSheet.create({
  flex: {
    flex: 1,
  },
  content: {
    flex: 1,
    marginVertical: 10,
  },
});
pelaxa commented 3 years ago

This works if you are creating the child nodes, but what if the children are passed in as props.children? how to set the height then?

troZee commented 3 years ago

This works if you are creating the child nodes, but what if the children are passed in as props.children? how to set the height then?

<View
   onLayout={(e) => {
     setHeight(e.nativeEvent.layout.height);
   }}
 >
   {props.children}
 </View>
pelaxa commented 3 years ago

Thank you but onLayout always return a height of 0. even when I explicityly set height on the children, it still gets a height of 0.

     <PagerView
        ref={ref}
        pageMargin={10}
        initialPage={state.selectedPage}
        onPageSelected={pageSelected}
        style={{ height: height }}>
        {props.children.map((page, idx) => {
          return (
            <View
              key={`pnPagerView_${idx}`}
              onLayout={e => {
                console.log(`inner view ${idx}`, e.nativeEvent.layout);
                if (height < e.nativeEvent.layout.height) {
                  setHeight(e.nativeEvent.layout.height);
                }
              }}>
              {page}
            </View>
          );
        })}
      </PagerView>
 LOG  inner view 2 {"height": 0, "width": 360, "x": 0, "y": 0}
 LOG  inner view 0 {"height": 0, "width": 360, "x": 0, "y": 0}
 LOG  inner view 1 {"height": 0, "width": 360, "x": 0, "y": 0}
pelaxa commented 3 years ago

For anyone else that comes across this. I had to clone each page and add a style={paddingTop: 1} to get this to work as I expected.

fukemy commented 1 year ago

hi @pelaxa , can u provide more information, where you adding paddingTop? THanks

pelaxa commented 1 year ago

@fukemy this was a while back and I do not recall exactly. I moved away from using this module and used a scrollview instead.

fukemy commented 1 year ago

thanks, i gave up too

matrunchyk commented 6 months ago

Hi, thank you for you library! Any chance it can be fixed without using the height hack? :)