当项目具有动态高度时,如何根据设备方向创建动态颤动网格布局

Posted

技术标签:

【中文标题】当项目具有动态高度时,如何根据设备方向创建动态颤动网格布局【英文标题】:How do I create a dynamic flutter grid layout based on device orientation when the items have dynamic height 【发布时间】:2018-12-29 23:51:58 【问题描述】:

我正在尝试创建一个类似于 android 在联系人应用程序中构建的布局,在创建新联系人(或为此编辑联系人)时,在纵向模式下,整个视图可以滚动,用户的头像放在顶部在从上到下布局中的联系表单中,当您切换到横向模式时,布局会更改为并排布局,头像占据屏幕的左半部分(全高且非滚动-能够)和右侧的联系表格完全可滚动,独立于左侧的头像保持固定。

我尝试使用 flutter_staggered_grid_view 库通过根据设备方向在StaggeredGridView.countBuilder 中设置crossAxisCount 来实现这一点,这样我就可以在交叉轴上只有一个项目之间切换(在纵向模式下有一个垂直布局)到在横轴上有 2 个项目(在有水平布局的横向模式下)。

不幸的是,即使StaggeredGridView.countBuilder 在我切换方向时嵌套在OrientationBuilder 中,布局似乎也不会更新,就好像crossAxisCount 属性不是动态的,并且一旦设置就无法更新。

body: OrientationBuilder(
    builder: (context, or) 
        int cac = (or == Orientation.portrait) ? 1 : 2;
            return StaggeredGridView.countBuilder(
                controller: _listViewScrollController,
                itemBuilder: (BuildContext context, int index)
                    return _view[index];
                ,
                itemCount: 2,
                crossAxisCount: cac,
                staggeredTileBuilder: (int index) 
                    return StaggeredTile.fit(cac);
                ,
                scrollDirection: Axis.vertical,
            );
        ,
    )

网格可能不是创建此类布局的正确方法,如果是这种情况,如果有人能指出正确的方向,我将不胜感激。

提前致谢。

【问题讨论】:

如果有人想根据图像大小获得不同大小的 GridView,请在此处阅读此 SO 答案:***.com/questions/49781657/… 【参考方案1】:

我认为更好的方法是使用RowColumnSingleChildScrollView

你可以试试这样的:

Widget buildBody(BuildContext context) 
    return OrientationBuilder(builder: (context, orientation) 
      if (orientation == Orientation.portrait) 
        return SingleChildScrollView(
          child: Column(
            children: <Widget>[
              _buildAvatar(context, orientation),
              _buildFields(context),
            ],
          ),
        );
       else 
        return Row(
          children: <Widget>[
            _buildAvatar(context, orientation),
            Expanded(
              child: SingleChildScrollView(
                child: _buildFields(context),
              ),
            ),
          ],
        );
      
    );
  

  Widget _buildAvatar(BuildContext context, Orientation orientation) 
    return Container(
      height: 300.0,
      width: orientation == Orientation.landscape ? 300.0 : null,
      color: Colors.blue,
      child: Center(
        child: CircleAvatar(
          backgroundColor: Colors.white,
          child: Text('RR'),
        ),
      ),
    );
  

  Widget _buildFields(BuildContext context) 
    return Container(
      height: 800.0,
      color: Colors.white,
      child: Center(
        child: Container(
          height: 250.0,
          width: 250.0,
          color: Colors.red,
        ),
      ),
    );
  

buildBody 函数将创建上面的布局,您必须替换 _buildAvatar_buildFields 的内容以满足您的需要。

【讨论】:

这是我已经尝试过的布局,但是因为在方向更改时会重新构建表单,并且正在重置字段中的数据。 TextEditController 会在重建后保留表单数据吗? 哦,好吧,这不是这个问题的主题,如果你想要一个详细的解决方案,你可能需要为此发布另一个问题。但是是的,您必须创建 TextEditControllers 以将数据保存在您的 State 中。

以上是关于当项目具有动态高度时,如何根据设备方向创建动态颤动网格布局的主要内容,如果未能解决你的问题,请参考以下文章

颤动中具有相同单元格高度的动态交错网格

如何根据其中的内容创建具有动态高度的集合视图?

在垂直列表视图中颤动动态高度水平列表视图

如何让 Storyboard 支持 UICollectionView 中动态大小的单元格?

具有动态高度的集合视图水平方向

iOS - 在旋转时使用动态单元格高度重绘 TableViewCells