Flutter 在点击的索引处更新数据 onClick

Posted

技术标签:

【中文标题】Flutter 在点击的索引处更新数据 onClick【英文标题】:Flutter update data onClick at clicked index 【发布时间】:2020-04-14 10:52:20 【问题描述】:

我正在构建一个食品车应用程序,并在菜单项页面上有一个查询。

我的菜单项页面包含一个列表视图,其中显示每个项目的描述以及指定项目数量的选项(1、2、3....)

现在我可以增加或减少单个项目的项目计数,但不确定如何在用户单击的特定索引处的列表视图中执行此操作。

有人可以帮我解决这个问题吗?

到目前为止我所做的代码如下:

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,
                  );
                )

【问题讨论】:

【参考方案1】:

您可以在下面复制粘贴运行完整代码 第 1 步:创建 Item 类 第 2 步:更改未来的构建器调用 第 3 步:处理 Inkwell onTap

工作演示

代码sn-p

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()');
                        );
                      ,    

完整代码

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,
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            );
          
          ;
        );
  

【讨论】:

你成就了我的一天。谢谢:)【参考方案2】:

您需要为您的项目创建对象列表。

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

在点击项目时,使用新的递增/递减值获取单击项目的索引,并更新 setState() 中的对象列表。

【讨论】:

【参考方案3】:

您需要用GestureDetector 包装您的itemBuilder 项目,即容器,然后在该检测器中调用onTap() 方法。

在此之前,您必须将您的项目转换为带有变量的有状态小部件以保持数量计数。

【讨论】:

以上是关于Flutter 在点击的索引处更新数据 onClick的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 源码分析(二十) 指令篇 v-once指令详解

如何在 Dart (Flutter) 中获取每个可迭代值的索引号

带有 Flutter 更新的 Android Studio 导致了索引循环

Flutter:更新列表中的特定索引(Firestore)

Firebase once() 方法不等待 Flutter

在预定义索引处将数据行添加到数据表