在颤动中,身体部位 我有 2 个小部件:1 个 listview.builder 和 1 行,其中包含 2 列,其中有文本。 但不知道如何使用 SingleChildScrollView 和 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),
),
),
],
)),
],
),
),
),
]),
),
我曾尝试将它们与 flex 或sizedBox 一起放入expanded() 中,但没有任何效果。 需要知道如何包装那些东西的答案 这是错误消息: 手势库捕获异常══════════════════════════════════ 无法测试从未布局过的渲染框。
您不能在可滚动小部件内使用
Expanded
。它试图为您的案例消耗无限的高度。您可以使用 LayoutBuilder 来获取父级高度并在每个项目上进行设置。如果要将视图分成两部分并制作单独的可滚动小部件,您可以使用 Column<[Expanded<A>,Expanded<B>]
。用可滚动的小部件包装每个 A
和 B
,而 A
已经有 ListView,您可以忽略 A. 或使用 LayoutBuilder 作为当前方法
body: LayoutBuilder(
builder: (context, constraints) => SingleChildScrollView(
padding: const EdgeInsets.all(10),
child: Column(
children: [
SizedBox(
height: constraints.maxHeight / 2,
child: ListView.builder(
itemCount: 10,
itemBuilder: (context, index) {
// kiểm tra món ăn đó có thuộc bàn này ko
return GestureDetector(
onTap: () {},
child: Container(
height: 50,
color: Colors.red,
child: Text('data'),
),
);
},
),
),
SizedBox(
height: constraints.maxHeight / 2,
child: Row(
children: [
// ------------cột trái--------------
],
),
),
],
),
),
),
您还可以检查 CustomScrollView。