Flutter - Clickable OnTap from List

538

You are on the right track with GestureDetector. If you want to open to a new screen, you can use Navigator.of(context).push to push a new MaterialPageRoute. And since you are in a GridView builder function, you can use menuList[position] to get the current item. For example:

GestureDetector(
  onTap: () {
    final title = menuList[position].title;
    Navigator.of(context).push(
      MaterialPageRoute(builder: (BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text(title)),
        );
      }),
    );
  },
  child: ...
)
Share:
538
WillWalsh
Author by

WillWalsh

Updated on January 01, 2023

Comments

  • WillWalsh
    WillWalsh 11 months

    I'm learning flutter and hit a wall with this one.

    Code below produces "home" screen in image. With multiple rounded buttons created from a List with each including an icon and text.

    What I need is to include a unique link to the onTap(){} call.

    I'm assuming to add the screen name to the same List line with icon and text then use index inside the onTap... or something like that.

    Help is welcomed and truly appreciated.

    Flutter Home Screen

    '''import 'dart:ui';
    
    import 'package:flutter/material.dart';
    import 'package:flutter_firebase_auth/appbar/app_bar_title.dart';
    import 'package:flutter_firebase_auth/drawer/drawer.dart';
    import 'package:flutter_firebase_auth/drawer/end_drawer.dart';
    import 'package:flutter_firebase_auth/logic/custom_colors.dart';
    
    class Home extends StatefulWidget {
      @override
      _HomeState createState() => _HomeState();
    }
    
    class _HomeState extends State<Home> {
      static List menuList = [
        _MenuItem(Icons.person, 'Mayor\'s Office', ),
        _MenuItem(Icons.people, 'Employees'),
        _MenuItem(Icons.chat, 'WeChat'),
        _MenuItem(Icons.cancel, 'OPEN'),
        _MenuItem(Icons.business, 'BizList'),
        _MenuItem(Icons.water_damage, 'utilities'),
        _MenuItem(Icons.map, 'Welaka Map'),
        _MenuItem(Icons.email, 'Contact Us'),
        _MenuItem(Icons.info_outline, 'About WelakaOne'),
        _MenuItem(Icons.add, 'About walsh+logic'),
      ];
    
      get index => null;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            brightness: Brightness.dark,
            backgroundColor: CustomColors.welakaoneBlack,
            title: AppBarTitle(),
            leading: Builder(
              builder: (context) {
                return IconButton(
                  onPressed: () {
                    Scaffold.of(context).openDrawer();
                  },
                  icon: Icon(Icons.menu),
                );
              },
            ),
            actions: <Widget>[
              Builder(
                builder: (context) {
                  return IconButton(
                    onPressed: () {
                      Scaffold.of(context).openEndDrawer();
                    },
                    icon: Icon(Icons.person),
                  );
                },
              ),
            ],
          ),
          drawer: new MyDrawer(),
          endDrawer: new MyEndDrawer(),
          body: Container(
            decoration: const BoxDecoration(
              gradient: LinearGradient(
                colors: [
                  CustomColors.welakaoneBlack,
                  CustomColors.welakaoneBlueDark,
                ],
                begin: FractionalOffset(0.0, 0.0),
                end: FractionalOffset(1.6, 1.0),
                stops: [0.3, 1.0],
                tileMode: TileMode.clamp,
              ),
            ),
            child: Padding(
              padding: const EdgeInsets.all(10.0),
              child: GridView.builder(
                itemCount: menuList.length,
                shrinkWrap: false,
                gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                  maxCrossAxisExtent: 200.0,
                  mainAxisSpacing: 10.0,
                  crossAxisSpacing: 10.0,
                  childAspectRatio: 1.5,
                ),
                itemBuilder: (context, position) {
                  return Padding(
                    padding: const EdgeInsets.all(0.0),
                    child: GestureDetector(
                      onTap: () {Navigator.pushNamed(context, _MenuItem(icon, title))},
                      child: Center(
                        child: Column(
                          children: [
                            Center(
                              child: Card(
                                color: CustomColors.welakaoneWhite,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(100.0),
                                ),
                                elevation: 8,
                                child: Padding(
                                  padding: const EdgeInsets.all(10.0),
                                  child: Icon(
                                    menuList[position].icon,
                                    size: 50,
                                    color: CustomColors.welakaoneBlueDark,
                                  ),
                                ),
                              ),
                            ),
                            Padding(
                              padding: const EdgeInsets.all(6.0),
                              child: Container(
                                alignment: Alignment.bottomCenter,
                                child: Text(
                                  menuList[position].title,
                                  textAlign: TextAlign.center,
                                  style: TextStyle(
                                    fontFamily: 'Calibri',
                                    fontSize: 16,
                                    color: CustomColors.welakaoneWhite,
                                    fontWeight: FontWeight.bold,
                                  ),
                                ),
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  );
                },
              ),
            ),
          ),
        );
      }
    }
    
    class _MenuItem {
      final IconData icon;
      final String title;
    
      _MenuItem(this.icon, this.title);
    }
     '''
    
  • WillWalsh
    WillWalsh about 2 years
    Thank you! Worked perfectly. I have navigated using drawers and bottom menu bars but never from within a list. :)
  • WillWalsh
    WillWalsh about 2 years
    I have "followup" question if you could answer. As every list item will be it's on screen how do I user MaterialPageRoute to push to the necessary screen? Where would I include the screen info in the list? Could be way off-base here but would think it necessary to place the screen with the icon and title info???
  • WSBT
    WSBT about 2 years
    @WillWalsh Your list (grid) items are custom classes _MenuItem, you can add a field there.