В настоящее время я создаю простое приложение со списком продуктов, чтобы использовать его с помощью 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,
''';
}