Flutter - 不可滚动的网格

Roy*_*hal 7 flutter flutter-layout

有没有一种方法可以构建一个本身不可滚动的网格,其大小取决于其子项,就像我们可以在行或列中指定 mainAxisSize: MainAxisSize.min 一样?

给你一张大图——

我正在尝试创建一个取决于设备宽度的响应式布局。它应该分为 2 部分,通过一列无缝连接。

1) 2 个大容器,其大小取决于屏幕宽度,考虑到它们之间的小空间。每个容器的宽度和高度都相同(方形容器)。

2)相同的想法,但有 3 行,每行由 3 个较小的容器组成。这将创建一个网格。尽管网格本身不可滚动并且其大小将根据其子项而定,但这一点非常重要。它应该只与包含在 SingleChildScrollView 中的页面的其余部分一起滚动。

尤其是因为每个容器的高度都需要与其宽度相同,所以我考虑将行、列和 LayoutBuilder 结合使用 - 它们为我提供了我需要的所有功能。

但是,在手动操作之前,我想知道是否有一些可以开箱即用的东西。

在此处输入图片说明

jan*_*tol 23

像这样的东西?

SingleChildScrollView(
  child: Column(
    children: <Widget>[
      Row(
        children: <Widget>[
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(10.0),
              child: AspectRatio(
                aspectRatio: 1.0,
                child: Container(
                  width: double.infinity,
                  decoration: BoxDecoration(
                    border: Border.all(width: 3.0, color: Colors.green),
                  ),
                ),
              ),
            ),
          ),
          Expanded(
            child: Padding(
              padding: const EdgeInsets.all(10.0),
              child: AspectRatio(
                aspectRatio: 1.0,
                child: Container(
                  width: double.infinity,
                  decoration: BoxDecoration(
                    border: Border.all(width: 3.0, color: Colors.green),
                  ),
                ),
              ),
            ),
          ),
        ],
      ),
      Container(
        padding: const EdgeInsets.all(10.0),
        child: GridView.builder(
          physics: NeverScrollableScrollPhysics(),
          shrinkWrap: true,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 3,
            childAspectRatio: 1.0,
            mainAxisSpacing: 10.0,
            crossAxisSpacing: 10.0,
          ),
          itemCount: 21,
          itemBuilder: (context, index) {
            return Container(
              decoration: BoxDecoration(
                border: Border.all(width: 3.0),
              ),
            );
          },
        ),
      ),
    ],
  ),
)
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢你的人。我花了将近 10 个小时来做​​这个.......再次感谢伙计。 (2认同)

Nha*_*tVM 6

对于我的情况,我使用 **

NeverScrollableScrollPhysics()

**

GridView.builder(
    gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 2,
    ),
    itemCount: listPaymentMethods.length,
    primary: false,
    physics: const NeverScrollableScrollPhysics(),
    itemBuilder: (context, index) {
      final paymentMethod = listPaymentMethods[index];
      bool isSelected = paymentMethod.code == selectedPaymentMethod?.code;
      return PaymentMethodItemWidget(
          paymentMethod: paymentMethod,
          onPaymentMethodChanged: onPaymentMethodChanged,
          isSelected: isSelected);
    });
Run Code Online (Sandbox Code Playgroud)


Edw*_*man 5

您可以为其创建自定义小部件

import 'package:flutter/material.dart';

class StaticGrid extends StatelessWidget {
  const StaticGrid({
    Key? key,
    this.columnCount = 2,
    this.gap,
    this.padding,
    this.columnMainAxisAlignment = MainAxisAlignment.start,
    this.columnCrossAxisAlignment = CrossAxisAlignment.center,
    this.rowMainAxisAlignment = MainAxisAlignment.start,
    this.rowCrossAxisAlignment = CrossAxisAlignment.center,
    required this.children,
  }) : super(key: key);

  final int columnCount;
  final double? gap;
  final EdgeInsets? padding;
  final MainAxisAlignment columnMainAxisAlignment;
  final CrossAxisAlignment columnCrossAxisAlignment;
  final MainAxisAlignment rowMainAxisAlignment;
  final CrossAxisAlignment rowCrossAxisAlignment;
  final List<Widget> children;

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: padding,
      child: Column(
        crossAxisAlignment: columnCrossAxisAlignment,
        mainAxisAlignment: columnMainAxisAlignment,
        children: _createRows(),
      ),
    );
  }

  List<Widget> _createRows() {
    final List<Widget> rows = [];
    final childrenLength = children.length;
    final rowCount = (childrenLength / columnCount).ceil();

    for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
      final List<Widget> columns = _createCells(rowIndex);
      rows.add(
        Row(
          crossAxisAlignment: rowCrossAxisAlignment,
          mainAxisAlignment: rowMainAxisAlignment,
          children: columns,
        ),
      );
      if (rowIndex != rowCount - 1) {
        rows.add(SizedBox(height: gap));
      }
    }

    return rows;
  }

  List<Widget> _createCells(int rowIndex) {
    final List<Widget> columns = [];
    final childrenLength = children.length;

    for (int columnIndex = 0; columnIndex < columnCount; columnIndex++) {
      final cellIndex = rowIndex * columnCount + columnIndex;
      if (cellIndex <= childrenLength - 1) {
        columns.add(Expanded(child: children[cellIndex]));
      } else {
        columns.add(Expanded(child: Container()));
      }

      if (columnIndex != columnCount - 1) {
        columns.add(SizedBox(width: gap));
      }
    }

    return columns;
  }
}

Run Code Online (Sandbox Code Playgroud)

使用方法与使用列或行小部件相同,您可以定义列数、间隙、填充和边距。

StaticGrid(
  gap: 16,
  padding: const EdgeInsets.all(16),
  children: [
    Text("1"),
    Text("2"),
    Text("3"),
    Text("4"),
    Text("5"),
    Text("6"),
  ],
);
Run Code Online (Sandbox Code Playgroud)