PeakGen
PeakGen

Reputation: 23025

Flutter: ListView height is getting reduced when other widgets are available

I am developing a flutter application and there, I am dynamically generating a list of checkboxes. so to do this, I used ListView.Builder.

Below is my full code, you can implement it at your end easily.

import 'package:flutter/material.dart';

class AddAccountPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: Text("Services"),
        actions: <Widget>[
          FlatButton(
            child: Text(
              "Save",
              style: Theme.of(context).textTheme.button,
            ),
            onPressed: () {},
          )
        ],
      ),
      body: SingleChildScrollView(
          child: ConstrainedBox(
        constraints:
            BoxConstraints(maxHeight: MediaQuery.of(context).size.height),
        child: Container(
          child: _AddAccountUI(),
        ),
      )),
    );
  }
}

class _AddAccountUI extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _AddAccountState();
  }
}

class _AddAccountState extends State<_AddAccountUI> {
  List<int> checkBoxElements = [];
  List<String> checkBoxStrings =['one','two','three','four'];

  bool _onTheSpotServices=false;
  bool _homeVisits=false;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Container(
          margin: EdgeInsets.all(10),
          child: Text(
            "Let's add your company into the system. Just fill out the form below.",
            style: Theme.of(context).textTheme.subtitle,
          ),
        ),
        _imageSelector(),
        Container(
          margin: EdgeInsets.all(20),
          child: Text(
            "Company Name",
            style: Theme.of(context).textTheme.body1,
          ),
        ),
        Container(
          margin: EdgeInsets.only(top: 5, left: 15),
          child: SizedBox(
            height: 36,
            width: MediaQuery.of(context).size.width * .90,
            child: TextFormField(
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
              decoration: InputDecoration(
                filled: true,
                fillColor: Colors.white,
                contentPadding:
                    const EdgeInsets.only(top: 2, bottom: 2, left: 8),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(30.0),
                ),
              ),
            ),
          ),
        ),
        Container(
          margin: EdgeInsets.only(top: 30, left: 20),
          child: Text(
            "Business Type",
            style: Theme.of(context).textTheme.body1,
          ),
        ),
        Container(
          margin: EdgeInsets.only(top: 10, left: 20),
          child: SizedBox(
            height: 36,
            width: MediaQuery.of(context).size.width * .90,
            child: DropdownButton<String>(
              hint: Text(
                "Please Select",
                style: Theme.of(context).textTheme.body1,
              ),
              items:
                  <String>['Foo000000000', 'Bar00000000'].map((String value) {
                return new DropdownMenuItem<String>(
                  value: value,
                  child: new Text(
                    value,
                    style: Theme.of(context).textTheme.body1,
                  ),
                );
              }).toList(),
              onChanged: (_) {},
            ),
          ),
        ),
        Container(
          margin: EdgeInsets.only(top: 30, left: 20, bottom: 10),
          child: Text(
            "Category",
            style: Theme.of(context).textTheme.body1,
          ),
        ),

        Expanded(
          child: Container(
              margin: EdgeInsets.only(left: 15),
              child: ListView.builder(
                  itemCount: 4,
                  itemBuilder: (BuildContext context, int index) {
                    return _TickBox(checkBoxElements, index);
                  })),
        ),
        Container(
          margin: EdgeInsets.only(top: 30, left: 20, bottom: 20),
          child: Text(
            "Location",
            style: Theme.of(context).textTheme.body1,
          ),
        ),
        Container(
          margin: EdgeInsets.only(top: 5, left: 15),
          child: SizedBox(
            height: 36,
            width: MediaQuery.of(context).size.width * .90,
            child: TextFormField(
              validator: (value) {
                if (value.isEmpty) {
                  return 'Please enter some text';
                }
                return null;
              },
              decoration: InputDecoration(
                filled: true,
                fillColor: Colors.white,
                contentPadding:
                    const EdgeInsets.only(top: 2, bottom: 2, left: 8),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(30.0),
                ),
              ),
            ),
          ),
        ),
        Container(child: _switchMaker(),),
        SizedBox(
          height: 50,
        )
      ],
    );
  }

  Widget _imageSelector() {
    return GestureDetector(
        onTap: () {},
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              width: 1,
              color: Color.fromRGBO(212, 208, 208, 100),
            ),
            color: Color.fromRGBO(242, 242, 242, 100),
          ),
          width: double.infinity,
          height: MediaQuery.of(context).size.height * .3,
          child: Center(child: Text("Add Your Cover Photo")),
        ));
  }

  Widget _switchMaker() {
    return Column(
      children: <Widget>[
        Row(
          children: <Widget>[
            Container(
              margin: EdgeInsets.only(top: 20, left:20),
                          child: Text(
                "Provide on the spot services",
                style: Theme.of(context).textTheme.body1,
              ),
            ),
            Spacer(flex: 1,),
            Container(margin: EdgeInsets.only(top:20, right: 20),
                          child: Text(
                "Make Home Visits",
                style: Theme.of(context).textTheme.body1,
              ),
            )
          ],
        ),
        Row(children: <Widget>[
          Container(
            margin: EdgeInsets.only(top: 10, left: 20),
            child: Switch(value: _onTheSpotServices, onChanged: (bool value) {
              setState(() {
                _onTheSpotServices=value;
              });
            }, )),
          Spacer(flex: 1,),
          Container(
            margin: EdgeInsets.only(top:10, right:20),
            child: Switch(value: _homeVisits, onChanged: (bool value) {
              setState(() {
                _homeVisits=value;
              });
            }, )),
        ],)
      ],
    );
  }
}

class _TickBox extends StatefulWidget {
  List<int> checkBoxElements = [];
  int dataValue = 0;

  _TickBox(List<int> elements, int value) {
    checkBoxElements = elements;
    dataValue = value;
  }

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _TickBoxState();
  }
}

class _TickBoxState extends State<_TickBox> {
  bool value = false;

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Container(
      child: CheckboxListTile(
        title: Text(
          "Garage shop with general repair",
          style: Theme.of(context).textTheme.body1,
        ),
        onChanged: (bool val) {
          setState(() {
            value = val;

            if (widget.checkBoxElements.contains(widget.dataValue)) {
              widget.checkBoxElements.remove(widget.dataValue);
            } else {
              widget.checkBoxElements.add(widget.dataValue);
            }

            print(widget.checkBoxElements);
          });
        },
        value: value,
        controlAffinity: ListTileControlAffinity.leading,
      ),
    );
  }
}

Now the issue is, the items generated by the ListView.Builder are totally compacted, only one item is visible. To see the rest, you have to scroll.

I tried using physics: const NeverScrollableScrollPhysics() and shrinkWrap:false to stop the scroll. It did work, however the items are still compacted.

tHIS IS how it looks like. To check the checkboxes, look under Category

enter image description here

I NEED these items to be displayed in full, without scrolling.How can I do that?

Upvotes: 1

Views: 1184

Answers (2)

NduJay
NduJay

Reputation: 810

Use 'SingleChildScrollView'. That should get you going!

Upvotes: 0

Mob Dev
Mob Dev

Reputation: 934

You need to remove the Expanded widget and add the following properties in ListView.builder:

      Container(
        child: ListView.builder(
        shrinkWrap: true,
        physics: const NeverScrollableScrollPhysics(),
        itemCount: 4,
        itemBuilder: (BuildContext context, int index) {
          return _TickBox(checkBoxElements, index);
        }),
      ),

Upvotes: 4

Related Questions