sujith sa
sujith sa

Reputation: 37

Flutter update data onClick at clicked index

I am building a food cart application and have a query on the menu item page.

My menu items page consists of a list view, which shows each item with description along with an option to specify the quantity of items( 1, 2, 3....)

Now I am able to increment or decrement item count for a single item, but not sure how to do that in a list view at a particular index where the user clicks.

Could some one please help me on this?

The code which I have done till now is as below :

FutureBuilder(
                future: getItemList(),
                builder: (context, snapshot) {
                  if (!snapshot.hasData) {
                    return CircularProgressIndicator();
                  }
                  var itemList = snapshot.data;
                  int itemlength = itemList.length;
                  return ListView.builder(
                    scrollDirection: Axis.vertical,
                    shrinkWrap: true,
                    itemBuilder: (BuildContext context, int index) {
                      return Container(
                        height: 100,
                        margin: EdgeInsets.only(left: 10, right: 10, top: 10),
                        decoration: BoxDecoration(
                          color: Colors.white70,
                          border: Border.all(width: 2.0, color: Colors.blueGrey),
                          borderRadius: BorderRadius.circular(6.0),
                          boxShadow: [
                            BoxShadow(
                                color: Color(0xFF6078ea).withOpacity(.3),
                                offset: Offset(0.0, 8.0),
                                blurRadius: 8.0),
                          ],
                        ),
                        child: Row(
                          children: < Widget > [
                            Container(
                              width: 75,
                              child: ClipRRect(
                                borderRadius: new BorderRadius.circular(10.0),
                                child: Image(
                                  image: AssetImage(
                                      'assets/images/loginbg3.jpg'),
                                  fit: BoxFit.cover,
                                ),
                              ),
                              margin: EdgeInsets.only(left: 10),
                            ),
                            Expanded(
                              child: Container(
                                child: Column(
                                  children: < Widget > [
                                    Row(
                                      children: < Widget > [
                                        Expanded(child: Container(margin: EdgeInsets.only(left: 10, top: 15, bottom: 5), child: Text(itemList[index]['itemname'], style: kClickableTextStyle, ))),
                                        Container(color: Colors.white, width: 25, margin: EdgeInsets.only(left: 10, top: 15, bottom: 5), child: Image.asset(_itemtype)),
                                      ],
                                    ),
                                    Row(
                                      children: < Widget > [
                                        Container(margin: EdgeInsets.only(left: 10, top: 15, bottom: 5), child: Text('Price : ', style: kListTitleTextStyle, )),
                                        Container(margin: EdgeInsets.only(left: 10, top: 15, bottom: 5), child: Text(numberofitems.toString() + ' \u20B9 ', style: kListTitleTextStyle, )),
                                      ],
                                    ),
                                  ],
                                ),
                              ),
                            ),
                            Container(
                              margin: EdgeInsets.only(left: 10),
                              child: Row(
                                children: < Widget > [
                                  InkWell(
                                    onTap: onClickDelete,
                                    child: Container(
                                      width: 30, child: Icon(
                                      Icons.remove_circle_outline,
                                      color: Colors.green,
                                      size: 30,
                                    ), ),
                                  ),
                                  Container(
                                    width: 30,
                                    child: Center(child: Text(_count.toString(), style: TextStyle(fontSize: 25), )),
                                  ),
                                  InkWell(
                                    onTap: onClickAdd,
                                    child: Container(
                                      margin: EdgeInsets.only(right: 5),
                                      width: 30, child: Icon(
                                      Icons.add_circle_outline,
                                      color: Colors.green,
                                      size: 30,
                                    ), ),
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      );
                    },
                    itemCount: itemList == null ? 0 : itemList.length,
                  );
                })

Upvotes: 1

Views: 4013

Answers (3)

chunhunghan
chunhunghan

Reputation: 54427

You can copy paste run full code below
Step 1: create Item class
Step 2: change future builder call
Step 3: deal with Inkwell onTap

working demo

enter image description here

code snippet

Future callback;

  @override
  void initState() {
    callback = _getItemList();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var futureBuilder =  FutureBuilder(
      future: callback,

...
InkWell(
                      onTap: () {
                        if (itemList[index].numberofitems > 0) {
                          setState(() {
                            itemList[index].numberofitems =
                                itemList[index].numberofitems - 1;
                          });
                        }
                      },

...
InkWell(
                      onTap: () {
                        setState(() {
                          itemList[index].numberofitems =
                              itemList[index].numberofitems + 1;
                          print(
                              ' ${itemList[index].itemname.toString()} ${itemList[index].numberofitems.toString()}');
                        });
                      },    

full code

import 'dart:async';
import 'dart:collection';

import 'package:flutter/material.dart';

void main() => runApp( MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return  MaterialApp(
      title: 'Flutter Demo',
      theme:  ThemeData(
        primarySwatch: Colors.blue,
      ),
      home:  MyHomePage(),
    );
  }
}

class Item {
  String itemname;
  String itemtype;
  int numberofitems;

  Item({this.itemname, this.itemtype, this.numberofitems});
}

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

class _MyHomePageState extends State<MyHomePage> {
  Future callback;

  @override
  void initState() {
    callback = _getItemList();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var futureBuilder =  FutureBuilder(
      future: callback,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.waiting:
            return  Center(child: CircularProgressIndicator());
          default:
            if (snapshot.hasError)
              return  Text('Error: ${snapshot.error}');
            else
              return createListView(context, snapshot);
        }
      },
    );

    return  Scaffold(
      appBar:  AppBar(
        title:  Text("Home Page"),
      ),
      body: futureBuilder,
    );
  }

  Future<List<Item>> _getItemList() async {
    var values =  List<Item>();
    values.add(
        Item(itemname: "A", itemtype: "assets/images/a.jpg", numberofitems: 0));
    values.add(
        Item(itemname: "B", itemtype: "assets/images/a.jpg", numberofitems: 1));
    values.add(
        Item(itemname: "C", itemtype: "assets/images/a.jpg", numberofitems: 2));

    //throw  Exception("Danger Will Robinson!!!");

    await  Future.delayed( Duration(seconds: 2));

    return values;
  }


  Widget createListView(BuildContext context, AsyncSnapshot snapshot) {
    List<Item> itemList = snapshot.data;
    return  ListView.builder(
        itemCount: itemList.length,
        itemBuilder: (BuildContext context, int index) {
          {
            return Container(
              height: 100,
              margin: EdgeInsets.only(left: 10, right: 10, top: 10),
              decoration: BoxDecoration(
                color: Colors.white70,
                border: Border.all(width: 2.0, color: Colors.blueGrey),
                borderRadius: BorderRadius.circular(6.0),
                boxShadow: [
                  BoxShadow(
                      color: Color(0xFF6078ea).withOpacity(.3),
                      offset: Offset(0.0, 8.0),
                      blurRadius: 8.0),
                ],
              ),
              child: Row(
                children: <Widget>[
                  Container(
                    width: 75,
                    child: ClipRRect(
                      borderRadius:  BorderRadius.circular(10.0),
                      child: Image(
                        image: AssetImage('assets/images/a.jpg'),
                        fit: BoxFit.cover,
                      ),
                    ),
                    margin: EdgeInsets.only(left: 10),
                  ),
                  Expanded(
                    child: Container(
                      child: Column(
                        children: <Widget>[
                          Row(
                            children: <Widget>[
                              Expanded(
                                  child: Container(
                                      margin: EdgeInsets.only(
                                          left: 10, top: 15, bottom: 5),
                                      child: Text(
                                        itemList[index].itemname,
                                      ))),
                              Container(
                                  color: Colors.white,
                                  width: 25,
                                  margin: EdgeInsets.only(
                                      left: 10, top: 15, bottom: 5),
                                  child: Image.asset(itemList[index].itemtype)),
                            ],
                          ),
                          Row(
                            children: <Widget>[
                              Container(
                                  margin: EdgeInsets.only(
                                      left: 10, top: 15, bottom: 5),
                                  child: Text(
                                    'Price : ',
                                  )),
                              Container(
                                  margin: EdgeInsets.only(
                                      left: 10, top: 15, bottom: 5),
                                  child: Text(
                                    itemList[index].numberofitems.toString() +
                                        ' \u20B9 ',
                                  )),
                            ],
                          ),
                        ],
                      ),
                    ),
                  ),
                  Container(
                    margin: EdgeInsets.only(left: 10),
                    child: Row(
                      children: <Widget>[
                        InkWell(
                          onTap: () {
                            if (itemList[index].numberofitems > 0) {
                              setState(() {
                                itemList[index].numberofitems =
                                    itemList[index].numberofitems - 1;
                              });
                            }
                          },
                          child: Container(
                            width: 30,
                            child: Icon(
                              Icons.remove_circle_outline,
                              color: Colors.green,
                              size: 30,
                            ),
                          ),
                        ),
                        Container(
                          width: 30,
                          child: Center(
                              child: Text(
                            itemList[index].numberofitems.toString(),
                            style: TextStyle(fontSize: 25),
                          )),
                        ),
                        InkWell(
                          onTap: () {
                            setState(() {
                              itemList[index].numberofitems =
                                  itemList[index].numberofitems + 1;
                              print(
                                  ' ${itemList[index].itemname.toString()} ${itemList[index].numberofitems.toString()}');
                            });
                          },
                          child: Container(
                            margin: EdgeInsets.only(right: 5),
                            width: 30,
                            child: Icon(
                              Icons.add_circle_outline,
                              color: Colors.green,
                              size: 30,
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            );
          }
          ;
        });
  }
}

Upvotes: 2

Faiq Mustaqeem
Faiq Mustaqeem

Reputation: 96

you need to create list of objects for your Item like.

class Item{
String name;
String description;
int quantity;
double price;
}

and on tap of item, get index of clicked item with new incremented/decremented value and update your list of objects inside setState().

Upvotes: 2

Anirudh Bagri
Anirudh Bagri

Reputation: 2447

You need to wrap your itemBuilder item, i.e the Container with a GestureDetector and then call the onTap() method inside that detector.

Before that, you'll have to convert your item into a stateful widget with a variable to maintain the count of quantity.

Upvotes: 0

Related Questions