GridView Multiple Item Types
To display grid items with varied layouts in the same GridView, use a Conditional Builder as the child template. This allows you to create dynamic grids where different items can have completely different visual representations—perfect for product catalogs with featured items, photo galleries with different media types, or dashboards with mixed widgets.

When to Use This Pattern
Use this approach when your grid contains items of different types that need different visual layouts:
Product catalogs - Mix regular products, featured products, and promotional banners
Photo galleries - Display photos, videos, and placeholders with different layouts
Dashboards - Combine metric cards, charts, and quick action tiles
App launchers - Show apps, folders, and widgets with varied presentations
Category grids - Mix category cards, promotional tiles, and navigation items
How It Works
The key is to include a type identifier in your data source, then use a Conditional Builder to check that type and render the appropriate layout for each grid item.
Step-by-Step Implementation
1. Structure Your Data Source
Your data array should include a property that identifies the item type:
[
{
"type": "regular",
"name": "Product 1",
"image": "product1.jpg",
"price": 29.99
},
{
"type": "featured",
"name": "Premium Product",
"image": "featured.jpg",
"price": 99.99,
"badge": "Best Seller"
},
{
"type": "promo",
"title": "Special Offer",
"description": "50% Off This Week",
"ctaText": "Shop Now"
}
]The type field determines which layout to render for each grid item.
2. Add a Conditional Builder as the GridView Child
Select your GridView widget
Add a Conditional Builder as the single child
The Conditional Builder will be repeated for each item in the data source
3. Create Conditions Based on Item Type
In the Conditional Builder, add conditions that check the type property of currentItem:
Condition 1: ${isEqual(currentItem.type, 'regular')}
Build a standard product card layout
Condition 2: ${isEqual(currentItem.type, 'featured')}
Build an enhanced featured product layout with badge
Condition 3: ${isEqual(currentItem.type, 'promo')}
Build a promotional banner layout
Default Case:
Optionally add a fallback layout for unknown types
Example Layouts
Regular Product Card
Card:
Column:
Image:
URL: ${currentItem.image}
Aspect Ratio: 1.0
Padding:
Column:
Text:
Text: ${currentItem.name}
Weight: Bold
Text:
Text: ${concat("$", currentItem.price)}
Color: PrimaryFeatured Product Card
Card:
Stack:
Image:
URL: ${currentItem.image}
Aspect Ratio: 1.0
Positioned (Top-right badge):
Container:
Background: Gold
Text: ${currentItem.badge}
Positioned (Bottom):
Container:
Background: Semi-transparent
Column:
Text: ${currentItem.name}
Text: ${concat("$", currentItem.price)}Promotional Banner
Card:
Background: Gradient
Center:
Column:
Icon: local_offer
Text:
Text: ${currentItem.title}
Size: Large
Text:
Text: ${currentItem.description}
Button:
Text: ${currentItem.ctaText}Advanced Patterns
Spanning Multiple Grid Cells
Note that in GridView, all items occupy the same grid cell size determined by the Cross Axis Count and Child Aspect Ratio. You cannot make a single item span multiple columns or rows like in traditional CSS Grid.
Workaround: If you need items to span multiple cells, consider:
Using a Wrap widget with custom-sized children
Using a Column with Rows for custom layouts
Implementing a custom layout using Positioned widgets inside a Stack
Dynamic Item Sizing Within Constraints
While all grid items have the same cell size, you can vary the content size within each cell:
Conditional Builder:
Condition: ${isEqual(currentItem.type, 'large')}
True:
Card (fills entire cell):
Image: Full cell
False:
Card (padded, smaller):
Padding: 8px
Image: Smaller image with paddingMixed Aspect Ratios
If you need dramatically different aspect ratios, consider using different GridViews stacked vertically or use a ListView with Rows containing varied numbers of items.
Grid Layout Considerations
Maintaining Visual Balance
When using multiple item types in a grid:
Keep proportions consistent: Even with different layouts, maintain visual weight balance
Use consistent spacing: Keep padding and margins uniform across item types
Align baselines: Try to align text and key elements across different item types
Color harmony: Use a consistent color palette even with varied layouts
Ordering Strategy
Consider how you order mixed item types:
[
{"type": "regular", ...},
{"type": "regular", ...},
{"type": "featured", ...}, // Featured item after 2 regulars
{"type": "regular", ...},
{"type": "promo", ...}, // Promo after 4 items
...
]Strategic placement of special items creates visual interest without overwhelming the grid.
Accessing currentItem in Each Branch
Remember that ${currentItem} and ${index} are available in all branches of the Conditional Builder:
Regular items:
${currentItem.name},${currentItem.price}Featured items:
${currentItem.badge},${currentItem.discount}Promo items:
${currentItem.title},${currentItem.ctaText}All items:
${index}for position-based logic
Using Index for Patterns
Conditional Builder:
Condition: ${isEqual(modulo(sum(index, 1), 6), 0)}
True:
// Every 6th item is a promotional banner
PromoCard
False:
// Regular product layout
ProductCardBest Practices
Keep type identifiers consistent: Use clear, predictable type names like
"regular","featured","promo"Handle unknown types gracefully: Always include a default case in your Conditional Builder
Maintain grid cohesion: Even with varied layouts, keep items visually connected through consistent spacing, colors, and sizing
Test different screen sizes: Ensure layouts work well with different Cross Axis Counts
Limit variety: Too many different item types can create visual chaos; stick to 2-4 types maximum
Use type for functionality: Different types can have different tap behaviors or navigation destinations
Performance Considerations
Conditional Builder is lightweight: It doesn't significantly impact performance; only one branch renders per item
Optimize complex layouts: If some item types are heavy (e.g., with videos), consider lazy loading or placeholders
Cache images: Use image caching for better scroll performance
Keep templates efficient: Even with varied layouts, maintain lightweight widget trees
Common Use Cases
Product Grid with Ads
[
{"type": "product", "name": "Item 1", ...},
{"type": "product", "name": "Item 2", ...},
{"type": "product", "name": "Item 3", ...},
{"type": "ad", "title": "Special Offer", ...},
{"type": "product", "name": "Item 4", ...},
...
]Photo Gallery with Videos
[
{"type": "photo", "url": "photo1.jpg", ...},
{"type": "photo", "url": "photo2.jpg", ...},
{"type": "video", "url": "video1.mp4", "thumbnail": "thumb1.jpg", ...},
{"type": "photo", "url": "photo3.jpg", ...},
...
]Dashboard with Widgets
[
{"type": "metric", "title": "Sales", "value": "1,234", ...},
{"type": "chart", "chartType": "line", "data": [...], ...},
{"type": "metric", "title": "Users", "value": "567", ...},
{"type": "action", "title": "Quick Action", "icon": "add", ...},
...
]Related Documentation
Conditional Builder - Complete Conditional Builder widget reference
GridView - Complete GridView widget reference
Logical Operators - Learn about
isEqual()and other comparison functionsCustom Widgets - Create reusable components for complex item layouts
Last updated