0

I have a clickable ListView and I want to have it open a new page to display detailed information when a card is clicked.

I have a ListView that builds itself automatically from a dictionary (not sure if that's the right term in flutter) that looks like this:

final courses = [
    {
      "name": "Course 1",
      "date": "20/03/2024",
      "logo": "course1",
      "distance": 12967,
      "temps" : 7384
    },
    {
      "name": "Course 2",
      "date": "06/03/2024",
      "logo": "course2",
      "distance" : 17413,
      "temps" : 13854
    },
    {
      "name": "Course 3",
      "date": "27/02/2024",
      "logo": "course3",
      "distance" : 4967,
      "temps" : 3891
    },
  ];

There is currently only 3 entries for testing purpose but once finished it contain a variable number of entry.

The builder and the ListView look like this:

  @override
  Widget build(BuildContext context) {
    return Center(
      child: ListView.builder(
        itemCount: courses.length,
        itemBuilder: (context, index) {
          final course = courses[index];
          final logo = course['logo'];
          final name = course['name'];
          final date = course['date'];

          return InkWell(
            onTap: () => print('$name selected'),
            child: Card(
              child: ListTile(
                leading: Image.asset("assets/images/$logo.png"),
                title: Text('$name'),
                subtitle: Text('course du $date'),
                trailing: const Icon(Icons.more_vert),
              ),
            ),
          );
        },
      ),
    );
  }
}

What I want is to have the onTap open a new page displaying the information related to the selected dictionary entry. My guess is that I'd need to have onTap call a builder of some sort but I'm not sure how to go about doing that. I'm new to flutter and I'm not very familiar with builders and such.

1 Answer 1

0

You can pass data forward to screens using settings parameter in MaterialPageRoute when navigating to desired page:

Here's your Courses Screen, look how the course get passed:

class CoursesScreen extends StatelessWidget {
   CoursesScreen({super.key});
  List<Map<String,dynamic>> courses = [
    {
      "name": "Course 1",
      "date": "20/03/2024",
      "logo": "course1",
      "distance": 12967,
      "temps" : 7384
    },
    {
      "name": "Course 2",
      "date": "06/03/2024",
      "logo": "course2",
      "distance" : 17413,
      "temps" : 13854
    },
    {
      "name": "Course 3",
      "date": "27/02/2024",
      "logo": "course3",
      "distance" : 4967,
      "temps" : 3891
    },
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(

      body: Column(
       children: [
         Expanded(
             child:
             ListView.builder(
           itemCount: courses.length,
           itemBuilder: (context, index) {
             final course = courses[index];
             final logo = course['logo'];
             final name = course['name'];
             final date = course['date'];

             return InkWell(
               onTap: () => Navigator.of(context).push(
                 MaterialPageRoute(
                     builder: (context) =>DetailsScreen(),
                   settings: RouteSettings(
                     arguments: course
                   )
                 ),

               ),
               child: Card(
                 child: ListTile(
                   leading: Text(logo),
                   title: Text(name),
                   subtitle: Text('course du $date'),
                   trailing: const Icon(Icons.more_vert),
                 ),
               ),
             );
           },
         )),
       ],
      )
    );
  }
}

and Here's the Course Details Screen, Look how the passed data get received by that page:

class DetailsScreen extends StatelessWidget {
  const DetailsScreen({super.key});

  @override
  Widget build(BuildContext context) {

    var course = ModalRoute.of(context)!.settings.arguments  as Map<String,dynamic>;

    return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
        
            Text('course name : ${course['name']}'),
            Text('course date : ${course['date']}'),
            Text('course logo : ${course['logo']}'),
        
          ],
        ),
      ),
    );
  }
}

You can pass data to screen also by taking data as a parameter in the Screen constructor, but it's not preferable.

courses:

enter image description here

course detail:

enter image description here

For more info you can see pass data between screens

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.