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

zIndex in FlatList

Open ShaMan123 opened this issue 4 years ago • 35 comments

Description

Related? #23614 #23615 Setting zIndex on items of a FlatList yields no result across different rows. However, it does work in the same row across it's columns if existing. I have tried using CellRenderComponent without success. This is crucial for dragging items in a list etc. I can confirm it is cross platform. See the snack below.

React Native version:

React Native version
System:
    OS: Windows 10 10.0.18362
    CPU: (4) x64 Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
    Memory: 2.84 GB / 7.87 GB
  Binaries:
    Node: 12.14.0 - C:\Users\DELL\AppData\Local\Temp\yarn--1587809387421-0.6934667812958264\node.CMD
    Yarn: 1.22.0 - C:\Users\DELL\AppData\Local\Temp\yarn--1587809387421-0.6934667812958264\yarn.CMD
    npm: 6.13.4 - C:\Program Files (x86)\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK:
      API Levels: 22, 23, 25, 26, 27, 28, 29
      Build Tools: 23.0.1, 23.0.3, 24.0.1, 26.0.2, 27.0.1, 27.0.3, 28.0.0, 28.0.3, 29.0.3, 30.0.0
      System Images: android-22 | Google APIs Intel x86 Atom, android-22 | Google APIs Intel x86 Atom_64, android-23 | Intel x86 Atom_64, android-23 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom_64, android-25 | Google APIs Intel x86 Atom, android-26 | Google APIs Intel x86 Atom_64, android-26 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-27 | Google Play Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-28 | Google APIs Intel x86 Atom_64, android-28 | Google Play Intel x86 Atom, android-28 | Google Play Intel x86 Atom_64, android-29 | Google APIs Intel x86 Atom, android-R | Google APIs Intel x86 Atom, android-R | Google Play Intel x86 Atom_64
      Android NDK: 17.2.4988734
  IDEs:
    Android Studio: Version  3.5.0.0 AI-191.8026.42.35.5791312
  Languages:
    Java: 1.8.0_172 - C:\Program Files\Java\jdk1.8.0_172\bin\javac.EXE
    Python: 3.6.5 - C:\Users\DELL\AppData\Local\Programs\Python\Python36-32\python.EXE
  npmPackages:
    @react-native-community/cli: Not Found
    react: ^16.13.0 => 16.13.1
    react-native: ^0.62.2 => 0.62.2
  npmGlobalPackages:
    *react-native*: Not Found
Done in 13.98s.

Steps To Reproduce

  1. Render a list of items with FlatList.
  2. Change items' position and zIndex so an item should render above other items placed after it in the list (descending zIndex).

Expected Results

zIndex should behave the same in FlatList items as it does in other view hierarchies. Meaning a greater value should result in rendering above other views.

Snack, code example, screenshot, or link to a repository:

https://snack.expo.io/VHjFLB_Dz

ShaMan123 avatar Apr 25 '20 10:04 ShaMan123

Check out how it behaves across rows/columns. zIndex works in the row but not across rows.

zindex

ShaMan123 avatar Apr 25 '20 10:04 ShaMan123

I got exact same issue. Any updates?

seunghyun-woo avatar May 18 '20 09:05 seunghyun-woo

Description

Related? #23614 #23615 Setting zIndex on items of a FlatList yields no result across different rows. However, it does work in the same row across it's columns if existing. I have tried using CellRenderComponent without success. This is crucial for dragging items in a list etc. I can confirm it is cross platform. See the snack below.

React Native version:

React Native version

Steps To Reproduce

  1. Render a list of items with FlatList.
  2. Change items' position and zIndex so an item should render above other items placed after it in the list (descending zIndex).

Expected Results

zIndex should behave the same in FlatList items as it does in other view hierarchies. Meaning a greater value should result in rendering above other views.

Snack, code example, screenshot, or link to a repository:

https://snack.expo.io/VHjFLB_Dz

BTW it's CellRendererComponent, not CellRenderComponent. This may solve your problem?

seunghyun-woo avatar Jun 08 '20 08:06 seunghyun-woo

https://github.com/facebook/react-native/issues/23392 Seems to be related (issue template is just a link).

In my case, I have an AutoComplete component within each rendered item that displays a list of items which should overlap the next list item below it. The issue appears to be that z-indexing is somehow backwards (each subsequent item is layered above the one before it) within the FlatList component and there's no way to override it because the rendered item isn't the row component.

You can see this visually by setting inverse={true} which was a bandaid for me to workaround this issue temporarily, at the cost of my list items now being shown backwards. By listing them backwards, the backwards z-index was effectively corrected.

Using React Native 0.61.4 (in case that helps)

jcargilo avatar Jun 24 '20 17:06 jcargilo

Hi,

I am having the same issue. (I am trying to implement a drag-and-drop sort FastList) Setting zIndex inside the renderItem function does not work.

I also tried to use CellRendererComponent and set the zIndex in the Wrapping component, but that would block my animations for some reason.

I finally made it work by making sure that CellRendererComponentis always the exact same instance of the function across re-renders.

Here is a simplified version of my code

  // make sure to use `.bind(this)` in the constructor or use auto binding. 
  renderCell = ({ index, style, ...props }) => {
	const { currentDragIndex } = this.state;
	const zIndex = {
      zIndex: index === currentDragIndex ? 2 : 0,
    };

    return <View style={[style, zIndex]} {...props} />;
  };

  render() {
    const {
      data,
    } = this.props;

    return (
      <FlatList
        data={data}
        // renderCell is always the same instance.
        CellRendererComponent={this.renderCell}
        // ...
      />
    );
  }

In a functional component, you would probably want to use useCallback.

Hope that helps

bboure avatar Aug 22 '20 13:08 bboure

Thanks for the issue @ShaMan123!

Have you tried @bboure's solution? Does it solve your case?

safaiyeh avatar Aug 23 '20 22:08 safaiyeh

Strangely enough on iOS the solution suggested by @bboure works. On android it has no effect. See updated snack with CellRendererComponent fix (thanks @seunghyun-woo) and useCallback.

ShaMan123 avatar Aug 29 '20 07:08 ShaMan123

Hi,

I am having the same issue. (I am trying to implement a drag-and-drop sort FastList) Setting zIndex inside the renderItem function does not work.

I also tried to use CellRendererComponent and set the zIndex in the Wrapping component, but that would block my animations for some reason.

I finally made it work by making sure that CellRendererComponentis always the exact same instance of the function across re-renders.

Here is a simplified version of my code

  // make sure to use `.bind(this)` in the constructor or use auto binding. 
  renderCell = ({ index, style, ...props }) => {
	const { currentDragIndex } = this.state;
	const zIndex = {
      zIndex: index === currentDragIndex ? 2 : 0,
    };

    return <View style={[style, zIndex]} {...props} />;
  };

  render() {
    const {
      data,
    } = this.props;

    return (
      <FlatList
        data={data}
        // renderCell is always the same instance.
        CellRendererComponent={this.renderCell}
        // ...
      />
    );
  }

In a functional component, you would probably want to use useCallback.

Hope that helps

when i was using this way to change my zIndex cause crash on android ? why ? please help, thank you The error say 'java.lang.ArrayIndexOutOfBoundsException: length=2; index=2'

Twelvefat avatar Sep 08 '20 04:09 Twelvefat

@Twelvefat A quick follow up on this. I too experienced crashing on Android with that solution. I ended up using a ScrollView instead 😞 It least a a temporary workaround.

bboure avatar Sep 08 '20 06:09 bboure

Having same issue. Can we expect a new workaround or a fix this year? it's been about 2 years now.

mmilvydas112 avatar Jan 08 '21 16:01 mmilvydas112

Just move ransform:[{translateY:200}] from greenBox style to redBox style and the result will be same in both Scroll and FlatList.. More over, there is absolutely no problem of zindex in FlashList within item and items across rows. I also have a line defined in one item stretching across items in rows.

ChiragMDave avatar Apr 18 '21 06:04 ChiragMDave

Description

Related? #23614 #23615 Setting zIndex on items of a FlatList yields no result across different rows. However, it does work in the same row across it's columns if existing. I have tried using CellRenderComponent without success. This is crucial for dragging items in a list etc. I can confirm it is cross platform. See the snack below.

React Native version:

React Native version

Steps To Reproduce

  1. Render a list of items with FlatList.
  2. Change items' position and zIndex so an item should render above other items placed after it in the list (descending zIndex).

Expected Results

zIndex should behave the same in FlatList items as it does in other view hierarchies. Meaning a greater value should result in rendering above other views.

Snack, code example, screenshot, or link to a repository:

https://snack.expo.io/VHjFLB_Dz

BTW it's CellRendererComponent, not CellRenderComponent. This may solve your problem?

Just move ransform:[{translateY:200}] from greenBox style to redBox style and the result will be same in both Scroll and FlatList.. More over, there is absolutely no problem of zindex in FlashList within item and items across rows. I also have a line defined in one item stretching across items in rows.

ChiragMDave avatar Apr 18 '21 06:04 ChiragMDave

#18616 (comment)

it will block the animation because you have to wait for next render

adamward459 avatar Dec 19 '21 05:12 adamward459

For anyone that had a crash on Android when using CellRendererComponent: This solution seems to be working, I hope performance won't take too big of a hit.

Couldn't make this workaround work on Android without also having removeClippedSubviews={false} explicitly set.

M-i-k-e-l avatar Mar 10 '22 11:03 M-i-k-e-l

            CellRendererComponent={({ children, item, ...props }) => {
                return (
                    <View onLayout={onLayout}>
                        {children}
                    </View>
                )
            }}
            renderItem={renderItem}

zhangwen9229 avatar Apr 13 '22 03:04 zhangwen9229

+1 It looks like this is open for a long time without a proper solution. I am having the exact same issue recorded here. It's even the same when using the ScrollView.

enesozturk avatar Jul 03 '22 12:07 enesozturk

Guys, when will this be fixed?

yolpsoftware avatar Sep 29 '22 21:09 yolpsoftware

How can I set the List Header zIndex on Android?

ListHeaderComponentStyle={{ zIndex: 9999 }} works well on iOS, but not on Andorid.

bolan9999 avatar Oct 17 '22 16:10 bolan9999

Experiencing this issue as well and even though CellRendererComponent does work, it causes my memoized RenderItem component to re-render (which does not happen if I don't use CellRendererComponent).

Would appreciate a proper fix on this!

julianjear avatar Oct 23 '22 23:10 julianjear

I tried every single suggestion abouve but unfortunately didn't help me. In my case i want to have pinch zoom functionality just like @wcandillon 's video right here https://www.youtube.com/watch?v=MukiK57qwVY&t=1186s but to achieve this, my zIndex value should be conditional. I tried hold my conditional value in component's local state or mobx state but it did not work at all. Seems like CellRendererComponent runs only once for each cell and not affecting when there is a change on the state. i dont know what to do at this point. I wonder how instagram guys achieved this on their feeds page.I am almost sure they created their own custom native component but...

Bayramito avatar Oct 29 '22 05:10 Bayramito

Hi,

I am having the same issue. (I am trying to implement a drag-and-drop sort FastList) Setting zIndex inside the renderItem function does not work.

I also tried to use CellRendererComponent and set the zIndex in the Wrapping component, but that would block my animations for some reason.

I finally made it work by making sure that CellRendererComponentis always the exact same instance of the function across re-renders.

Here is a simplified version of my code

  // make sure to use `.bind(this)` in the constructor or use auto binding. 
  renderCell = ({ index, style, ...props }) => {
	const { currentDragIndex } = this.state;
	const zIndex = {
      zIndex: index === currentDragIndex ? 2 : 0,
    };

    return <View style={[style, zIndex]} {...props} />;
  };

  render() {
    const {
      data,
    } = this.props;

    return (
      <FlatList
        data={data}
        // renderCell is always the same instance.
        CellRendererComponent={this.renderCell}
        // ...
      />
    );
  }

In a functional component, you would probably want to use useCallback.

Hope that helps

It is important to notice that it works only with class components, not functional

vberezkin avatar Dec 14 '22 13:12 vberezkin

How can I set the List Header zIndex on Android?

ListHeaderComponentStyle={{ zIndex: 9999 }} works well on iOS, but not on Andorid.

In order to get it working on Android, you should also use the elevation property.

ListHeaderComponentStyle={{ zIndex: 9999, elevation: 1 }}

kapobajza avatar May 11 '23 14:05 kapobajza

I have solved this thanks

Bayramito avatar May 11 '23 15:05 Bayramito

For me, it's working on iOS but not on Android. Also, set removeClippedSubviews={false} I have a popup view that gets extended to 2nd item of FlatList but it's getting cut out after the separator of FlatList

code:

	const cellRenderer = (props: any) => {
		const { children, index } = props;
		return (
			<View style={{
				elevation: dataIdToRenderList.length - index,
				zIndex: dataIdToRenderList.length - index,
			}}
			>
				{children}
			</View>
		);
	};

Abhishek2250 avatar May 29 '23 12:05 Abhishek2250

what do you guys trying to achieve ?

Bayramito avatar May 29 '23 12:05 Bayramito

@Bayramito Screenshot 2023-05-29 at 6 18 29 PM see in the above screenshot, a blue bg popup should not get cut. It should be above the item 2 of flatlist

Abhishek2250 avatar May 29 '23 12:05 Abhishek2250

why do you hold the popup in the row item ?

Bayramito avatar May 29 '23 13:05 Bayramito

Hope this helps to understand methodology correctly...

const Home = () => {
  const [activePopup, setActivePopup] = React.useState(null);
  return (
    <View style={{flex: 1}}>
      <FlashList
        disableAutoLayout={true}
        data={[0, 1, 2, 3, 4]}
        estimatedItemSize={400}
        ItemSeparatorComponent={() => {
          return <View style={{height: 10}} />;
        }}
        CellRendererComponent={props => {
          return (
            <View
              {...props}
              style={{
                zIndex: activePopup === props.index ? 10 : 2,
              }}>
              {props.children}
            </View>
          );
        }}
        renderItem={({item, index}) => {
          return (
            <View
              style={{
                width: '100%',
                height: 400,
                backgroundColor: 'red',
              }}>
              <TouchableOpacity
                onPress={() => {
                  if (activePopup === null) {
                    setActivePopup(index);
                  } else {
                    setActivePopup(null);
                  }
                }}
                style={{
                  position: 'absolute',
                  bottom: 10,
                  left: 10,
                  backgroundColor: 'blue',
                  padding: 10,
                }}>
                <Text>Click me</Text>
              </TouchableOpacity>
              {activePopup === index && (
                <View
                  style={{
                    position: 'absolute',
                    bottom: -130,
                    left: 50,
                    height: 150,
                    width: 150,
                    backgroundColor: 'yellow',
                  }}>
                  <Text>PopUp</Text>
                </View>
              )}
            </View>
          );
        }}
      />
    </View>
  );
};

Simulator Screen Shot - iPhone 14 - 2023-05-29 at 16 11 37

Bayramito avatar May 29 '23 13:05 Bayramito

@Bayramito thanks for the quick reply Screenshot 2023-05-29 at 6 51 09 PM

this is working on iOS but not Android. That's the same issue which I'm facing

Abhishek2250 avatar May 29 '23 13:05 Abhishek2250