Изменить значения (состояние обновления) списка объектов Flutter - PullRequest
0 голосов
/ 20 апреля 2020

В настоящее время я создаю простое приложение со списком продуктов, чтобы использовать его с помощью Flutter. По сути, пользователь (я) будет иметь возможность добавлять продуктовые элементы в список до того, как отправиться за покупками, и, когда они будут брать каждый элемент, будет возможность выбрать его из списка, и после нажатия на элемент списка он получит возможность редактировать цену каждого товара. Общая стоимость складывается и отображается внизу. Цель этого - в целях составления бюджета, поскольку у меня всегда была проблема с захватом слишком многих вещей и удивлением, когда я добирался до кассы.

Я пытаюсь добавить функцию редактирования и не могу понять, как это сделать. У меня есть список объектов, к которым мне А. нужно получить доступ, Б. отобразить выбранный объект на нижнем модальном листе и C. У меня есть возможность обновить значения перед сохранением обновленного элемента.

Я попытался написать метод, который устанавливает текущие значения, равные выбранному объекту:

    final updatedItem = ItemModel(
      amount: _userItems[index].amount,
      groceryItem: _userItems[index].groceryItem,
      isEditing: true,
    );
    setState(() {
      _userItems[index] = updatedItem;
    });
    print(updatedItem);
  }

У меня есть получил доступ к выбранному объекту, но я просто не очень уверен, откуда go отсюда. Двигаясь вперед, мне нужен нижний модальный лист, чтобы открыть обратно и отобразить значения выбранного объекта и соответственно отредактировать эти значения. Я думаю, что мне нужно написать отдельный метод, который позволяет фактически обновлять значения? Вот мой код:

Виджет списка покупок:

import 'package:shopping_list_project/components/new_item.dart';
import 'package:shopping_list_project/models/item_model.dart';

class ShoppingListView extends StatefulWidget {
  @override
  _ShoppingListViewState createState() => _ShoppingListViewState();
}

class _ShoppingListViewState extends State<ShoppingListView> {
  static List<ItemModel> _userItems = [];
  static var sum = 0.0;

  //Method to add new item
  void _addNewItem(String item, double itemAmount) {
    final newItem = ItemModel(
      amount: itemAmount,
      groceryItem: item,
    );

    setState(() {
      _userItems.add(newItem);
    });
    _addTotalCost();
  }

  //Initiate bottom modal sheet
  void _startAddNewItem(BuildContext ctx) {
    showModalBottomSheet(
      context: ctx,
      builder: (_) {
        return GestureDetector(
          child: NewItem(_addNewItem),
        );
      },
    );
  }

  // Method to add total
  void _addTotalCost() {
    double tempSum = 0.0;
    for (var i = 0; i < _userItems.length; i++) {
      tempSum += _userItems[i].amount;
    }
    setState(() {
      sum = tempSum;
    });
  }

  void _handleEdit(int index) {
    final updatedItem = ItemModel(
      amount: _userItems[index].amount,
      groceryItem: _userItems[index].groceryItem,
      isEditing: true,
    );
    setState(() {
      _userItems[index] = updatedItem;
    });
    print(updatedItem);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Shopping list'),
      ),
      body: _userItems.length == 0
          ? Center(
              child: Container(
                child: Text(
                  'No items added yet!',
                  style: TextStyle(fontSize: 25.0),
                ),
              ),
            )
          : Column(
              children: <Widget>[
                Expanded(
                  child: _buildItemTile(),
                ),
                _buildTotalCard(),
              ],
            ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          _startAddNewItem(context);
        },
      ),
    );
  }

  ListView _buildItemTile() {
    return ListView.builder(
      itemBuilder: (context, index) {
        return GestureDetector(
          onTap: () {
            _handleEdit(index);
          },
          child: Container(
            padding: EdgeInsets.all(3.0),
            child: Card(
              child: ListTile(
                leading: Checkbox(
                  value: _userItems[index].isSelected,
                  onChanged: (bool val) {
                    setState(() {
                      _userItems[index].isSelected = val;
                    });
                  },
                ),
                title: Center(
                  child: Text(_userItems[index].groceryItem),
                ),
                trailing:
                    Text('\$${_userItems[index].amount.toStringAsFixed(2)}'),
              ),
            ),
          ),
        );
      },
      itemCount: _userItems.length,
    );
  }

  Row _buildTotalCard() {
    return Row(
      children: <Widget>[
        Expanded(
          child: Container(
            decoration: BoxDecoration(
              color: Colors.grey[300],
            ),
            padding: EdgeInsets.all(50.0),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                Container(
                  padding: EdgeInsets.all(10.0),
                  child: Text(
                    'Total',
                    style: TextStyle(fontSize: 20.0),
                  ),
                ),
                Container(
                  padding: EdgeInsets.all(5.0),
                  child: Text(
                    '\$${sum.toStringAsFixed(2)}',
                    style: TextStyle(fontSize: 35.0),
                  ),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

Виджет нового товара:

import 'package:shopping_list_project/models/item_model.dart';

class NewItem extends StatefulWidget {
  final Function addNewItm;

  NewItem(this.addNewItm);

  @override
  _NewItemState createState() => _NewItemState();
}

class _NewItemState extends State<NewItem> {
  TextEditingController itemController = TextEditingController();
  TextEditingController amtController = TextEditingController();

  void submitData() {
    String enteredItem = itemController.text;
    double enteredAmount = double.tryParse(amtController.text) ?? 0.0;

    if (enteredItem.isEmpty) {
      return;
    }

    widget.addNewItm(
      enteredItem,
      enteredAmount,
    );

    Navigator.of(context).pop();
  }

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 5,
      child: Container(
        padding: EdgeInsets.all(35.0),
        child: Column(
          children: <Widget>[
            TextField(
              controller: itemController,
              decoration: InputDecoration(labelText: 'Item'),
              onSubmitted: (_) => submitData(),
            ),
            TextField(
              controller: amtController,
              decoration: InputDecoration(labelText: 'Amount'),
              onSubmitted: (_) => submitData(),
            ),
            Container(
              padding: EdgeInsets.all(20.0),
              child: RaisedButton(
                padding: EdgeInsets.all(15.0),
                child: Text('Add item'),
                onPressed: submitData,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Модель товара:

import 'package:flutter/material.dart';

class ItemModel {
  final String groceryItem;
  final double amount;
  bool isSelected = false;
  bool isEditing = false;

  ItemModel({this.groceryItem, this.amount, this.isSelected = false, this.isEditing});

  String toString() => '''

  groceryItem: $groceryItem,
  amount: $amount,
  isSelected: $isSelected,
  isEditing: $isEditing,

  ''';
}
...