skip to Main Content

I am trying to make a dynamic Container where the height of the Container itself can changed based on the ExpansionTile. If the Expansion Tile is being expand, then the width will increase, but if it’s being collapsed, the width will back to normal. But I found that when it’s being collapsed, there are overflow. How do I fix it?

Collapse screen

Expand screen

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

class Address extends StatefulWidget {
  const Address({super.key});

  @override
  State<Address> createState() => _AddressState();
}

class _AddressState extends State<Address> {
  FocusNode addressText = FocusNode();
  bool _open = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        centerTitle: true,
        title: Container(
          width: 200,
          child: PreferredSize(
            preferredSize: Size.fromHeight(10.0),
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Expanded(
                  child: LinearProgressIndicator(
                    value: 1, // Value for first step
                    backgroundColor: Color(0xD9D9D9D9),
                    valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                  ),
                ),
                SizedBox(width: 7.0),
                Expanded(
                  child: LinearProgressIndicator(
                    value: 1, // Value for second step
                    backgroundColor: Color(0xD9D9D9D9),
                    valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                  ),
                ),
                SizedBox(width: 7.0),
                Expanded(
                  child: LinearProgressIndicator(
                    value: 0.15, // Value for third step
                    backgroundColor: Color(0xD9D9D9D9),
                    valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                  ),
                ),
              ],
            ),
          ),
        )
      ),
      body: SingleChildScrollView(
        child: Container(
          // padding: EdgeInsets.symmetric(horizontal: 24.0,vertical: 12.0),
          padding: EdgeInsets.all(30.0),
          width: MediaQuery.of(context).size.width,
          height: _open ? MediaQuery.of(context).size.height-1/9*(MediaQuery.of(context).size.height)+100 : MediaQuery.of(context).size.height-1/9*(MediaQuery.of(context).size.height),
          // height: MediaQuery.of(context).size.height,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text("Enter your address",style: TextStyle(fontSize: 22,fontFamily: "GraphikMedium"),),
                  SizedBox(height: 12,),
                  Text("Enter the street address of your primary residence. Please do not use a PO box or business address",
                  style: TextStyle(color: Colors.grey,fontSize: 16),),
                  SizedBox(height: 24,),
                  Text("Search for Address",style: TextStyle(fontSize: 16.0,fontFamily: "GraphikMedium",
                      color: addressText.hasFocus ? Colors.blue : Colors.black),
                  ),
                  SizedBox(height: 8.0,),
                  Focus(
                    onFocusChange: (focus){
                      setState(() {});
                    },
                    child: TextFormField(
                      focusNode: addressText,
                      decoration: InputDecoration(
                        enabledBorder: OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.grey),
                        ),
                        focusedBorder: OutlineInputBorder(
                          borderSide: BorderSide(color: Colors.blue)
                        ),
                        hintText: "Enter your address",
                        hintStyle: TextStyle(color: Colors.grey)
                      ),
                    ),
                  ),
                  SizedBox(height: 40,),
                  Theme(
                    data: Theme.of(context).copyWith(dividerColor: Colors.transparent),
                    child: ListTileTheme(
                      contentPadding: EdgeInsets.all(0),
                      dense: true,
                      child: ExpansionTile(
                        title: Text("Enter Address Manually",style: TextStyle(fontFamily: "GraphikRegular",fontSize: 16.0),),
                        onExpansionChanged: (bool value) {
                          setState(() {
                            _open = value;
                          });
                        },
                        children: [
                          Container(
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                SizedBox(height: 8.0,),
                                Text("Address line 1",style: TextStyle(fontFamily: "GraphikRegular",fontSize: 16.0),),
                                TextFormField(
                                  decoration: InputDecoration(
                                    enabledBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.grey)
                                    ),
                                    focusedBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.blue),
                                    )
                                  ),
                                ),
                                SizedBox(height: 8.0,),
                                Text("Address line 2 (optional)",style: TextStyle(fontFamily: "GraphikRegular",fontSize: 16.0),),
                                TextFormField(
                                  decoration: InputDecoration(
                                      enabledBorder: OutlineInputBorder(
                                          borderSide: BorderSide(color: Colors.grey)
                                      ),
                                      focusedBorder: OutlineInputBorder(
                                        borderSide: BorderSide(color: Colors.blue),
                                      )
                                  ),
                                ),
                                SizedBox(height: 8.0,),
                                Text("City",style: TextStyle(fontFamily: "GraphikRegular",fontSize: 16.0),),
                                TextFormField(
                                  decoration: InputDecoration(
                                      enabledBorder: OutlineInputBorder(
                                          borderSide: BorderSide(color: Colors.grey)
                                      ),
                                      focusedBorder: OutlineInputBorder(
                                        borderSide: BorderSide(color: Colors.blue),
                                      )
                                  ),
                                ),
                                SizedBox(height: 8.0,),
                                Text("City",style: TextStyle(fontFamily: "GraphikRegular",fontSize: 16.0),),
                                TextFormField(
                                  decoration: InputDecoration(
                                      enabledBorder: OutlineInputBorder(
                                          borderSide: BorderSide(color: Colors.grey)
                                      ),
                                      focusedBorder: OutlineInputBorder(
                                        borderSide: BorderSide(color: Colors.blue),
                                      )
                                  ),
                                ),
                              ],
                            ),
                          )
                        ],
                      ),
                    ),
                  )
                ],
              ),
              Container(
                width: MediaQuery.of(context).size.width,
                child: ElevatedButton(
                  onPressed: (){
                    Navigator.pushNamed(context, '/user-purpose');
                  },
                  child: Text(
                    "Continue",
                    style: TextStyle(
                      fontSize: 14.0,
                      fontWeight: FontWeight.normal,
                      color: Colors.white,
                      fontFamily: "GraphikMedium",
                    ),
                  ),
                  style: ButtonStyle(
                    shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                      RoundedRectangleBorder(borderRadius: BorderRadius.circular(5.0))
                    ),
                    minimumSize: MaterialStateProperty.all(Size.fromHeight(60.0)),
                    backgroundColor: MaterialStateProperty.all(Colors.blue),
                    shadowColor: MaterialStateProperty.all(Colors.transparent)
                  ),
                ),
              )
            ],
          ),
        ),
      )
    );
  }
}

2

Answers


  1. when collapsing the ExpansionTile occurs because the container’s height is calculated based on the MediaQuery.of(context).size.height and a dynamic factor. When the tile collapses, the content shrinks, but the container height might still be larger than necessary, leading to the overflow.

    Wrap the content in a SingleChildScrollView like in the below example,

    SingleChildScrollView(
      child: Container(
        // ... Codes
      ),
    )
    
    Login or Signup to reply.
  2. Ok, let me reproduce your issue first.

    issued

    So, the UI is overflow is because the scrolling layout is not correct, let me explain below.

    remove code

    1. there is a conditional operator in the height property, scrolling layout (SingleChildScrollView) will automaically adapt if the widget content is exceeds the screen, you can remove the height in this case
    2. you give the nested column for layout the content and the continue button with the spaceBetween alignment, just remove this column and move the continue button to… (continue to next step)

    move code

    1. move the continue button to Scaffold -> bottomNavigationBar like the code above to position the button as bottom nav bar so the button will stick to the bottom of the screen
    2. add padding to make some space on the button

    And this is the result:

    result demo

    This is the final code:

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    class Address extends StatefulWidget {
      const Address({super.key});
    
      @override
      State<Address> createState() => _AddressState();
    }
    
    class _AddressState extends State<Address> {
      FocusNode addressText = FocusNode();
      bool _open = false;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          backgroundColor: Colors.white,
          appBar: AppBar(
            centerTitle: true,
            title: Container(
              width: 200,
              child: PreferredSize(
                preferredSize: Size.fromHeight(10.0),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: [
                    Expanded(
                      child: LinearProgressIndicator(
                        value: 1, // Value for first step
                        backgroundColor: Color(0xD9D9D9D9),
                        valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                      ),
                    ),
                    SizedBox(width: 7.0),
                    Expanded(
                      child: LinearProgressIndicator(
                        value: 1, // Value for second step
                        backgroundColor: Color(0xD9D9D9D9),
                        valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                      ),
                    ),
                    SizedBox(width: 7.0),
                    Expanded(
                      child: LinearProgressIndicator(
                        value: 0.15, // Value for third step
                        backgroundColor: Color(0xD9D9D9D9),
                        valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
          body: SingleChildScrollView(
            child: Container(
              // padding: EdgeInsets.symmetric(horizontal: 24.0,vertical: 12.0),
              padding: EdgeInsets.all(30.0),
              width: MediaQuery.of(context).size.width,
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    "Enter your address",
                    style: TextStyle(fontSize: 22, fontFamily: "GraphikMedium"),
                  ),
                  SizedBox(
                    height: 12,
                  ),
                  Text(
                    "Enter the street address of your primary residence. Please do not use a PO box or business address",
                    style: TextStyle(color: Colors.grey, fontSize: 16),
                  ),
                  SizedBox(
                    height: 24,
                  ),
                  Text(
                    "Search for Address",
                    style: TextStyle(
                        fontSize: 16.0,
                        fontFamily: "GraphikMedium",
                        color: addressText.hasFocus ? Colors.blue : Colors.black),
                  ),
                  SizedBox(
                    height: 8.0,
                  ),
                  Focus(
                    onFocusChange: (focus) {
                      setState(() {});
                    },
                    child: TextFormField(
                      focusNode: addressText,
                      decoration: InputDecoration(
                          enabledBorder: OutlineInputBorder(
                            borderSide: BorderSide(color: Colors.grey),
                          ),
                          focusedBorder: OutlineInputBorder(
                              borderSide: BorderSide(color: Colors.blue)),
                          hintText: "Enter your address",
                          hintStyle: TextStyle(color: Colors.grey)),
                    ),
                  ),
                  SizedBox(
                    height: 40,
                  ),
                  Theme(
                    data: Theme.of(context)
                        .copyWith(dividerColor: Colors.transparent),
                    child: ListTileTheme(
                      contentPadding: EdgeInsets.all(0),
                      dense: true,
                      child: ExpansionTile(
                        title: Text(
                          "Enter Address Manually",
                          style: TextStyle(
                              fontFamily: "GraphikRegular", fontSize: 16.0),
                        ),
                        onExpansionChanged: (bool value) {
                          setState(() {
                            _open = value;
                          });
                        },
                        children: [
                          Container(
                            child: Column(
                              crossAxisAlignment: CrossAxisAlignment.start,
                              children: [
                                SizedBox(
                                  height: 8.0,
                                ),
                                Text(
                                  "Address line 1",
                                  style: TextStyle(
                                      fontFamily: "GraphikRegular", fontSize: 16.0),
                                ),
                                TextFormField(
                                  decoration: InputDecoration(
                                    enabledBorder: OutlineInputBorder(
                                        borderSide: BorderSide(color: Colors.grey)),
                                    focusedBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.blue),
                                    ),
                                  ),
                                ),
                                SizedBox(
                                  height: 8.0,
                                ),
                                Text(
                                  "Address line 2 (optional)",
                                  style: TextStyle(
                                      fontFamily: "GraphikRegular", fontSize: 16.0),
                                ),
                                TextFormField(
                                  decoration: InputDecoration(
                                    enabledBorder: OutlineInputBorder(
                                        borderSide: BorderSide(color: Colors.grey)),
                                    focusedBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.blue),
                                    ),
                                  ),
                                ),
                                SizedBox(
                                  height: 8.0,
                                ),
                                Text(
                                  "City",
                                  style: TextStyle(
                                      fontFamily: "GraphikRegular", fontSize: 16.0),
                                ),
                                TextFormField(
                                  decoration: InputDecoration(
                                    enabledBorder: OutlineInputBorder(
                                        borderSide: BorderSide(color: Colors.grey)),
                                    focusedBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.blue),
                                    ),
                                  ),
                                ),
                                SizedBox(
                                  height: 8.0,
                                ),
                                Text(
                                  "City",
                                  style: TextStyle(
                                    fontFamily: "GraphikRegular",
                                    fontSize: 16.0,
                                  ),
                                ),
                                TextFormField(
                                  decoration: InputDecoration(
                                    enabledBorder: OutlineInputBorder(
                                        borderSide: BorderSide(color: Colors.grey)),
                                    focusedBorder: OutlineInputBorder(
                                      borderSide: BorderSide(color: Colors.blue),
                                    ),
                                  ),
                                ),
                              ],
                            ),
                          )
                        ],
                      ),
                    ),
                  )
                ],
              ),
            ),
          ),
          bottomNavigationBar: Container(
            padding: EdgeInsets.all(30.0).copyWith(top: 0),
            width: MediaQuery.of(context).size.width,
            child: ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(context, '/user-purpose');
              },
              child: Text(
                "Continue",
                style: TextStyle(
                  fontSize: 14.0,
                  fontWeight: FontWeight.normal,
                  color: Colors.white,
                  fontFamily: "GraphikMedium",
                ),
              ),
              style: ButtonStyle(
                shape: MaterialStateProperty.all<RoundedRectangleBorder>(
                  RoundedRectangleBorder(
                    borderRadius: BorderRadius.circular(5.0),
                  ),
                ),
                minimumSize: MaterialStateProperty.all(Size.fromHeight(60.0)),
                backgroundColor: MaterialStateProperty.all(Colors.blue),
                shadowColor: MaterialStateProperty.all(Colors.transparent),
              ),
            ),
          ),
        );
      }
    }
    

    Hopefully it can solve your problem, Thanks 😉

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search