Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add gap between columns #706

Unanswered
wong2 asked this question in Q&A
Dec 14, 2022 · 12 comments · 1 reply
Discussion options

I'm implementing a two column list with FlashList, ItemSeparatorComponent are only added between rows, how can I add a gap between these two columns?

You must be logged in to vote

Replies: 12 comments 1 reply

Comment options

@wong2 , any news on this?

You must be logged in to vote
0 replies
Comment options

same needs

You must be logged in to vote
0 replies
Comment options

^

You must be logged in to vote
0 replies
Comment options

It's not implemented yet in the FlashList!
However, I found a way to hack it.
I wrapped my elements in a View and depending on their indexes I added a padding:

// ...
renderItem={({data, index}) => {
return (
<View style={[index % 2 ? {paddingRight: 20} : {paddingLeft: 20}, {flex: 1}]} >
<Item data={data} />
</View> );
}}
// ...

If you have more columns I still have a way to hack it!

You must be logged in to vote
0 replies
Comment options

if you have dynamic column number, you can try:

 const colNum = 4;
 const gap = 8;
 const renderRowItem = useCallback(({item, index}: any) => {
 return (
 <View
 style={{
 flexGrow: 1,
 paddingLeft: index % colNum === 0 ? gap : 0,
 paddingRight: index % 1 === 0 ? gap : 0,
 paddingBottom: index % 1 === 0 ? gap : 0,
 paddingTop: index < colNum ? gap : 0,
 }}>
 <RenderItemComponent {...item} />
 </View>
 );
 }, []);
You must be logged in to vote
0 replies
Comment options

Although i am using tailwindcss with nativewind, you can use the same approach using stylesheet.

 const renderItem = React.useCallback(
 ({ item, index }: { item: BusinessType; index: number }) => (
 <BusinessCard
 className={cn("w-[95%]", {
 "mr-auto": index % 2 === 0,
 "ml-auto": index % 2 === 1
 })}
 {...item}
 />
 ),
 []
 );

with styles

 const renderItem = React.useCallback(
 ({ item, index }: { item: BusinessType; index: number }) => (
 <BusinessCard
 
 style={{
 width: "95%",
 marginRight: index % 2 === 0 ? "auto" : undefined,
 marginLeft: index % 2 === 1 ? "auto" : undefined
 }}
 {...item}
 />
 ),
 []
 );
You must be logged in to vote
0 replies
Comment options

How is this not already implemented?!

You must be logged in to vote
0 replies
Comment options

bump... we need this!

You must be logged in to vote
0 replies
Comment options

None of the above solutions worked for me - they all resulted in some columns being larger than others.

After a lot of trial and error I landed on this which seems to work well for 2 or more columns, and keeps all columns the same width:

const gap = 8;
const numCols = 4;
// Evenly distribute the gap width between each item (4 columns has 3 gaps)
const itemGap = (gap * (numCols - 1)) / numCols;
return (
 <FlashList
 renderItem={({ item, index }) => {
 // Left margin increases for each column, right margin decreases for each column
 // What's important is that marginRight + marginLeft === itemGap
 const marginLeft = ((index % numCols) / (numCols - 1)) * itemGap;
 const marginRight = itemGap - marginLeft
 return (
 <View
 style={{
 flexGrow: 1,
 marginLeft,
 marginRight,
 }}
 >
 {'...'}
 </View>
 );
 }}
 />
);

With the example above you get 4 nicely spaced columns:

| [ITEM] <-6-> | <-2-> [ITEM] <-4-> | <-4-> [ITEM] <-2-> | <-6-> [ITEM] |
You must be logged in to vote
1 reply
Comment options

this is indeed the easiest to implement atm.. thanks man 👏

Comment options

any solution for masonry ?

You must be logged in to vote
0 replies
Comment options

Here's my solution for a GridList component using FlashList

import { View } from "react-native";
import { FlashList, FlashListProps } from "@shopify/flash-list";
interface Props {
 gap: number;
 cols: number;
}
export default <T extends Props>({gap, cols, ...rest}: FlashListProps<T> & Props) => (
 <FlashList 
 numColumns={cols}
 ItemSeparatorComponent={() => <View style={{height: gap}} />}
 CellRendererComponent={({style, index, ...props}) => {
 const itemGap = (gap * (cols - 1)) / cols;
 const paddingLeft = ((index % cols) / (cols - 1)) * itemGap;
 const paddingRight = itemGap - paddingLeft
 return (
 <View 
 style={{...style, flexGrow: 1, paddingLeft, paddingRight}} 
 {...props} 
 />
 )
 }}
 {...rest}
 />
)
You must be logged in to vote
0 replies
Comment options

This issue is almost 3 years old by now, is there really no roadmap on this getting implemented?

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

AltStyle によって変換されたページ (->オリジナル) /