Повторно открыть модальный нижний лист с текущим состоянием в текстовых полях Flutter
У меня есть простое приложение, в котором пользователь может добавить товар в список перед тем, как отправиться в магазин, а затем, добавив товар в свою корзину, у них есть возможность нажать на товар и изменить его стоимость. Сумма всех элементов отображается внизу экрана. Цель здесь - дать пользователю возможность составить бюджет и узнать общую стоимость своего списка покупок ДО того, как добраться до кассы.
Проблема, с которой я столкнулся, разбита на две части, и этот пост охватывает только первую часть. Когда пользователь нажимает FAB, открывается нижний модальный лист, где пользователь вводит элемент / количество, и после нажатия кнопки "Добавить элемент" элемент добавляется в ListView.
Моя цель состоит в том, чтобы, когда пользователь нажимает плитку списка, тот же самый модальный нижний лист открывался с ТЕКУЩИМ состоянием объекта, отображаемого в текстовых полях (часть 2 будет включать редактирование значений).
Мой вопрос: нужно ли мне создать отдельный метод, который будет отображать НОВЫЙ модальный нижний лист, или я могу использовать существующий, показанный здесь, передав экземпляр ItemModel
как ребенок, затем передавая какой-то метод редактирования в качестве аргумента?
Модель элемента
import 'package:flutter/material.dart';
class ItemModel {
String groceryItem;
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,
''';
}
Виджет нового предмета
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,
),
),
],
),
),
);
}
}
Виджет списка покупок
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);
});
print(_userItems);
_addTotalCost();
}
//Initiate bottom modal sheet
void _startAddNewItem(BuildContext ctx) {
showModalBottomSheet(
context: ctx,
builder: (_) {
return GestureDetector(
child: NewItem(_addNewItem),
);
},
);
}
//Method to get current state
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: () {
//Method to re-open Modal bottom sheet
},
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,
);
}