颤振-不可滚动网格

时间:2019-10-05 12:57:13

标签: flutter flutter-layout

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

给你大局-

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

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

2)想法相同,但是有3行,每行由3个较小的容器组成。 这将创建一个网格。尽管网格本身不可滚动,并且网格的大小将取决于其子级,但这非常重要。仅应将其与SingleChildScrollView中包含的页面的其余部分一起滚动。

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

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

enter image description here

3 个答案:

答案 0 :(得分:2)

您可以为其创建自定义小部件,这是从我正在处理的 library 创建不可滚动网格小部件的代码。

import 'package:flutter/material.dart';

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

  final int columnCount;
  final List<Widget> children;
  final double? gap;
  final EdgeInsets? padding;
  final EdgeInsets? margin;
  final bool expanded;
  final MainAxisAlignment rowMainAxisAlignment;
  final CrossAxisAlignment rowCrossAxisAlignment;

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

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

    for (int i = 0; i < rowCount; i++) {
      final List<Widget> columns = _createColumns(i, childrenLength);

      rows.add(
        expanded
            ? Expanded(
                child: Row(
                  mainAxisAlignment: rowMainAxisAlignment,
                  crossAxisAlignment: rowCrossAxisAlignment,
                  children: columns,
                ),
              )
            : Row(
                mainAxisAlignment: rowMainAxisAlignment,
                crossAxisAlignment: rowCrossAxisAlignment,
                children: columns,
              ),
      );

      if (i != rowCount - 1) rows.add(SizedBox(height: gap));
    }

    return rows;
  }

  List<Widget> _createColumns(int rowIndex, int childrenLength) {
    final List<Widget> columns = [];

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

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

    return columns;
  }
}

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

GoogleGrid(
  gap: 16,
  padding: const EdgeInsets.all(16),
  children: [
    Text("1"),
    Text("2"),
    Text("3"),
    Text("4"),
    Text("5"),
    Text("6"),
  ],
);

答案 1 :(得分:1)

像这样吗?

comboBox2.SelectedIndex = 0;

答案 2 :(得分:1)

与GridView(janstol的答案)相比,table widget可能是一种更简单的方法,因为它是为您要查找的内容而专门设计的。尽管这不适用于您的情况,但如果您的窗口小部件可以使用不同的大小,则Table尤其有用-它会垂直和水平对齐窗口小部件以分别匹配每行/列中最宽/最高的窗口小部件。

这里将janstol的解决方案代码重写为使用Table。请注意,表格要求所有行的长度都相同,因此前两个元素行必须位于表格之外。

Widget bigBox = 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),
                  ),
                ),
              ),
            ),
          );
          Widget smallBox = 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),
                  ),
                ),
              ),
            );
          return Scaffold(
            body: SingleChildScrollView(
              child: Column(
                children: [
                  Row(
                    children: List.filled(2, bigBox),
                  ),
                  Container(
                    child: Table(
                      children: List.filled(
                          // 7 rows instead of 3 just to demonstrate the scrolling functionality
                          7,
                          TableRow(
                            children: List.filled(3, smallBox),
                          )
                      ),
                    ),
                  ),
                ],
              ),
            ),