Shourya Shikhar
Shourya Shikhar

Reputation: 1524

How can I vertically center all the widgets inside a ListView?

I have this main screen with a ListView: Screenshot

I decided to use a ListView as it resulted in screen overflow error each time the keyboard opened up.

This is my code:

ListView(children: [
  Align(
    alignment: Alignment.topCenter,
    child: Padding(
      padding: const EdgeInsets.only(top: 46.0, bottom: 8),
      child: ClipRect(
        child: Image.asset(
          'images/icon.png',
          scale: 2,
        ),
      ),
    ),
  ),
  Align(
    alignment: Alignment.center,
    child: Padding(
      padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 12.0),
      child: TextField(
        controller: _word,
        textAlign: TextAlign.center,
        decoration: InputDecoration(
          suffixIcon: IconButton(
            icon: Icon(Icons.close),
            onPressed: () {
              _word.text = '';
            },
          ),
          border: OutlineInputBorder(
            borderRadius: BorderRadius.circular(10.0),
          ),
          filled: true,
          fillColor: Colors.lightGreen[200],
          hintStyle: TextStyle(color: Colors.green),
          hintText: 'Enter a word',
        ),
      ),
    ),
  ),
  Align(
    alignment: Alignment.bottomCenter,
    child: Padding(
      padding: const EdgeInsets.only(top: 16, bottom: 12),
      child: ConstrainedBox(
        constraints: BoxConstraints.tightFor(width: 65, height: 65),
        child: ElevatedButton(
            style: ButtonStyle(
                shape: MaterialStateProperty.all<CircleBorder>(CircleBorder())),
            child: Icon(Icons.search),
            onPressed: () async {
              detectNetStatus(context);
              String word = _word.text;
              _word.text = '';
              Navigator.push(context, MaterialPageRoute(builder: (context) {
                return word == '' ? RandomResults() : Results(word);
              }));
            }),
      ),
    ),
  ),
]),

I've also used the Align widget on all the three screen widgets. But it seems that the use of Align practically has no effect on the placement of the three widgets.

I want to place the three widgets in such a way that the space above and below the three widgets is equal (or in other words, I want to group and place them in a vertically centered alignment).

Upvotes: 0

Views: 573

Answers (2)

Maulik Sinroja
Maulik Sinroja

Reputation: 191

Here is the solution for your code to align the widget with centered with using of the Flex widget.

Widget build(BuildContext context) {
   return Scaffold(
  body: LayoutBuilder(
  builder: (context, viewportConstraints) {
    return SingleChildScrollView(
      child: ConstrainedBox(
        constraints: viewportConstraints.copyWith(
          minHeight: viewportConstraints.maxHeight,
          maxHeight: double.infinity,
        ),
        child: Flex(
          direction: Axis.vertical,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ClipRect(
              child: Image.asset(
                "images/icon.png",
                scale: 2,
              ),
            ),
            Padding(
              padding: const EdgeInsets.symmetric(
                  horizontal: 10.0, vertical: 30.0),
              child: TextField(
                controller: _word,
                textAlign: TextAlign.center,
                decoration: InputDecoration(
                  suffixIcon: IconButton(
                    color: Colors.green,
                    icon: Icon(Icons.close),
                    onPressed: () {
                      _word.text = '';
                    },
                  ),
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(10.0),
                  ),
                  filled: true,
                  fillColor: Colors.yellow[50],
                  hintStyle: TextStyle(color: Colors.green),
                  hintText: 'Enter a word',
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(bottom: 10.0),
              child: ConstrainedBox(
                constraints: BoxConstraints.tightFor(width: 65, height: 65),
                child: ElevatedButton(
                    style: ButtonStyle(
                        shape: MaterialStateProperty.all<CircleBorder>(
                            CircleBorder())),
                    child: Icon(Icons.search),
                    onPressed: () async {
                      detectNetStatus(context);
                      String word = _word.text;
                      _word.text = '';
                      Navigator.push(context,
                          MaterialPageRoute(builder: (context) {
                        return word == '' ? RandomResults() : Results(word);
                      }));
                    }),
              ),
            ),
          ],
        ),
      ),
    );
  },
),    
  );
}

Upvotes: 0

Md. Yeasin Sheikh
Md. Yeasin Sheikh

Reputation: 63769

This code will help you to get the concepet. if you need layoutSize wrap Stack with LayoutoutBuilder to get the constrains.

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Stack(
        children: [
          Align(
            alignment: Alignment.topCenter,
            child: Padding(
              padding: const EdgeInsets.only(top: 46.0, bottom: 8),
              child: ClipRect(
                child: Image.asset(
                  // 'images/icon.png',
                  "assets/me.jpg",
                  scale: 2,
                ),
              ),
            ),
          ),
          Align(
            /// change this value according to your desire
            alignment: Alignment(0, .2),
            child: ListView(
              shrinkWrap: true,
              children: [
                Padding(
                  padding: const EdgeInsets.symmetric(
                      horizontal: 24.0, vertical: 12.0),
                  child: TextField(
                    // controller: _word,F
                    textAlign: TextAlign.center,
                    decoration: InputDecoration(
                      suffixIcon: IconButton(
                        icon: Icon(Icons.close),
                        onPressed: () {
                          // _word.text = '';
                        },
                      ),
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(10.0),
                      ),
                      filled: true,
                      fillColor: Colors.lightGreen[200],
                      hintStyle: TextStyle(color: Colors.green),
                      hintText: 'Enter a word',
                    ),
                  ),
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 16, bottom: 12),
                  child: ConstrainedBox(
                    constraints: BoxConstraints.tightFor(width: 65, height: 65),
                    child: ElevatedButton(
                        style: ButtonStyle(
                            shape: MaterialStateProperty.all<CircleBorder>(
                                CircleBorder())),
                        child: Icon(Icons.search),
                        onPressed: () async {
                          // detectNetStatus(context);
                          // String word = _word.text;
                          // _word.text = '';
                          // Navigator.push(context,
                          //     MaterialPageRoute(builder: (context) {
                          //   return word == '' ? RandomResults() : Results(word);
                          // }));
                        }),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

Upvotes: 1

Related Questions