Flutter Widget for Responsive Grid View with image

MyResponsiveGridImage is a Flutter widget that provides a responsive grid view with customizable column count and item layout based on the device's screen size.

It uses the ResponsiveUtils class to determine the screen size and adjusts the number of columns and item layout accordingly. It also supports dynamic image loading from network URLs, and customizable title and description for each grid item.


Usage:

MyResponsiveGridImage can be used in a Flutter app to create a responsive grid view with different column counts and item layouts based on the device's screen size. 

It can be useful in scenarios where you want to display a grid of items such as images, cards, or tiles, and you want the layout to adapt to different screen sizes, such as mobile, tablet, and desktop devices.


Code:

import 'package:flutter/material.dart';
import '../util/responsive_utils.dart';
import '../util/typography.dart';

class MyResponsiveGridImage extends StatelessWidget {
  const MyResponsiveGridImage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {

    final textTheme = Theme.of(context)
        .textTheme
        .apply(displayColor: Theme.of(context).colorScheme.onSurface);

    // Set the default number of columns to 3.
    int columnsCount = 2;

    // Define the icon size based on the screen width
    double iconSize =  45;


    // Use the ResponsiveUtils class to determine the device's screen size.
    if (ResponsiveUtils.isMobile(context)) {
      columnsCount = 1;
      iconSize = 30;
    } else if (ResponsiveUtils.isDesktop(context)) {
      columnsCount = 4;
      iconSize = 50;
    }

    // Build the grid view using the number of columns.
    return Scaffold(
      appBar: AppBar(
        title: const Text('Responsive Grid View'),
      ),
      body: GridView.builder(
        // Set padding and spacing between cards.
        padding: const EdgeInsets.all(10),
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          // Set the number of columns based on the device's screen size.
          crossAxisCount: columnsCount,
          // Set the aspect ratio of each card.
          childAspectRatio: 3 / 2,
          crossAxisSpacing: 10,
          mainAxisSpacing: 10,
        ),
        // Set the number of items in the grid view.
        itemCount: 20,
        itemBuilder: (BuildContext context, int index) {
          // Build each card in the grid view.
          return Card(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: [
                Expanded(
                  // Add an image to each card.
                  child: Image.network(
                    'https://picsum.photos/id/$index/400/300',
                    fit: BoxFit.cover,
                  ),
                ),
                const SizedBox(height: 10),
                Padding(
                  padding: const EdgeInsets.symmetric(horizontal: 10),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      // Add a title to each card.
                      MyTextStyle(
                          name: 'Item $index', style: textTheme.titleLarge!),
                      const SizedBox(height: 5),
                      // Add a description to each card.
                      MyTextStyle(
                          name: 'Description of item $index', style: textTheme.bodyMedium!),
                    ],
                  ),
                ),
                const SizedBox(height: 10),
              ],
            ),
          );
        },
        // Set the grid view to shrink wrap its contents.
        shrinkWrap: true,
        // Disable scrolling in the grid view.
        physics: const NeverScrollableScrollPhysics(),
      ),
    );
  }
}

..

lib : Util : typography.dart

import 'package:flutter/material.dart';

// create typography.dart file
class MyTextStyle extends StatelessWidget {
  const MyTextStyle({
    super.key,
    required this.name,
    required this.style,
  });

  final String name;
  final TextStyle style;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(2.0),
      child: Text(name, style: style),//.copyWith(letterSpacing: 1.0)
    );
  }
}


lib : Util : responsive_utils.dart

import 'package:flutter/material.dart';

class ResponsiveUtils {
  // Check if the device is considered as mobile based on screen width.
  static bool isMobile(BuildContext context) =>
      MediaQuery.of(context).size.width <= 600;

  // Check if the device is considered as tablet based on screen width.
  static bool isTablet(BuildContext context) =>
      MediaQuery.of(context).size.width > 600 &&
          MediaQuery.of(context).size.width <= 1200;

  // Check if the device is considered as desktop based on screen width.
  static bool isDesktop(BuildContext context) =>
      MediaQuery.of(context).size.width > 1200;
}


Properties:

  • columnsCount: An integer that defines the number of columns in the grid view. It can be customized based on the screen size using the ResponsiveUtils class.
  • iconSize: A double that defines the size of icons in the grid view. It can be customized based on the screen size using the ResponsiveUtils class.
  • itemCount: An integer that defines the total number of items in the grid view.
  • itemBuilder: A callback function that defines how each item in the grid view should be built. It takes the context and index as parameters and should return a Widget.
  • shrinkWrap: A boolean that determines whether the grid view should shrink wrap its contents. When set to true, the grid view will wrap its contents tightly, resulting in a smaller height.
  • physics: A ScrollPhysics object that determines how the grid view should behave when scrolling. In this code, it is set to NeverScrollableScrollPhysics to disable scrolling in the grid view.
  • appBar: An AppBar widget that serves as the app bar for the screen.
  • body: The main body of the screen, which contains the GridView.builder widget for building the responsive grid view. The child widgets inside each grid item include an image, title, and description, which can be customized using the MyTextStyle widget. 
..
Flutter Basic,


Comments