Home > Software engineering >  Flutter SingleChildScrollView Sign Up Screen not working
Flutter SingleChildScrollView Sign Up Screen not working

Time:04-22

I am trying to create a scrollable sign up screen for when the keyboard pops up but my SingleChildScrollView widget doesn't seem to be working. I don't know whether this has to do with its placement in the stack or the inner column but help would be much appreciated. I've tried a ListView instead of a column, using the Expanded widget around the SingleChildScrollView but to no success.

Sign Up Screen

Sign Up Screen with Keyboard

An example to copy and run here.

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const SignUpScreen(),
    );
  }
}

class SignUpScreen extends StatefulWidget {
  const SignUpScreen({Key? key}) : super(key: key);

  @override
  _SignUpScreenState createState() => _SignUpScreenState();
}

class _SignUpScreenState extends State<SignUpScreen> {
  final _formKey = GlobalKey<FormState>();

  bool _obscurePassword = true;
  Color _obscureColor = Colors.grey;

  InputDecoration textFormFieldDecoration = InputDecoration(
    filled: true,
    fillColor: const Color(0xFFF5F5F5),
    prefixIcon: const Padding(
      padding: EdgeInsets.symmetric(horizontal: 20),
      child: Icon(
        Icons.email,
        color: Colors.blueAccent,
        size: 26,
      ),
    ),
    suffixIcon: null,
    border: OutlineInputBorder(
      borderRadius: BorderRadius.circular(30),
      borderSide: const BorderSide(color: Colors.white),
    ),
    enabledBorder: OutlineInputBorder(
      borderRadius: BorderRadius.circular(30),
      borderSide: const BorderSide(color: Colors.white),
    ),
    focusedBorder: OutlineInputBorder(
      borderRadius: BorderRadius.circular(30),
      borderSide: const BorderSide(color: Colors.white),
    ),
    hintText: 'E-mail',
    hintStyle: const TextStyle(
      fontFamily: 'OpenSans',
      fontSize: 18,
    ),
  );

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: false,
        // Shows circular progress indicator while loading
        body:
            // A stack lays items over one another.
            Stack(
          children: [
            //The SizedBox provides the colored rounded aesthetic card behind the login.
            SizedBox(
              height: MediaQuery.of(context).size.height * 0.7,
              child: Container(
                color: Colors.redAccent,
              ),
            ),
            Form(
              key: _formKey,
              child: Column(
                // Keeps things in the center vertically
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
                  // Builds App Logo
                  Row(
                    // Keeps things in the center horizontally.
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: const [
                      Text(
                        'Heart',
                        style: TextStyle(
                          fontSize: 34,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                        ),
                      ),
                      Text(
                        'by AHG',
                        style: TextStyle(
                          fontSize: 24,
                          fontWeight: FontWeight.bold,
                          color: Colors.white,
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 30),
                  // Build sign up container card.
                  ClipRRect(
                    borderRadius: const BorderRadius.all(
                      Radius.circular(20),
                    ),
                    child: SingleChildScrollView(
                      child: Container(
                        height: MediaQuery.of(context).size.height * 0.65,
                        width: MediaQuery.of(context).size.width * 0.85,
                        color: Colors.white,
                        child: Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 24),
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: [
                              //Sign Up / Login Text
                              const Text(
                                'Sign Up',
                                style: TextStyle(
                                  fontSize: 30,
                                  fontWeight: FontWeight.w700,
                                  color: Colors.black,
                                ),
                              ),
                              const SizedBox(height: 25),
                              // Email form field
                              TextFormField(
                                keyboardType: TextInputType.emailAddress,
                                decoration: textFormFieldDecoration.copyWith(
                                    prefixIcon: Padding(
                                      padding: const EdgeInsets.symmetric(
                                          horizontal: 20),
                                      child: Icon(
                                        Icons.email,
                                        color: Theme.of(context)
                                            .colorScheme
                                            .secondary,
                                        size: 26,
                                      ),
                                    ),
                                    hintText: 'E-mail'),
                                autocorrect: false,
                              ),
                              const SizedBox(height: 13),
                              // Build password form field
                              TextFormField(
                                obscureText: _obscurePassword,
                                keyboardType: TextInputType.text,
                                decoration: textFormFieldDecoration.copyWith(
                                    prefixIcon: Padding(
                                      padding: const EdgeInsets.symmetric(
                                          horizontal: 20),
                                      child: Icon(
                                        Icons.lock,
                                        color: Theme.of(context)
                                            .colorScheme
                                            .secondary,
                                        size: 26,
                                      ),
                                    ),
                                    suffixIcon: Padding(
                                      padding: const EdgeInsets.only(right: 25),
                                      child: IconButton(
                                        icon: const Icon(
                                            Icons.remove_red_eye_rounded),
                                        color: _obscureColor,
                                        iconSize: 23,
                                        onPressed: () {
                                          setState(() {
                                            _obscurePassword =
                                                !_obscurePassword;
                                            _obscureColor == Colors.grey
                                                ? _obscureColor =
                                                    Theme.of(context)
                                                        .colorScheme
                                                        .secondary
                                                : _obscureColor = Colors.grey;
                                          });
                                        },
                                      ),
                                    ),
                                    hintText: 'Password'),
                                autocorrect: false,
                              ),
                              const SizedBox(height: 13),
                              // Build confirm password form field
                              TextFormField(
                                obscureText: _obscurePassword,
                                keyboardType: TextInputType.text,
                                decoration: textFormFieldDecoration.copyWith(
                                    prefixIcon: Padding(
                                      padding: const EdgeInsets.symmetric(
                                          horizontal: 20),
                                      child: Icon(
                                        Icons.lock,
                                        color: Theme.of(context)
                                            .colorScheme
                                            .secondary,
                                        size: 26,
                                      ),
                                    ),
                                    suffixIcon: Padding(
                                      padding: const EdgeInsets.only(right: 25),
                                      child: IconButton(
                                        icon: const Icon(
                                            Icons.remove_red_eye_rounded),
                                        color: _obscureColor,
                                        iconSize: 23,
                                        onPressed: () {
                                          setState(() {
                                            _obscurePassword =
                                                !_obscurePassword;
                                            _obscureColor == Colors.grey
                                                ? _obscureColor =
                                                    Theme.of(context)
                                                        .colorScheme
                                                        .secondary
                                                : _obscureColor = Colors.grey;
                                          });
                                        },
                                      ),
                                    ),
                                    hintText: 'Confirm'),
                                autocorrect: false,
                              ),
                              // Login Button
                              const SizedBox(
                                height: 30,
                              ),
                              SizedBox(
                                height: 1.4 *
                                    (MediaQuery.of(context).size.height / 20),
                                width: 5 *
                                    (MediaQuery.of(context).size.width / 10),
                                child: ElevatedButton(
                                  child: const Text('Sign Up'),
                                  onPressed: _validateInputs,
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ),
                  ),
                  //Sign Up Text
                  const SizedBox(
                    height: 20,
                  ),
                  TextButton(
                    onPressed: () {},
                    child: RichText(
                      text: TextSpan(children: [
                        TextSpan(
                          text: 'Don\'t have an account?',
                          style: TextStyle(
                            color: Colors.black,
                            fontSize: MediaQuery.of(context).size.height / 40,
                            fontWeight: FontWeight.w400,
                          ),
                        ),
                        TextSpan(
                          text: ' Login',
                          style: TextStyle(
                            color: Theme.of(context).colorScheme.primary,
                            fontSize: MediaQuery.of(context).size.height / 40,
                            fontWeight: FontWeight.bold,
                          ),
                        )
                      ]),
                    ),
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }

  void _validateInputs() {
    if (_formKey.currentState?.validate() != null) {
      final _validForm = _formKey.currentState!.validate();
      if (_validForm) {
        _formKey.currentState!.save();
      }
    }
  }
}

CodePudding user response:

1)Change resizeToAvoidBottomInset to true 2)SingleChildScrollView put it before Stack

Like this

@override
Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: true,
        // Shows circular progress indicator while loading
        body:
            // A stack lays items over one another.
            SingleChildScrollView(
          child: Stack(
            children: [

CodePudding user response:

Put the SingleChildScrollView as the Scaffold's body.

Scaffold(
        resizeToAvoidBottomInset: true,
        body:
            SingleChildScrollView(child: ...)
        )
  • Related