2

I'm trying to create a layout similar to Android's build in Contacts App, when creating a new contact (or editing one for that matter), in portrait mode the whole view is scroll-able with the user's avatar placed on top of the contact form in a top-to-bottom layout, when you switch to landscape mode however, the layout changes to a side-by-side layout with the avatar taking up the left half of the screen (full height and non scroll-able) and the contact form to the right fully scroll-able independent of the avatar to the left which stays fixed.

I tried implementing this using the flutter_staggered_grid_view library by setting the crossAxisCount in a StaggeredGridView.countBuilder based on the device orientation this will make it so that I can switch between having only 1 item in the cross axis (in portrait mode where there's a vertical layout) to having 2 items in the cross axis (in landscape mode where there's a horizontal layout).

Unfortunately, even though the StaggeredGridView.countBuilder is nested within a OrientationBuilder whenever I switch orientation, the layout doesn't seem to update as if the crossAxisCount property is not dynamic and can not be updated once set.

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,
            );
        },
    )

There's the possibility that Grids aren't the right approach to creating such a layout, if that's the case, I'd appreciate if anyone could point me in the right direction.

Thanks in advance.

effy
  • 410
  • 8
  • 20
  • if anyone want to get different size GridView according to image sizes, read this SO answer here: https://stackoverflow.com/questions/49781657/adjust-gridview-child-height-according-to-the-dynamic-content-in-flutter/54059209#54059209 – Blasanka Jan 06 '19 at 07:23

1 Answers1

3

I think that a better approach would be to play with Row, Column and SingleChildScrollView:

You can try something like this:

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,
        ),
      ),
    );
  }

contact layout

The buildBody function will create the layout above, and you'll have to replace the content of _buildAvatar and _buildFields to fit your needs.

Romain Rastel
  • 5,144
  • 2
  • 25
  • 23
  • This is a layout I've already tried, but because on orientation change the form is rebuilt, and data in the fields are being reset. Would a TextEditController keep the form data persisted after a rebuild? – effy Jul 22 '18 at 08:49
  • 1
    Oh ok, this is off topic for this question and you may need to post another question for that if you want a detailed solution. But yes you have to create TextEditControllers to keep the data inside your `State`. – Romain Rastel Jul 22 '18 at 09:20