1

I'm trying to scroll a whole page. This is the code I have:

SingleChildScrollView(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container(
              color: Colors.white.withOpacity(0.95),
              width: 400,
              height: 400,
              child: Text("")),
          Flexible(
            child: ListView(
              physics: NeverScrollableScrollPhysics(),
              shrinkWrap: true,
              children: posts3,
            ),
          ),
        ],
      ),
    );

This is the error message I get:

A RenderFlex overflowed by 1162 pixels on the bottom.

I think it's because it's not possible to scroll.

How to make the screen scrollable?

Thank you very much!

UPDATE: I use the SingleChildScrollView in a Column, maybe that's the problem?

1 Answer 1

1

From your comments, you would like to have the entire view scrollable and have a ListView inside, here is an example widget doing just that using Flexible (I left ScrollConfiguration wrapper as you might want to know about, but you can remove that parent for your needs):

import 'package:flutter/material.dart';
import 'package:hybrid/@core/constants/nav_bar_index.dart';
import 'package:hybrid/@core/util/ui_util.dart';
import 'package:hybrid/screens/courses/course_details.dart';
import 'package:hybrid/screens/courses/shared/state_card.dart';
import 'package:hybrid/screens/courses/shared/state_model.dart';
import 'package:hybrid/screens/courses/shared/state_util.dart';
import 'package:hybrid/screens/shared/app_bar.dart';
import 'package:hybrid/screens/shared/nav_bar.dart';
import 'package:hybrid/screens/shared/scroll_behavior.dart';

const _grandCourseId = 'ILXBlsKJW8Cdqk27MTq5';

class Courses extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _CoursesState();
}

class _CoursesState extends State<Courses> {
  List<StateModel> _states;
  var _scaffoldKey = new GlobalKey<ScaffoldState>();

  @override
  void initState() {
    super.initState();
    _states = StateUtil.buildStatesList();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar: BmsAppBar(),
      body: Center(
          child: Stack(
        children: <Widget>[
          Container(
            decoration: UIUtil.getDecorationBg(),
          ),
          Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _buildStatesListView(),
            ],
          ),
        ],
      )),
      bottomNavigationBar: NavBar(index: NavBarIndex.Courses),
    );
  }

  Widget _buildStatesListView() {
    return ScrollConfiguration(
      behavior: ScrollBehaviorHideSplash(),
      child: Flexible(
        child: ListView.builder(
          itemCount: _states.length,
          itemBuilder: (BuildContext context, int index) {
            return GestureDetector(
              onTap: () {
                if (_states[index].name.toLowerCase() == 'california') {
                  _navigateCourseDetails(context);
                  return;
                }
                _showInSnackBar(
                    'Courses in ${_states[index].name} Coming Soon!');
              },
              child: StateCard(
                state: _states[index],
              ),
            );
          },
        ),
      ),
    );
  }

  void _navigateCourseDetails(BuildContext context) async {
    bool _ = await Navigator.push(
      context,
      MaterialPageRoute(
          builder: (context) => CourseDetails(id: _grandCourseId)),
    );
  }

  void _showInSnackBar(String value) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(
      content: new Text(
        value,
        style: UIUtil.getTxtStyleCaption2(),
      ),
      duration: new Duration(seconds: 3),
    ));
  }
}

Also, here is an example using SingleChildScrollView:

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:hybrid/@core/bms_colors.dart';
import 'package:hybrid/@core/constants/nav_bar_index.dart';
import 'package:hybrid/@core/models/contest_model.dart';
import 'package:hybrid/@core/models/course_model.dart';
import 'package:hybrid/@core/services/admin_service.dart';
import 'package:hybrid/@core/ui-components/button_primary.dart';
import 'package:hybrid/@core/ui-components/progress_indicator.dart';
import 'package:hybrid/@core/ui-components/text_form_field.dart';
import 'package:hybrid/@core/util/auth_util.dart';
import 'package:hybrid/@core/util/ui_util.dart';
import 'package:hybrid/screens/account/confirm_contest.dart';
import 'package:hybrid/screens/shared/app_bar.dart';
import 'package:hybrid/screens/shared/nav_bar.dart';
import 'package:hybrid/screens/shared/scroll_behavior.dart';

class ContactUs extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _ContactUsState();
}

class _ContactUsState extends State<ContactUs> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  final _formKey = GlobalKey<FormState>();
  FirebaseUser _currentUser;
  bool _autoValidate = false;
  var _messageSent = false;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: AuthUtil.getCurrentUser(),
        builder: (BuildContext context, AsyncSnapshot snapshot) {
          if (!snapshot.hasData) {
            return _buildScaffold();
          }

          _currentUser = snapshot.data;
          return _buildScaffold();
        });
  }

  Widget _buildScaffold() {
    return Scaffold(
      key: _scaffoldKey,
      appBar: BmsAppBar(),
      body: _buildBody(),
      bottomNavigationBar: NavBar(index: NavBarIndex.Home),
    );
  }

  Widget _buildBody() {
    if (_currentUser == null) {
      return Stack(
        children: <Widget>[
          Container(
            decoration: UIUtil.getDecorationBg(),
          ),
          Center(
            child: BmsProgressIndicator(),
          ),
        ],
      );
    }

    return Stack(
      children: <Widget>[
        Container(
          decoration: UIUtil.getDecorationBg(),
        ),
        ScrollConfiguration(
          behavior: ScrollBehaviorHideSplash(),
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.start,
              children: <Widget>[
                _buildMemberNumCard(_currentUser.email),
                Padding(
                  padding: EdgeInsets.only(
                    left: 20,
                    right: 20,
                  ),
                  child: _buildContactForm(),
                ),
                SizedBox(
                  height: 15,
                ),
                (_messageSent)
                    ? Container()
                    : Padding(
                        padding: EdgeInsets.only(top: 8, bottom: 8),
                        child: ButtonPrimary(
                            text: 'Send Message',
                            onPressed: () => _validateForm()),
                      ),
              ],
            ),
          ),
        ),
      ],
    );
  }

  Widget _buildMemberNumCard(String email) {
    return Card(
      color: BmsColors.primaryBackground,
      elevation: 2.0,
      child: ListTile(
        title: Text(
          'Contact Us',
          style: UIUtil.getTxtStyleTitle3(),
        ),
        subtitle: Text(
          'We will respond via your email address: $email',
          style: UIUtil.getListTileSubtitileStyle(),
        ),
        leading: Icon(
          Icons.contact_mail,
          color: BmsColors.primaryForeground,
        ),
      ),
    );
  }

  Widget _buildContactForm() {
    return Form(
      key: _formKey,
      autovalidate: _autoValidate,
      child: BmsTextFormField(
        hintText: 'Enter Message',
        maxLines: 3,
        keyboardType: TextInputType.multiline,
        textInputAction: TextInputAction.done,
        validator: validateMessage,
        inputFormatters: [LengthLimitingTextInputFormatter(100)],
        onFieldSubmitted: (String val) {
          if (val == null || val.isEmpty) {
            return;
          }
          sendMessage(_currentUser.email, val);
        },
        onSaved: (String val) {
          print('onSaved = $val');
          sendMessage(_currentUser.email, val);
        },
        //validator: _validateOtherAmount,
      ),
    );
  }

  void _showInSnackBar(String value, int seconds) {
    _scaffoldKey.currentState.showSnackBar(new SnackBar(
      content: Text(
        value,
        style: UIUtil.getTxtStyleCaption2(),
      ),
      duration: Duration(seconds: seconds),
    ));
  }

  void _hideSnackBar() {
    _scaffoldKey.currentState.hideCurrentSnackBar();
  }

  String validateMessage(String value) {
    if (value == null || value.isEmpty)
      return 'Please Enter Your Message';
    else
      return null;
  }

  void _validateForm() {
    if (_formKey.currentState.validate()) {
      //    If all data are correct then save data to out variables
      _formKey.currentState.save();
    } else {
      //    If all data are not valid then start auto validation.
      setState(() {
        _autoValidate = true;
      });
    }
  }

  void sendMessage(email, message) async {
    var result = await AdminService.contactUs(email: email, message: message);

    if (result == ContactUsStatus.Error) {
      _showInSnackBar(
          'There was an error, please wait 30 seconds and try again', 10);
      return;
    }

    _showInSnackBar('Message Sent, We will contact you shortly', 10);
    setState(() {
      _messageSent = true;
    });
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks!, I'm using the flexible because I don't want the list (here: posts3) to scroll, but the whole page. So you don't see the container when you scroll down. How Can I achieve that without a flexible?
That would be a different SO question, you should confirm that my answer works and thus completing this question
I understand, I replaced the flexible with it's child. But the error stays: renderflex bottom overflowed...
Try removing mainAxisSize: MainAxisSize.min,
Then I get this error: RenderFlex children have non-zero flex but incoming height constraints are unbounded.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.