1

I have a scrolableView with x amount of ExpansionTiles, I need to place the 'Test' button on the bottom of the page, only if a number of tiles are fitting the screen or if they expand within the page, else to push the button off the screen.

import 'package:flutter/material.dart';

class MyHomePage extends StatelessWidget {
  MyHomePage({Key? key}) : super(key: key);

  List datas = [1, 2, 3, 4, 5, 6];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: SingleChildScrollView(
          child: Column(
            children: [
              ListView.builder(
                physics: NeverScrollableScrollPhysics(),
                itemCount: datas.length,
                shrinkWrap: true,
                itemBuilder: (context, i) {
                  return ExpansionTile(
                      title: Text(
                        datas[i].toString(),
                      ),
                      children: List.generate(
                        datas.length,
                        (index) {
                          return Text(datas[index].toString());
                        },
                      ));
                },
              ),
              ElevatedButton(onPressed: () {}, child: Text('Test'))
            ],
          ),
        ),
      ),
    );
  }
}

Button should be on the bottom

Button is off-screen and in scrollable like it should

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
Alex Apps
  • 317
  • 6
  • 19

1 Answers1

1

The UX is a little tricky. It will be easy and get better performance using CustomScrollView.

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
          child: CustomScrollView(
        slivers: [
          SliverList(
            delegate: SliverChildListDelegate.fixed(
              [
                ...datas
                    .map((e) => ExpansionTile(
                        title: Text(
                          e.toString(),
                        ),
                        children: List.generate(
                          datas.length,
                          (index) {
                            return Text(datas[index].toString());
                          },
                        )))
                    .toList(),
              ],
            ),
          ),
          SliverFillRemaining(
            hasScrollBody: false,
            child: Align(
              alignment: Alignment.bottomCenter,
              child: ElevatedButton(
                onPressed: () {},
                child: const Text('Test'),
              ),
            ),
          )
        ],
      )),
    );
  }

The important thing is using SliverFillRemaining with hasScrollBody: false along with Align child.

More about CustomScrollView.

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
  • This seems to be the best solution. I did try before with slivers but probably in the wrong way. Thanks. – Alex Apps Jul 03 '22 at 17:42