Building a Photo Gallery App in Flutter: A Step-by-Step Guide

Prerequisites

Before we dive into the tutorial, make sure you have the following:

  • Flutter installed on your machine
  • Dependencies (imagesizegetter, imageeditor, photoview) added to your project
  • A cup of coffee (optional, but highly recommended)

Building the Homepage

The first step is to create a new Flutter project and set up the homepage. We’ll create a simple grid layout to display our images.

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<String> _images = [
    'assets/image1.jpg',
    'assets/image2.jpg',
    'assets/image3.jpg',
    'assets/image4.jpg',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Photo Gallery'),
      ),
      body: GridView.builder(
        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
        ),
        itemCount: _images.length,
        itemBuilder: (context, index) {
          return InkWell(
            onTap: () {
              // Navigate to image index
            },
            child: Image.asset(_images[index]),
          );
        },
      ),
    );
  }
}

Creating the Organized Feature

Next, we’ll create a feature to sort our images by size and name. We’ll add four callback functions to sort the images in ascending and descending order.

class _MyHomePageState extends State<MyHomePage> {
  //...

  void _sortImagesByIncreasingSize() {
    setState(() {
      _images.sort((a, b) {
        return a.length.compareTo(b.length);
      });
    });
  }

  void _sortImagesByDecreasingSize() {
    setState(() {
      _images.sort((a, b) {
        return b.length.compareTo(a.length);
      });
    });
  }

  void _sortImagesByNameIncreasing() {
    setState(() {
      _images.sort((a, b) {
        return a.compareTo(b);
      });
    });
  }

  void _sortImagesByNameDecreasing() {
    setState(() {
      _images.sort((a, b) {
        return b.compareTo(a);
      });
    });
  }

  //...
}

Routing to Image Index

Now, let’s navigate to each image when tapped. We’ll create a new file called gallerywidget.dart and add a GalleryWidget class.

class GalleryWidget extends StatefulWidget {
  @override
  _GalleryWidgetState createState() => _GalleryWidgetState();
}

class _GalleryWidgetState extends State<GalleryWidget> {
  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PhotoViewGallery.builder(
        pageController: PageController(initialPage: _currentIndex),
        itemCount: _images.length,
        builder: (context, index) {
          return PhotoViewGalleryPageOptions(
            imageProvider: AssetImage(_images[index]),
          );
        },
      ),
    );
  }
}

Creating a Bottom Navigation Bar

Finally, let’s add a bottom navigation bar to navigate to the edit page.

class _MyHomePageState extends State<MyHomePage> {
  //...

  int _currentIndex = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //...
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        onTap: (index) {
          setState(() {
            _currentIndex = index;
          });
        },
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.edit), label: 'Edit'),
        ],
      ),
    );
  }
}

Creating an Edit Feature

Let’s create an edit feature using the image_editor package. We’ll add two editing features: rotation and flipping.

class EditScreen extends StatefulWidget {
  @override
  _EditScreenState createState() => _EditScreenState();
}

class _EditScreenState extends State<EditScreen> {
  File _image;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _image!= null
         ? Image.file(_image)
          : Text('No image selected'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () async {
          final pickedFile = await ImagePicker().getImage(source: ImageSource.gallery);
          setState(() {
            if (pickedFile!= null) {
              _image = File(pickedFile.path);
            } else {
              print('No image selected.');
            }
          });
        },
        tooltip: 'Pick an image',
        child: Icon(Icons.add_a_photo),
      ),
      bottomNavigationBar: BottomAppBar(
        child: Row(
          children: [
            IconButton(
              icon: Icon(Icons.rotate_left),
              onPressed: () async {
                final editedImage = await ImageEditor.editImage(
                  image: _image,
                  editOption: EditOption(
                    rotation: 90,
                  ),
                );
                setState(() {
                  _image = editedImage;
                });
              },
            ),
            IconButton(
              icon: Icon(Icons.flip),
              onPressed: () async {
                final editedImage = await ImageEditor.editImage(
                  image: _image,
                  editOption: EditOption(
                    flip: true,
                  ),
                );
                setState(() {
                  _image = editedImage;
                });
              },
            ),
          ],
        ),
      ),
    );
  }
}

That’s it! You now have a complete photo gallery app with editing features.

Leave a Reply