Search code examples
flutterflutter-providerflutter-ui

how to Navigate from Listview Builder and access and show the selected Product in Flutter using provider?


I made an e-commerce app . i used the list view builder for listing the products. Now i need to display the product details page when tapped on the the desired list . How can i access the product i tapped and show its details in an another page. Below is my code for UI

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

  @override
  Widget build(BuildContext context) {
    final products = context.watch<Shop>().shop;

    return Scaffold(
      backgroundColor: AppColors.backgroundColor,
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        foregroundColor: AppColors.inversePrimaryColor,
        title: const Text('Main Page'),
        centerTitle: true,
        actions: [
          IconButton(
            onPressed: () {
              Navigator.pushNamed(context, '/cart_page');
            },
            icon: Icon(Icons.shopping_cart),
          ),
        ],
      ),
      drawer: CustomDrawer(),
      body: ListView(
        children: [
          SizedBox(height: 25.h),
          // SubTitle
          Center(
            child: Text(
              'Please Select a Product from the Following',
              style: TextStyle(
                  color: AppColors.inversePrimaryColor, fontSize: 15.h),
            ),
          ),
          SizedBox(
            height: 550.h,
            child: ListView.builder(
              scrollDirection: Axis.horizontal,
              padding: EdgeInsets.all(15.h),
              itemBuilder: (context, index) {
                final product = products[index];
                return GestureDetector(
                  child: ProductTile(product: product),
                );
              },
              itemCount: products.length,
            ),
          ),
        ],
      ),
    );
  }
}

here is my Product model

class Shop extends ChangeNotifier {
  // Product List

  List<Product> _shop = [
    // Product 1

    Product(
      name: 'Nike Sneakers',
      price: 424.77,
      description:
          '''Say hello to the next generation of Air technology. The Air Max Dn features our Dynamic Air unit system of dual-pressure tubes, creating a reactive sensation with every step. This results in a futuristic design that's comfortable enough to wear from day to night. Go ahead—Feel the Unreal.''',
      imagePath: "assets/images/image1.jpg",
    ),

    // Product 2

    Product(
      name: '''Men's Sneakers''',
      price: 74.99,
      description:
          'If you love the thrill of riding a motorcycle, you need a pair of shoes that match your passion. That’s why we created City-Ride, a part of our exclusive Motomania Collection. These shoes are designed to give you a unique and stylish look, whether you’re on the road or off it. The shoes feature a stunning design on the top, with intricate details that make them stand out. They also have a PU Foam insole and a Tyre-Tech sole, which provide comfort and durability for your feet. With City-Ride, you can enjoy the speed and style of a true motorcycle enthusiast. CAMPUS brings you the ultimate shoes for your ride',
      imagePath: "assets/images/image2.jpg",
    ),

    // Product 3

    Product(
      name: 'BaseBall Cap',
      price: 25.00,
      description:
          '''This 5-panel, flexfit, low-profile baseball cap is a great wear. It's perfect for teams or individuals, for the field or the street. The addition of spandex to the material makes for a form-fit, and the extras like a sewn-in sweatband and embroidered ventilation holes make this piece a smart buy.''',
      imagePath: "assets/images/image3.jpg",
    ),

    // Product 4

    Product(
      name: '''Men's Sandal''',
      price: 24.77,
      description:
          '''he often imitated, never duplicated, category-defining, two-strap wonder from Birkenstock. A comfort legend and a fashion staple. With adjustable straps and a magical cork footbed that conforms to the shape of your foot, a truly custom fit is as effortless as the classic design.''',
      imagePath: "assets/images/image4.jpg",
    ),

    // Product 5

    Product(
      name: '''Men's T-shirt''',
      price: 30.55,
      description:
          '''T-shirt in lightweight cotton jersey with a round, rib-trimmed neckline and a straight-cut hem. Regular fit for comfortable wear and a classic silhouette.''',
      imagePath: "assets/images/image5.jpg",
    ),
  ];

  // User Cart
  List<Product> _cart = [];

  // Get Product List
  List<Product> get shop {
    return _shop;
  }

  // Get Cart list
  List<Product> get cart {
    return _cart;
  }

  // Add to Cart
  void addToCart(Product item) {
    _cart.add(item);
    notifyListeners();
  }

  // Delete item from cart
  void deleteFromCart(Product item) {
    _cart.remove(item);
    notifyListeners();
  }
}

this is the current state of my app enter image description here

Can anybody tell me how i can access the tapped product details and display it in Another page that is for showing Product Details. I am using Provider for state Management


Solution

  • I am not sure about Provider but you can surround your ListTile Item with a GestureDetector or InkWill Widget and when you tap on your list tile you can send the id of your item to the next page with page parameters for example:

    GestureDetector(
                  onTap:(){
                     Navigator.of(context).push(
                     new MaterialPageRoute(
                     builder: (BuildContext context) =>
                     new productDetailsScreen(product:product),
                     ),
                    )
                   );
    
                 },
                      child: ProductTile(product: product),
                    );
    

    After create productDetailsScreen page like this:

    import 'package:flutter/material.dart';
    
    
    class productDetailsScreen extends StatelessWidget {
    
      final Product Product;
      const productDetailsScreen({Key? key, required this.Product})
          : super(key: key);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
            appBar: AppBar(
              //this is a mock code just to show you can show value of your productDetails field like this
              title: const Text(product.name),
            ),
            body: ...);
      }
    }