4

In the picture below, what I'm trying to achieve, is let the Green part Scrollable, since, in case the keyboard pops up, it doesn't give me the render error.

The whole screen is just a Column, where yellow part is a custom widget, and green part another Column inside it.

I've tried different solutions. Wrap the whole Column into a SingleChildScrollView, but I would like that yellow part would stay fixed at the top. I've tried also wrapping only green part into a SingleChildScrollView, but it doesn't work (The Render Error still raised).

I've seen I could use SliverAppBar, but I would like to achieve using my custom widget (yellow part).

I am a little bit stuck.

Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            AppBarWidget(height: size.height * 0.15),
            Container(
              height: size.height - size.height * 0.15 - mediaQuery.padding.top,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  EditableAvatarWidget(
                    circleRadius: circleRadius,
                    badge: test,
                    border: Border.all(color: test.mainColor, width: 5),
                  ),
                  Column(
                    children: [
                      Text(
                        "Name Surname",
                        style: TextStyle(
                            fontWeight: FontWeight.bold,
                            fontSize: 26,
                            color: Global.blackGrey),
                      ),
                      SizedBox(height: 10),
                      Text(
                        "mail@mail.com",
                        style: TextStyle(fontSize: 18, color: Colors.grey),
                      )
                    ],
                  ),
                  Padding(
                    padding: EdgeInsets.symmetric(
                        horizontal: size.width / 6, vertical: 0),
                    child: FlatCustomButton(
                      onPress: () {},
                      background: Global.editProfileButton,
                      text: "Edit profile",
                      textColor: Global.blackGrey,
                      inkwellColor: Colors.black,
                    ),
                  )
                ],
              ),
            ),
          ],
        ),
      ),
    );

I would maybe also think to implement a ListView (?), but as you can see I've set inside the Column the mainAxisAlignment: MainAxisAlignment.spaceAround to have already my UI preference.

Do you have any idea how I could achieve this?

TL;DR: Let scrollable only GreenPart (Column) that belong to another Column (Whole Screen) and let Yellow Part stay on that fixed position

Picture

Tizianoreica
  • 2,142
  • 3
  • 28
  • 43

3 Answers3

6

That's how I fixed.

I've encapsulated the Green Column Part in a Expanded before and then into a SingleChildScrollView. It works exactly how I wanted.

Now only the green part scroll, and the yellow part stays in a fixed position when keyboard appears.

 return Scaffold(
      body: SafeArea(
        child: Column(
          children: [
            AppBarWidget(
              height: size.height * 0.15,
            ),
            Expanded( //This 
              child: SingleChildScrollView( // and this fixed my issue
                child: Container(
                  height:
                      size.height - size.height * 0.15 - mediaQuery.padding.top,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      EditableAvatarWidget(
                        circleRadius: circleRadius,
                        badge: test,
                        border: Border.all(color: test.mainColor, width: 5),
                      ),
                      Column(
                        children: [
                          Text(
                            "Name Surname",
                            style: TextStyle(
                                fontWeight: FontWeight.bold,
                                fontSize: 26,
                                color: Global.blackGrey),
                          ),
                          SizedBox(height: 10),
                          Text(
                            "mail@mail.com",
                            style: TextStyle(fontSize: 18, color: Colors.grey),
                          )
                        ],
                      ),
                      Padding(
                        padding: EdgeInsets.symmetric(
                            horizontal: size.width / 6, vertical: 0),
                        child: FlatCustomButton(
                          onPress: () {},
                          background: Global.editProfileButton,
                          text: "Edit profile",
                          textColor: Global.blackGrey,
                          inkwellColor: Colors.black,
                        ),
                      )
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ),
    );
Toothgip
  • 469
  • 6
  • 14
Tizianoreica
  • 2,142
  • 3
  • 28
  • 43
  • 1
    Simple yet effective! `Column(View1, Expanded(ScrollableView2), View3)` – om-ha Jun 14 '22 at 13:10
  • Just make sure to remove `Spacer()` as that's redundant with `SingleChildScrollView()`, both implies unbounded height thus one should be used only. – om-ha Jun 14 '22 at 13:10
1

You can use SliverAppBar like you have already tried, but inside that you have flexibleSpaceBar which has background property that can accept any kind of Widget.

A sample code is here.

Anirudh Bagri
  • 2,346
  • 1
  • 21
  • 33
1

If you can set a fixed height to the Column inside the SingleChildScrollView, that's probably the best, even if it involves a bit of "hacking" as in the fix you provided.

However, when you need flexible/expanding content in the Column, you can consider using a ConstrainedBox with IntrinsicHeight inside the SingleChildScrollView as the SingleChildScrollView's documentation describes.

I've found that for relatively simple screens this works well. E.g. where you really only need scrolling if you have an input field and the keyboard pops up, as in your code.

LayoutBuilder(
    builder: (BuildContext context, BoxConstraints viewportConstraints) {
      return SingleChildScrollView(
        child: ConstrainedBox(
          constraints: BoxConstraints(
            minHeight: viewportConstraints.maxHeight,
          ),
          child: IntrinsicHeight(
            child: Column(
              children: <Widget>[
              ...

Note: with more complex screens, IntrinsicHeight might be too costly, see its docs for more info.

ezmegy
  • 605
  • 6
  • 17