0

I have used SingleChildScrollView in many places of my app and everything is fine. However, it cannot scroll to the bottom of the column when the keyboard pops up in the scenario below.

Future<void> _showCupertinoModalBottomSheet() async {
    final Size screenSize = MediaQuery.of(context).size;

    await showCupertinoModalPopup(
        context: context,
        builder: (BuildContext context) {
          return Container(
            height: screenSize.height * 0.8,
            color: CupertinoColors.white,
            child: Column(
              children: <Widget>[
                CupertinoTextField(
                ),
                Expanded(
                  child: SingleChildScrollView(
                    child: Column(
                      children: <Widget>[
                        //List of widgets
                      ],
                    ),
                  ),
                ),
              ],
            ),
          );
        });
  }

I have no idea why it is scrollable but cannot scroll to the bottom, and some contents are hidden by the keyboard.

Any help is appreciated!

Cassie Liu
  • 195
  • 2
  • 17

3 Answers3

2

As a last resort, maybe try adding a SizedBox widget as the last child of your SingleChildScrollView. Alternatively, you could wrap it in Padding. Either way, set the top padding parameter or height parameter of the SizedBox to MediaQuery.of(context).size.height / x. X being an adjustable value that you can mess around with to try to get the percentage of the height of screen it isn't scrolling down to. This will push everything else up a certain amount.

Again, this is 'hacky', so use it only if you can't find another solution.

Also maybe try setting these in your Scaffold, they may help:

resizeToAvoidBottomInset: false,
resizeToAvoidBottomPadding: false,

Also changing your stateless widget into a stateful widget sometimes helps.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Matthew Trent
  • 2,611
  • 1
  • 17
  • 30
  • Thank you for your help! Unfortunately the first two solutions don't work in my case and I'm already using a stateful widget. May I ask why this problem occurs? Does it have anything to do with CupertinoModalPopup? – Cassie Liu Aug 27 '20 at 09:50
  • @CassieLiu I believe it's because of some wacky box constraints, but I'm not entirely sure. – Matthew Trent Aug 27 '20 at 19:38
2

Adding a padding widget works

Future<void> _showCupertinoModalBottomSheet() async {
  final Size screenSize = MediaQuery.of(context).size;
  await showCupertinoModalPopup(
    context: context,
    builder: (BuildContext context) {
      return Padding(
        padding: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
        ),
        child: Container(
          height: screenSize.height * 0.8,
          color: CupertinoColors.white,
          child: Column(
            children: <Widget>[
              CupertinoTextField(),
              Expanded(
                child: SingleChildScrollView(
                  child: Column(
                    children: <Widget>[
                      for (int i = 0; i < 50; i++) Text(i.toString())
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    },
  );
}
Mr Random
  • 1,992
  • 7
  • 20
  • Child of Expanded should be one of (Row, Column, or Flex) only, ref: https://api.flutter.dev/flutter/widgets/Expanded-class.html – AnasSafi Jan 03 '22 at 10:59
0

How I fixed mine:

I wrapped my widgets with a SingleChildScrollView and removed the resizeToAvoidBottomInset property from the Scaffold.