Home > Software design >  How to navigate to a page by clicking on a ListView Item in flutter?
How to navigate to a page by clicking on a ListView Item in flutter?

Time:12-09

so what i want to do is to whatever item in list I click it navigates to the especific page for it item, example: the first item in the list is the "agentes", i want whenever I click on "agentes" box it navigates to agentes screen. Basically I have this List here:

final List<HomeModel> homes = [
    HomeModel("Agentes", "assets/icons/agents_icon.png"),
    HomeModel("Armas", "assets/icons/weapons_icon.png"),
    HomeModel("Mapas", "assets/icons/maps_icon.png"),
    HomeModel("Ranks", "assets/icons/ranks_icon.png"),
    HomeModel("Cards", "assets/icons/cards_icon.png"),
  ];

also the model I use in the list:

class HomeModel {
  late String tittle;
  late String icon;

  HomeModel(
    this.tittle,
    this.icon,
  );
}

then I have the code for my listView:

Expanded(
              child: ListView(
                children: [
                  for (var home in homes)
                    Container(
                      margin: const EdgeInsets.fromLTRB(10, 15, 10, 5),
                      padding: const EdgeInsets.fromLTRB(30, 5, 15, 5),
                      width: double.infinity,
                      decoration: BoxDecoration(
                        border: Border.all(
                          color: const Color.fromARGB(255, 255, 70, 85),
                          width: 2,
                        ),
                      ),
                      child: Row(
                        crossAxisAlignment: CrossAxisAlignment.center,
                        children: [
                          Container(
                            margin: const EdgeInsets.fromLTRB(0, 1, 38, 0),
                            child: Stack(
                              alignment: Alignment.center,
                              children: [
                                Text(
                                  home.tittle,
                                  style: GoogleFonts.bowlbyOneSc(
                                    color: Colors.white,
                                    letterSpacing: .5,
                                    fontSize: 24,
                                  ),
                                ),
                              ],
                            ),
                          ),
                          const Spacer(),
                          // ignore: sized_box_for_whitespace
                          Container(
                            width: 125,
                            height: 140,
                            child: Stack(
                              alignment: Alignment.center,
                              children: [
                                Image.asset(
                                  home.icon,
                                )
                              ],
                            ),
                          ),
                        ],
                      ),
                    ),
                ],
              ),
            ),

I have also my routes file where i get all the screens routes:

import 'package:flutter/material.dart';
import 'package:guia_de_valorant/screens/agent_screen.dart';
import 'package:guia_de_valorant/screens/card_screen.dart';
import 'package:guia_de_valorant/screens/home.dart';
import 'package:guia_de_valorant/screens/map_screen.dart';
import 'package:guia_de_valorant/screens/rank_screen.dart';
import 'package:guia_de_valorant/screens/splash_scren.dart';
import 'package:guia_de_valorant/screens/weapon_screen.dart';

class Routes {
  Routes._();

  //static variables
  static const String agents = "/agents";
  static const String weapons = "/weapons";
  static const String maps = "/maps";
  static const String ranks = "/ranks";
  static const String cards = "/cards";
  static const String splash = '/splash';
  static const String home = '/home';


  static final routes = <String, WidgetBuilder>{
    agents: (BuildContext context) => const AgentScreen(),
    weapons: (BuildContext context) => const WeaponScreen(),
    maps: (BuildContext context) => const MapScreen(),
    ranks: (BuildContext context) => const RankScreen(),
    cards: (BuildContext context) => const CardScreen(),
    splash: (BuildContext context) => const SplashScreen(),
    home: (BuildContext context) => HomeScreen(),

  };
}

CodePudding user response:

to keep your code consistent and for a relation for each path and it's Model, I specifying it in the Model itself.

class HomeModel {
  late String tittle;
  late String icon;
  late String routePath
  HomeModel(
    this.tittle,
    this.icon,
    this.routePath,
  );
}

So your List should be:

final List<HomeModel> homes = [
    HomeModel("Agentes", "assets/icons/agents_icon.png", "/agents"),
    HomeModel("Armas", "assets/icons/weapons_icon.png", "/weapons"),
    HomeModel("Mapas", "assets/icons/maps_icon.png", "/maps"),
    HomeModel("Ranks", "assets/icons/ranks_icon.png", "/ranks"),
    HomeModel("Cards", "assets/icons/cards_icon.png", "/cards"),
  ];

then in the ListView.builder, you can use a GestureDetector widget to achieve a clickable Item:

Expanded(
          child: ListView(
            children: [
              for (var home in homes)
                GestureDetector(
                  onTap: () {
                    Navigator.of(context).pushNamed(home.routePath); // this will navigate to the route
                  },
                  child: Container(
                    margin: const EdgeInsets.fromLTRB(10, 15, 10, 5),
                    padding: const EdgeInsets.fromLTRB(30, 5, 15, 5),
                    width: double.infinity,
                    decoration: BoxDecoration(
                      border: Border.all(
                        color: const Color.fromARGB(255, 255, 70, 85),
                        width: 2,
                      ),
                    ),
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: [
                        Container(
                          margin: const EdgeInsets.fromLTRB(0, 1, 38, 0),
                          child: Stack(
                            alignment: Alignment.center,
                            children: [
                              Text(
                                home.tittle,
                                style: GoogleFonts.bowlbyOneSc(
                                  color: Colors.white,
                                  letterSpacing: .5,
                                  fontSize: 24,
                                ),
                              ),
                            ],
                          ),
                        ),
                        const Spacer(),
                        // ignore: sized_box_for_whitespace
                        Container(
                          width: 125,
                          height: 140,
                          child: Stack(
                            alignment: Alignment.center,
                            children: [
                              Image.asset(
                                home.icon,
                              )
                            ],
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
            ],
          ),
        );
  • Related