I’m working on a Flutter project where I have a PageView with three children. Each child contains a LayoutBuilder that builds a GridView.
When I don’t specify any padding, the grid looks like this:
However, when I add padding directly to the GridView or wrap it with padding, everything looks correct on a desktop screen, but on mobile devices, there’s extra padding or space at the bottom of the grid.
Desktop View (Correct): The layout appears as expected, with consistent padding around the grid.
Mobile View (Incorrect): On mobile devices (and Raspberry Pi using Flutter-pi), the same grid has extra space below the last row, even though no additional padding is set there.
Question:
Why does the layout behave differently on mobile devices compared to desktop, and how can I ensure a consistent UI across all platforms, including when embedded on a Raspberry Pi using Flutter-pi?
class MainPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
margin: const EdgeInsets.symmetric(
vertical: 50.0,
),
child: PageView(
controller: PageController(
initialPage: 0,
viewportFraction: 0.9,
),
children: const [
GrindBuilderBeverages(
backgroundColor: Colors.redAccent,
rows: 4,
columns: 4,
crossAxisSpacing: 15.0,
mainAxisSpacing: 20.0,
),
GrindBuilderBeverages(
backgroundColor: Colors.purpleAccent,
rows: 3,
columns: 3,
crossAxisSpacing: 10.0,
mainAxisSpacing: 10.0,
),
GrindBuilderBeverages(
backgroundColor: Colors.greenAccent,
rows: 2,
columns: 5,
crossAxisSpacing: 5.0,
mainAxisSpacing: 5.0,
),
],
),
),
);
}
}
class GrindBuilderBeverages extends StatelessWidget {
final Color backgroundColor;
final int rows;
final int columns;
final double crossAxisSpacing;
final double mainAxisSpacing;
const GrindBuilderBeverages(
{super.key,
required this.backgroundColor,
required this.rows,
required this.columns,
required this.crossAxisSpacing,
required this.mainAxisSpacing});
@override
Widget build(BuildContext context) {
return Container(
margin: const EdgeInsets.symmetric(horizontal: 16.0),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: BorderRadius.circular(16.0),
),
child: LayoutBuilder(
builder: (context, constraints) {
// Calculate the childAspectRatio based on the available width and height
final double totalHorizontalSpacing = (columns - 1) * crossAxisSpacing;
final double totalVerticalSpacing = (rows - 1) * mainAxisSpacing;
final double itemWidth =
(constraints.maxWidth - totalHorizontalSpacing) / columns;
final double itemHeight =
(constraints.maxHeight - totalVerticalSpacing) / rows;
final double aspectRatio = itemWidth / itemHeight;
return GridView.builder(
padding: const EdgeInsets.all(16.0),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: columns, // Set the number of columns
childAspectRatio: aspectRatio, // Dynamic aspect ratio
crossAxisSpacing: crossAxisSpacing, // Horizontal spacing
mainAxisSpacing: mainAxisSpacing, // Vertical spacing
),
itemCount: rows * columns, // Total number of items
itemBuilder: (context, index) {
return Container(
color: Colors.white.withOpacity(0.5),
child: Center(
child: Text(
'Item $index',
style: const TextStyle(color: Colors.black),
),
),
);
},
);
},
),
);
}
}
A simple solution would be to change the code according to the platform, you can do such a thing by using the 'dart:io'
library.
here is an example:
import'dart:io' show Platform;
void main(){
if(Platform.isIOS){
//make the Grid for the IOS
}else if(Platform.isAndroid){
//make the Grid for the Android
}else if (Platform.isWindows) {
// make the Grid for the Windows
}else if(Platform.isMacOS){
//make the Grid for the MacOS
}
And you can explore more and learn how to use it from the Flutter documentation for sure: https://flutter.dev/