flutter RenderFlex的孩子们,如何 Package 一列的列表视图和行与列在侧挂hildscrollview

wgxvkvu9  于 12个月前  发布在  Flutter
关注(0)|答案(2)|浏览(91)

在Flutter,身体部分我有2小部件:1个listview.builder和1个包含2列的行,其中包含文本。但是不知道如何使用SingleChildScrollView和resizeToAvoidBottomInset:真的,

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()中,但没有效果。需要回答如何 Package 这些东西在这里的错误消息:

Exception caught by gestures library ══════════════════════════════════
Cannot hit test a render box that has never been laid out.
ezykj2lf

ezykj2lf1#

您不能在可滚动的小部件中使用Expanded。它试图为你的案子消耗无限的高度。您可以使用LayoutBuilder来获取父高度并在每个项目上设置。如果它是关于分裂的两个视图和单独的滚动部件,您可以使用Column<[Expanded<A>,Expanded<B>] .使用可滚动的小部件 Package 每个AB,而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。

q3aa0525

q3aa05252#

只需将顶部的Column Package 到一个容器中,然后通过MediaQuery给予它一个屏幕高度,就可以了

return Scaffold(
  resizeToAvoidBottomInset: true,
  body: SingleChildScrollView(
    padding: const EdgeInsets.all(10),
    child: Container(
      height: MediaQuery.of(context).size.height,
      child: Column(
        children: [
          Expanded(
            child: ListView.builder(
              itemCount: mytable.length,
              itemBuilder: (context, index) {
                // kiểm tra món ăn đó có thuộc bàn này ko
                if (mytable.isNotEmpty) {
                  return GestureDetector(
                    onTap: () {},
                    child: ListTile(
                      contentPadding:
                          const EdgeInsets.only(left: 10, right: 10),
                      leading: Text(
                        '${index + 1}',
                        style: const TextStyle(fontSize: 20),
                      ),
                      title: Text("name",
                          style: const TextStyle(fontSize: 18)),
                      subtitle: Text('Tổng'),
                      trailing: Row(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          IconButton(
                            icon: const Icon(Icons.add),
                            onPressed: () {},
                          ),
                          IconButton(
                            icon: const Icon(Icons.remove),
                            onPressed: () {},
                          ),
                          IconButton(
                            icon: const Icon(Icons.delete),
                            onPressed: () {},
                          )
                        ],
                      ),
                    ),
                  );
                } 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) {},
                              keyboardType: TextInputType.number,
                              controller: TextEditingController(),
                              validator: (value) {},
                              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 ',
                              style: const TextStyle(
                                  color: Colors.black, fontSize: 18),
                            ),
                          ),
                          Expanded(
                            flex: 1,
                            child: Text(
                              'Được giả',
                              style: const TextStyle(
                                  color: Colors.black, fontSize: 18),
                            ),
                          ),
                          Expanded(
                            child: Text(
                              'Tổng tiền:',
                              style: const TextStyle(
                                  color: Colors.black, fontSize: 18),
                            ),
                          ),
                        ],
                      )),
                ],
              ),
            ),
          ),
        ],
      ),
    ),
  ),
);

相关问题