Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluter - how to add a TabBar in the body of scaffold

I want to add a Tabbar in the body of the scaffold which decide the signUp method i.e, whether using phone number or email. I added a TabBar followed by TabBarView in a column in the body of scaffold. But it gives me the following exception

'The following assertion was thrown during performResize(): Horizontal viewport was given unbounded height. Viewports expand in the cross axis to fill their container and constrain their children to match their extent in the cross axis. In this case, a horizontal viewport was given an unlimited amount of vertical space in which to expand.'

The same code works independantly when there were no TabBar. Here is my code,

class _SignUpState extends State<SignUp> with SingleTickerProviderStateMixin {
  final emailController = TextEditingController();
  final phoneController = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  bool isLoading = true;
  late TabController tabController;


  @override
  void dispose(){
    emailController.dispose();
    phoneController.dispose();
    super.dispose();
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    tabController = TabController(length: 2, vsync: this);
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold
      body: SafeArea(
        child: SingleChildScrollView(
          child: Container(
            padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30),
            height: MediaQuery.of(context).size.height,
            width: double.infinity,
            child: Form(
              key: _formKey,
              child: ListView(
                scrollDirection: Axis.vertical,
                children: [
                  const SizedBox(height: 50,),
                  const Center(
                    child: Text(
                      'MyApp',
                      style: TextStyle(
                        color: Colors.red,
                        fontSize: 75,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                  const SizedBox(height: 40),
                  const Center(
                    child: Text(
                      'Welcome to My App',
                      style: TextStyle(
                          fontSize: 20,
                          fontWeight: FontWeight.normal,
                      ),
                    ),
                  ),
                  SizedBox(height: 10,),
                 const  Center(
                    child: Text(
                      'Sign up to continue',
                      style: TextStyle(
                          color: Color.fromARGB(255, 127, 125, 125),
                          fontSize: 16,
                          fontWeight: FontWeight.normal
                      ),
                    ),
                  ),
                  const SizedBox(height: 50),
                  TabBar(
                    controller: tabController,
                    tabs: [
                      Tab(text: 'EMAIL ADDRESS',),
                      Tab(text: 'PHONE NUMBER',),
                    ]
                  ),
                  Container(
                    child: TabBarView(
                      controller: tabController,
                      children: [
                        Column(
                          children: [
                            Padding(
                              padding: const EdgeInsets.fromLTRB(0, 30, 0, 6),
                              child: TextFormField(
                                controller: emailController,
                                keyboardType: TextInputType.emailAddress,
                                textInputAction: TextInputAction.next,
                                autofillHints: [AutofillHints.email],
                                autovalidateMode:
                                    AutovalidateMode.onUserInteraction,
                                validator: (value) {
                                  if (emailController.text == '') {
                                    return 'This is a required field';
                                  }
                                  EmailValidator.validate(value!)
                                      ? null
                                      : "Please enter a valid email";
                                },
                                cursorColor: Colors.blue,
                                decoration: InputDecoration(
                                  prefixIcon: Icon(Icons.email),
                                  focusedBorder: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(20),
                                      borderSide: const BorderSide(
                                          color: Colors.blue, width: 2)),
                                  enabledBorder: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(20),
                                    borderSide: BorderSide(
                                        color: Color.fromARGB(254, 57, 40, 71)),
                                  ),
                                  label: Row(children: const [
                                    Text(
                                      'Email',
                                      style: TextStyle(
                                          color:
                                              Color.fromARGB(254, 57, 40, 71),
                                          fontSize: 20),
                                    ),
                                    Text(
                                      ' *',
                                      style: TextStyle(
                                          color: Colors.red, fontSize: 20),
                                    ),
                                  ]),
                                  hintText: '[email protected]',
                                  hintStyle: const TextStyle(
                                      color: Color.fromARGB(255, 158, 156, 156),
                                      fontSize: 20),
                                ),
                              ),
                            ),
                            
                            const SizedBox(
                              height: 50,
                            ),
                            Center(
                              child: MaterialButton(
                                minWidth: double.infinity,
                                height: 60,
                                color: Colors.red,
                                elevation: 0,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10),
                                ),
                                onPressed: () {
                                  if (_formKey.currentState!.validate() ==
                                      true) {
                                    signUp();
                                  }
                                },
                                child: const Text(
                                  'SIGN UP',
                                  style: TextStyle(
                                    fontWeight: FontWeight.w600,
                                    fontSize: 18,
                                    color: Colors.white,
                                  ),
                                ),
                              ),
                            ),
                            const SizedBox(height: 20),
                          ],
                        ),
                        Column(
                          children: [
                            
                            Padding(
                              padding: const EdgeInsets.fromLTRB(0, 6, 0, 6),
                              child: TextFormField(
                                controller: phoneController,
                                textInputAction: TextInputAction.next,
                                cursorColor: Colors.blue,
                                keyboardType: TextInputType.number,
                                autovalidateMode:
                                    AutovalidateMode.onUserInteraction,
                                validator: (value) {
                                  if (value!.length != 10 && value.isNotEmpty) {
                                    return 'phone number must contain 10 numbers';
                                  }
                                },
                                decoration: InputDecoration(
                                  focusedBorder: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(20),
                                      borderSide: const BorderSide(
                                          color: Colors.blue, width: 2)),
                                  enabledBorder: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(20),
                                    borderSide: BorderSide(
                                        color: Color.fromARGB(254, 57, 40, 71)),
                                  ),
                                  label: Row(children: const [
                                    Text(
                                      'Phone',
                                      style: TextStyle(
                                          color:
                                              Color.fromARGB(254, 57, 40, 71),
                                          fontSize: 20),
                                    ),
                                  ]),
                                  prefixIcon: const Icon(Icons.phone),
                                  hintText: 'Your phone number',
                                  hintStyle: const TextStyle(
                                      color: Color.fromARGB(255, 158, 156, 156),
                                      fontSize: 20),
                                ),
                              ),
                            ),
                            Center(
                              child: MaterialButton(
                                minWidth: double.infinity,
                                height: 60,
                                color: Colors.red,
                                elevation: 0,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10),
                                ),
                                onPressed: () {
                                  if (_formKey.currentState!.validate() ==
                                      true) {
                                    signUp();
                                  }
                                },
                                child: const Text(
                                  'SIGN UP',
                                  style: TextStyle(
                                    fontWeight: FontWeight.w600,
                                    fontSize: 18,
                                    color: Colors.white,
                                  ),
                                ),
                              ),
                            ),
                            const SizedBox(height: 20),
                          ],
                        ),
                      ],
                    ),
                  ),
                  
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const Text("Already have an account..?  ", style: TextStyle(fontSize: 16),),
                      RichText(
                        text: TextSpan(                            
                          children: [
                            TextSpan(
                                recognizer: TapGestureRecognizer()
                                  ..onTap = widget.onClickedSignIn,
                                text:'Log In',
                                style: TextStyle(
                                  decoration: TextDecoration.underline,
                                  color: Theme.of(context).colorScheme.secondary,
                                  fontSize: 17
                                )
                            )
                          ],
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(height: 100,)
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }
  Future signUp() {
    
  }

}

Can someone help with a solution ?

like image 394
Gireesh Avatar asked Nov 01 '25 01:11

Gireesh


1 Answers

Change ListView in to Column and TabBarView parent Expanded instead of Container

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

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

  @override
  State<SignUp> createState() => _SignUpState();
}

class _SignUpState extends State<SignUp> with SingleTickerProviderStateMixin {
  final emailController = TextEditingController();
  final phoneController = TextEditingController();
  final _formKey = GlobalKey<FormState>();
  bool isLoading = true;
  late TabController tabController;

  @override
  void dispose() {
    emailController.dispose();
    phoneController.dispose();
    super.dispose();
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    tabController = TabController(length: 2, vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          child: Container(
            padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 30),
            height: MediaQuery.of(context).size.height,
            width: double.infinity,
            child: Form(
              key: _formKey,
              child: Column(
                children: [
                  const SizedBox(
                    height: 50,
                  ),
                  const Center(
                    child: Text(
                      'MyApp',
                      style: TextStyle(
                        color: Colors.red,
                        fontSize: 75,
                        fontWeight: FontWeight.bold,
                      ),
                    ),
                  ),
                  const SizedBox(height: 40),
                  const Center(
                    child: Text(
                      'Welcome to My App',
                      style: TextStyle(
                        fontSize: 20,
                        fontWeight: FontWeight.normal,
                      ),
                    ),
                  ),
                  SizedBox(
                    height: 10,
                  ),
                  const Center(
                    child: Text(
                      'Sign up to continue',
                      style: TextStyle(color: Color.fromARGB(255, 127, 125, 125), fontSize: 16, fontWeight: FontWeight.normal),
                    ),
                  ),
                  const SizedBox(height: 50),
                  TabBar(
                    controller: tabController,
                    tabs: [
                      Tab(
                        text: 'EMAIL ADDRESS',
                      ),
                      Tab(
                        text: 'PHONE NUMBER',
                      ),
                    ],
                    labelColor: Colors.black,
                  ),
                  Expanded(
                    child: TabBarView(
                      controller: tabController,
                      children: [
                        Column(
                          children: [
                            Padding(
                              padding: const EdgeInsets.fromLTRB(0, 30, 0, 6),
                              child: TextFormField(
                                controller: emailController,
                                keyboardType: TextInputType.emailAddress,
                                textInputAction: TextInputAction.next,
                                autofillHints: [AutofillHints.email],
                                autovalidateMode: AutovalidateMode.onUserInteraction,
                                validator: (value) {
                                  if (emailController.text == '') {
                                    return 'This is a required field';
                                  }
                                  /* EmailValidator.validate(value!)
                                    ? null
                                    : "Please enter a valid email";*/
                                },
                                cursorColor: Colors.blue,
                                decoration: InputDecoration(
                                  prefixIcon: Icon(Icons.email),
                                  focusedBorder: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(20),
                                      borderSide: const BorderSide(color: Colors.blue, width: 2)),
                                  enabledBorder: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(20),
                                    borderSide: BorderSide(color: Color.fromARGB(254, 57, 40, 71)),
                                  ),
                                  label: Row(children: const [
                                    Text(
                                      'Email',
                                      style: TextStyle(color: Color.fromARGB(254, 57, 40, 71), fontSize: 20),
                                    ),
                                    Text(
                                      ' *',
                                      style: TextStyle(color: Colors.red, fontSize: 20),
                                    ),
                                  ]),
                                  hintText: '[email protected]',
                                  hintStyle: const TextStyle(color: Color.fromARGB(255, 158, 156, 156), fontSize: 20),
                                ),
                              ),
                            ),
                            const SizedBox(
                              height: 50,
                            ),
                            Center(
                              child: MaterialButton(
                                minWidth: double.infinity,
                                height: 60,
                                color: Colors.red,
                                elevation: 0,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10),
                                ),
                                onPressed: () {
                                  if (_formKey.currentState!.validate() == true) {
                                    signUp();
                                  }
                                },
                                child: const Text(
                                  'SIGN UP',
                                  style: TextStyle(
                                    fontWeight: FontWeight.w600,
                                    fontSize: 18,
                                    color: Colors.white,
                                  ),
                                ),
                              ),
                            ),
                            const SizedBox(height: 20),
                          ],
                        ),
                        Column(
                          children: [
                            Padding(
                              padding: const EdgeInsets.fromLTRB(0, 6, 0, 6),
                              child: TextFormField(
                                controller: phoneController,
                                textInputAction: TextInputAction.next,
                                cursorColor: Colors.blue,
                                keyboardType: TextInputType.number,
                                autovalidateMode: AutovalidateMode.onUserInteraction,
                                validator: (value) {
                                  if (value!.length != 10 && value.isNotEmpty) {
                                    return 'phone number must contain 10 numbers';
                                  }
                                },
                                decoration: InputDecoration(
                                  focusedBorder: OutlineInputBorder(
                                      borderRadius: BorderRadius.circular(20),
                                      borderSide: const BorderSide(color: Colors.blue, width: 2)),
                                  enabledBorder: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(20),
                                    borderSide: BorderSide(color: Color.fromARGB(254, 57, 40, 71)),
                                  ),
                                  label: Row(children: const [
                                    Text(
                                      'Phone',
                                      style: TextStyle(color: Color.fromARGB(254, 57, 40, 71), fontSize: 20),
                                    ),
                                  ]),
                                  prefixIcon: const Icon(Icons.phone),
                                  hintText: 'Your phone number',
                                  hintStyle: const TextStyle(color: Color.fromARGB(255, 158, 156, 156), fontSize: 20),
                                ),
                              ),
                            ),
                            Center(
                              child: MaterialButton(
                                minWidth: double.infinity,
                                height: 60,
                                color: Colors.red,
                                elevation: 0,
                                shape: RoundedRectangleBorder(
                                  borderRadius: BorderRadius.circular(10),
                                ),
                                onPressed: () {
                                  if (_formKey.currentState!.validate() == true) {
                                    signUp();
                                  }
                                },
                                child: const Text(
                                  'SIGN UP',
                                  style: TextStyle(
                                    fontWeight: FontWeight.w600,
                                    fontSize: 18,
                                    color: Colors.white,
                                  ),
                                ),
                              ),
                            ),
                            const SizedBox(height: 20),
                          ],
                        ),
                      ],
                    ),
                  ),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      const Text(
                        "Already have an account..?  ",
                        style: TextStyle(fontSize: 16),
                      ),
                      RichText(
                        text: TextSpan(
                          children: [
                            TextSpan(
                                recognizer: TapGestureRecognizer()
                                  ..onTap = () {
                                    print('login');
                                  },
                                text: 'Log In',
                                style: TextStyle(
                                    decoration: TextDecoration.underline,
                                    color: Theme.of(context).colorScheme.secondary,
                                    fontSize: 17))
                          ],
                        ),
                      ),
                    ],
                  ),
                  const SizedBox(
                    height: 100,
                  )
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }

  Future signUp() async {}
}

It will look something like this -

like image 134
Gursewak Singh Avatar answered Nov 02 '25 14:11

Gursewak Singh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!