react-native
react-native copied to clipboard
zIndex in FlatList
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
- Render a list of items with
FlatList
. - Change items' position and
zIndex
so an item should render above other items placed after it in the list (descendingzIndex
).
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
Check out how it behaves across rows/columns.
zIndex
works in the row but not across rows.
I got exact same issue. Any updates?
Description
Related? #23614 #23615 Setting
zIndex
on items of aFlatList
yields no result across different rows. However, it does work in the same row across it's columns if existing. I have tried usingCellRenderComponent
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
- Render a list of items with
FlatList
.- Change items' position and
zIndex
so an item should render above other items placed after it in the list (descendingzIndex
).Expected Results
zIndex
should behave the same inFlatList
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?
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)
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 CellRendererComponent
is 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
Thanks for the issue @ShaMan123!
Have you tried @bboure's solution? Does it solve your case?
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
.
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
CellRendererComponent
is 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 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.
Hi guys. Maybe this will help someone: https://github.com/facebook/react-native/issues/18616#issuecomment-389444165
Having same issue. Can we expect a new workaround or a fix this year? it's been about 2 years now.
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.
Description
Related? #23614 #23615 Setting
zIndex
on items of aFlatList
yields no result across different rows. However, it does work in the same row across it's columns if existing. I have tried usingCellRenderComponent
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
- Render a list of items with
FlatList
.- Change items' position and
zIndex
so an item should render above other items placed after it in the list (descendingzIndex
).Expected Results
zIndex
should behave the same inFlatList
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
, notCellRenderComponent
. 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.
#18616 (comment)
it will block the animation because you have to wait for next render
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.
CellRendererComponent={({ children, item, ...props }) => {
return (
<View onLayout={onLayout}>
{children}
</View>
)
}}
renderItem={renderItem}
+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.
Guys, when will this be fixed?
How can I set the List Header zIndex on Android?
ListHeaderComponentStyle={{ zIndex: 9999 }}
works well on iOS, but not on Andorid.
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!
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...
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
CellRendererComponent
is 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
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 }}
I have solved this thanks
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>
);
};
what do you guys trying to achieve ?
@Bayramito
see in the above screenshot, a blue bg popup should not get cut. It should be above the item 2 of flatlist
why do you hold the popup in the row item ?
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>
);
};
@Bayramito thanks for the quick reply
this is working on iOS but not Android. That's the same issue which I'm facing