In flutter , bodypart I have 2 widget : 1 listview.builder and 1 row that containt 2 column with text inside. But don't know how to use SingleChildScrollView and resizeToAvoidBottomInset: true,
resizeToAvoidBottomInset: true,
body: SingleChildScrollView(
padding: const EdgeInsets.all(10),
child: Column(children: [
Expanded(
child: ListView.builder(
itemCount: widget.mytable.chitiet.length,
itemBuilder: (context, index) {
// kiểm tra món ăn đó có thuộc bàn này ko
if (widget.mytable.chitiet.isNotEmpty) {
return GestureDetector(
onTap: () {
_showEditPrice(widget.mytable.chitiet[index]);
},
child: ListTile(
contentPadding:
const EdgeInsets.only(left: 10, right: 10),
leading: Text(
'${index + 1}',
style: const TextStyle(fontSize: 20),
),
title: Text(widget.mytable.chitiet[index].meal.name,
style: const TextStyle(fontSize: 18)),
subtitle: Text(
'${money.format(widget.mytable.chitiet[index].meal.price)} x ${widget.mytable.chitiet[index].quantity} ${availableDonViTinh[widget.mytable.chitiet[index].meal.donViTinh]!.data}\n'
'Tổng tiền: ${money.format(widget.mytable.chitiet[index].meal.price * widget.mytable.chitiet[index].quantity)}'),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(Icons.add),
onPressed: () {
setState(() {
widget.mytable.chitiet[index].quantity += 1;
tongtien = widget.mytable.chitiet.fold<double>(
0, (previousValue, currentvalue) {
return previousValue +
currentvalue.meal.price *
currentvalue.quantity;
});
});
},
),
IconButton(
icon: const Icon(Icons.remove),
onPressed: () {
setState(() {
widget.mytable.status;
var oldChitiet = widget.mytable.chitiet
.firstWhere((element) =>
element.meal.name ==
chitietban[index].meal.name);
if (oldChitiet.quantity > 1) {
widget.mytable.chitiet[index].quantity -= 1;
} else if (widget
.mytable.chitiet[index].quantity <=
1) {
// do nothing
}
;
tongtien = widget.mytable.chitiet.fold<double>(
0, (previousValue, currentvalue) {
return previousValue +
currentvalue.meal.price *
currentvalue.quantity;
});
});
},
),
IconButton(
icon: const Icon(Icons.delete),
onPressed: () {
setState(() {
widget.mytable.status;
widget.mytable.chitiet.removeAt(index);
tongtien = widget.mytable.chitiet.fold<double>(
0, (previousValue, currentvalue) {
return previousValue +
currentvalue.meal.price *
currentvalue.quantity;
});
});
},
)
],
),
),
);
} else {
const Center(
child: Text('Không có món ăn'),
);
}
},
),
),
Expanded(
flex: 2,
child: SizedBox(
height: MediaQuery.of(context).size.height - 500,
child: Row(
children: [
// ------------cột trái--------------
Expanded(
flex: 2,
child: Padding(
padding: const EdgeInsets.only(top: 10),
child: Column(
children: [
const Expanded(
flex: 1,
child: Text(
'Nhập số % giảm giá',
style: TextStyle(fontSize: 16),
)),
const SizedBox(height: 10),
Expanded(
flex: 1,
child: TextFormField(
onChanged: (value) {
setState(() {
phantram = tongtien *
double.parse(
discountController.value.text) /
100;
});
},
keyboardType: TextInputType.number,
controller: discountController,
validator: (value) {
if (loaiGiamGia == 'phantram') {
if (int.parse(value!) < 0 ||
int.parse(value!) > 100) {
return 'Giá trị phải nằm trong khoảng từ 0 đến 100';
}
} else {
if (int.parse(value!) < 0) {
return 'Hãy nhập số tiền hợp lệ';
}
}
return null;
},
decoration: const InputDecoration(
contentPadding: EdgeInsets.all(16),
hintText: 'Số tiền/ %',
),
),
),
Expanded(flex: 1, child: Text(''))
],
),
),
),
// ------------cột phải--------------
Expanded(
flex: 3,
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
flex: 1,
child: Text(
'Tạm tính: ${money.format(tongtien)} đ',
style: const TextStyle(
color: Colors.black, fontSize: 18),
),
),
Expanded(
flex: 1,
child: Text(
'Được giảm: ${money.format(phantram + tienmat)} đ',
style: const TextStyle(
color: Colors.black, fontSize: 18),
),
),
Expanded(
child: Text(
'Tổng tiền: ${money.format(tongtien - phantram - tienmat)} đ',
style: const TextStyle(
color: Colors.black, fontSize: 18),
),
),
],
)),
],
),
),
),
]),
),
I had try to put those in expanded() with flex or sizedBox but nothing working. need answer for how to wrap those thing here the error message:
Exception caught by gestures library ══════════════════════════════════
Cannot hit test a render box that has never been laid out.
You can't use
Expanded
inside a scrollable widget. It is trying to consume infinite height for your case. You can use LayoutBuilder for to get the parent height and set on each item. If it is about splitting the view in two and making separate scrollable widget, You can useColumn<[Expanded<A>,Expanded<B>]
. wrap eachA
andB
with scrollable widget, whileA
is already having ListView,you can ignore for A. or with LayoutBuilder as current approachYou may also check CustomScrollView.