Flutter: My Listview.builder disappears under my Fixed bottom Container

742

Solution 1

Please check the edited code here.

class CheckoutScreen extends StatelessWidget {
  static const String id = 'checkout_screen';

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        leading: IconButton(
          icon: Icon(
            Icons.arrow_back_ios,
            color: Colors.black26,
          ),
          onPressed: () => Navigator.pop(context),
        ),
        title: Text(
          'Shopping cart',
          style: TextStyle(
            fontSize: 21.0,
            color: Colors.black26,
            fontWeight: FontWeight.bold,
          ),
        ),
        elevation: 0.0,
        backgroundColor: Colors.white,
      ),
      // bottomNavigationBar: _buildCartSummary(context),
      body: Column(
        children: <Widget>[
          Container(
            height: MediaQuery.of(context).size.height - 225,
            child: ListView.builder(
              shrinkWrap: true,
              itemCount: 6,
              itemBuilder: (context, index) {
                return _buildCartItems();
              },
            ),
          ),
          Expanded(
//            height: 300,
//            color: Colors.white,
            child: Align(
              alignment: Alignment.bottomCenter,
              child: _buildCartSummary(context),
            ),
          )
        ],
      ),
    );
  }

  _buildCartItems() {
    return Container(
      color: Colors.white,
      margin: EdgeInsets.symmetric(vertical: 6.0),
      child: Row(
        children: <Widget>[
          Container(
            width: 80.0,
            height: 80.0,
            decoration: BoxDecoration(
              color: Colors.grey[300],
              borderRadius: BorderRadius.circular(20.0),
            ),
            child: Center(
              child: Container(
                padding: EdgeInsets.all(4.0),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(20.0),
                  image: DecorationImage(
                    fit: BoxFit.cover,
                    image: NetworkImage(
                        'https://s2.r29static.com/bin/entry/ebd/0,675,2000,1050/x,80/1929471/image.jpg'),
                  ),
                ),
              ),
            ),
          ),
          SizedBox(width: 12.0),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Container(
                width: 100.0,
                child: Text(
                  'Nike Air max',
                  style: TextStyle(fontWeight: FontWeight.bold),
                ),
              ),
              SizedBox(height: 8.0),
              Row(
                children: <Widget>[
                  Container(
                    width: 20.0,
                    height: 20.0,
                    decoration: BoxDecoration(
                      color: Colors.grey[200],
                      borderRadius: BorderRadiusDirectional.circular(4.0),
                    ),
                    child: Icon(
                      Icons.remove,
                      color: Colors.white,
                      size: 15.0,
                    ),
                  ),
                  Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 15.0),
                    child: Text(
                      '1',
                      style: TextStyle(
                          fontWeight: FontWeight.bold, fontSize: 15.0),
                    ),
                  ),
                  Container(
                    width: 20.0,
                    height: 20.0,
                    decoration: BoxDecoration(
                      color: Colors.red,
                      borderRadius: BorderRadiusDirectional.circular(4.0),
                    ),
                    child: Icon(
                      Icons.add,
                      color: Colors.white,
                      size: 15.0,
                    ),
                  ),
                ],
              ),
            ],
          ),
          Spacer(),
          Text(
            '\u20b9 6,000',
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
          ),
        ],
      ),
    );
  }

  _buildCartSummary(BuildContext context) {
    return Container(
      height: 200,
      color: Colors.white,
      padding: EdgeInsets.fromLTRB(15.0, 8.0, 15.0, 0.0),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Divider(),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Text(
                'Sub Total',
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
              ),
              Text(
                '\u20b9 480',
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
              ),
            ],
          ),
          SizedBox(height: 10.0),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Text(
                'Taxes (absorbed by you)',
                style: TextStyle(fontSize: 15.0),
              ),
              Text(
                '\u20b9 40',
                style: TextStyle(fontSize: 15.0),
              ),
            ],
          ),
          SizedBox(height: 10.0),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: <Widget>[
              Text(
                'Total',
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
              ),
              Text(
                '\u20b9 520',
                style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
              ),
            ],
          ),
          MaterialButton(
            onPressed: () {
              showModalBottomSheet(
                context: context,
                isScrollControlled: false,
                builder: (context) => SingleChildScrollView(
                  child: Container(
                    padding: EdgeInsets.only(
                        bottom: MediaQuery.of(context).viewInsets.bottom),
//                    child: ShowPaymentOptionsScreen(),
                  ),
                ),
              );
            },
            height: 40.0,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(5.0),
            ),
            minWidth: double.infinity,
            child: Text(
              'PROCESS PAYMENT',
              style: TextStyle(
                color: Colors.white,
                fontSize: 14.0,
                fontWeight: FontWeight.bold,
              ),
            ),
            color: Colors.red,
          ),
          SizedBox(height: 15.0),
        ],
      ),
    );
  }
}

Solution 2

Just add Positioned widget with all dimens as 0.0

Positioned(
            bottom: 0.0,
            right: 0.0,
            left: 0.0,
            child: Container(
              color: Colors.white,
              child: Align(
                alignment: Alignment.bottomCenter,
                child: _buildCartSummary(context),
              ),
            ),
          ),

Output:

enter image description here

Share:
742
hermie_brown
Author by

hermie_brown

Flutter Enthusiast! All things mobile and cool.

Updated on December 24, 2022

Comments

  • hermie_brown
    hermie_brown over 1 year

    I am building a shopping cart UI and therein I want to display a list of my shopping cart items and also a fixed bottom widget which would show the cart summary details.

    I want the cart summary container fixed to the bottom and the ListView.builder scrollable but to sit right ontop of the bottom widget, not disappear in it.

    Here's my code. I know it must be something I am overlooking. I need help with that.

    Thanks.

    class CheckoutScreen extends StatelessWidget {
      static const String id = 'checkout_screen';
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            leading: IconButton(
              icon: Icon(
                Icons.arrow_back_ios,
                color: Colors.black26,
              ),
              onPressed: () => Navigator.pop(context),
            ),
            title: Text(
              'Shopping cart',
              style: TextStyle(
                fontSize: 21.0,
                color: Colors.black26,
                fontWeight: FontWeight.bold,
              ),
            ),
            elevation: 0.0,
            backgroundColor: Colors.white,
          ),
          // bottomNavigationBar: _buildCartSummary(context),
          body: Stack(
            children: <Widget>[
              Container(
                padding: const EdgeInsets.symmetric(horizontal: 16.0),
                child: ListView.builder(
                  itemCount: 5,
                  itemBuilder: (context, index) {
                    return _buildCartItems();
                  },
                ),
              ),
              SizedBox(height: 30),
              Container(
                child: Align(
                  alignment: Alignment.bottomCenter,
                  child: _buildCartSummary(context),
                ),
              ),
            ],
          ),
          // Align(
          //     alignment: Alignment.center,
          //     child: Text('Your cart is empty.')),
        );
      }
    
      _buildCartItems() {
        return Container(
          color: Colors.white,
          margin: EdgeInsets.symmetric(vertical: 6.0),
          child: Row(
            children: <Widget>[
              Expanded(
                child: Container(
                  width: 80.0,
                  height: 80.0,
                  decoration: BoxDecoration(
                    color: Colors.grey[300],
                    borderRadius: BorderRadius.circular(20.0),
                  ),
                  child: Center(
                    child: Container(
                      padding: EdgeInsets.all(4.0),
                      decoration: BoxDecoration(
                        borderRadius: BorderRadius.circular(20.0),
                        image: DecorationImage(
                          fit: BoxFit.cover,
                          image: NetworkImage(
                              'https://s2.r29static.com/bin/entry/ebd/0,675,2000,1050/x,80/1929471/image.jpg'),
                        ),
                      ),
                    ),
                  ),
                ),
              ),
              SizedBox(width: 12.0),
              Expanded(
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    Container(
                      width: 100.0,
                      child: Text(
                        'Nike Air max',
                        style: TextStyle(fontWeight: FontWeight.bold),
                      ),
                    ),
                    SizedBox(height: 8.0),
                    Row(
                      children: <Widget>[
                        Container(
                          width: 20.0,
                          height: 20.0,
                          decoration: BoxDecoration(
                            color: Colors.grey[200],
                            borderRadius: BorderRadiusDirectional.circular(4.0),
                          ),
                          child: Icon(
                            Icons.remove,
                            color: Colors.white,
                            size: 15.0,
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.symmetric(horizontal: 15.0),
                          child: Text(
                            '1',
                            style: TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 15.0),
                          ),
                        ),
                        Container(
                          width: 20.0,
                          height: 20.0,
                          decoration: BoxDecoration(
                            color: kThemeStyleButtonFillColour,
                            borderRadius: BorderRadiusDirectional.circular(4.0),
                          ),
                          child: Icon(
                            Icons.add,
                            color: Colors.white,
                            size: 15.0,
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ),
              Spacer(),
              Expanded(
                child: Text(
                  '\u20b9 6,000',
                  style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
                ),
              ),
            ],
          ),
        );
      }
    
      _buildCartSummary(BuildContext context) {
        return Container(
          padding: EdgeInsets.fromLTRB(15.0, 8.0, 15.0, 0.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.end,
            children: <Widget>[
              Divider(),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text(
                    'Sub Total',
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
                  ),
                  Text(
                    '\u20b9 480',
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
                  ),
                ],
              ),
              SizedBox(height: 10.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text(
                    'Taxes (absorbed by you)',
                    style: TextStyle(fontSize: 15.0),
                  ),
                  Text(
                    '\u20b9 40',
                    style: TextStyle(fontSize: 15.0),
                  ),
                ],
              ),
              SizedBox(height: 10.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text(
                    'Total',
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20.0),
                  ),
                  Text(
                    '\u20b9 520',
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15.0),
                  ),
                ],
              ),
              MaterialButton(
                onPressed: () {
                  showModalBottomSheet(
                    context: context,
                    isScrollControlled: true,
                    builder: (context) => SingleChildScrollView(
                      child: Container(
                        padding: EdgeInsets.only(
                            bottom: MediaQuery.of(context).viewInsets.bottom),
                        child: ShowPaymentOptionsScreen(),
                      ),
                    ),
                  );
                },
                height: 40.0,
                shape: RoundedRectangleBorder(
                  borderRadius: BorderRadius.circular(5.0),
                ),
                minWidth: double.infinity,
                child: Text(
                  'PROCESS PAYMENT',
                  style: TextStyle(
                    color: Colors.white,
                    fontSize: 14.0,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                color: kThemeStyleButtonFillColour,
              ),
              SizedBox(height: 15.0),
            ],
          ),
        );
      }
    }
    
  • hermie_brown
    hermie_brown over 3 years
    But I noticed with your implementation, the last items on the list disappears in the list view scroll. Try changing the itemCount to something like 7 or 10 to see what I mean.
  • hermie_brown
    hermie_brown over 3 years
    Thanks! This is the best implementation thus far. I'll just add that to avoid the scribbly overflow yellow lines in smaller devices such as Nexus 5, I had to do a small improvement in the Build function. I also wrapped the first Container in the column with an Expanded widget and set the flex to 2. But overall, great fix!