Rizal Nurul Huda
Rizal Nurul Huda

Reputation: 73

ListView with Expanded when not scrollable

I want to make a menu with list of ExpansionTile and a footer, when the ExpansionTile is not expanded (not scrollable) the footer stay on the bottom of screen, but when the ExpansionTile is expanded (scrollable) the children of ExpansionTile push the footer out of screen.

For a clearer illustration, please see the following image

enter image description here

this my current code, but it's not a best way I think

checking is scrollable or not

checkIsScrollable(BuildContext context) {
if (Scrollable.of(context).position.minScrollExtent >=
    Scrollable.of(context).position.maxScrollExtent) {
  setState(() {
    scrollable = false;
  });
} else {
  setState(() {
    scrollable = true;
  });
}

this the listview

ListView(
  padding: EdgeInsets.symmetric(horizontal: 16),
  children: [
    LimitedBox(
      maxHeight: !scrollable
          ? MediaQuery.of(context).size.height - 84
          : double.infinity,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          SizedBox(
            height: 24,
          ),
          Text(
            "Account".toUpperCase(),
            style: ThemeApp.appBarTextStyle(),
          ),
          SizedBox(
            height: 24,
          ),
          photoProfile(),
          SizedBox(
            height: 40,
          ),
          menuProfile(),
          SizedBox(
            height: 40,
          ),
          AccountContent.customerCare1(
            context: context,
            onExpansionChanged: (_) {
              Future.delayed(
                Duration(milliseconds: 101),
                () {
                  checkIsScrollable(context);
                },
              );
            },
          ),
          AccountContent.sellWithUs(
            context: context,
            onExpansionChanged: (_) {
              Future.delayed(
                Duration(milliseconds: 101),
                () {
                  checkIsScrollable(context);
                },
              );
            },
          ),
          AccountContent.customerCare2(
            context: context,
            onExpansionChanged: (_) {
              Future.delayed(
                Duration(milliseconds: 101),
                () {
                  checkIsScrollable(context);
                },
              );
            },
          ),
          !scrollable
              ? Expanded(
                  child: Container(),
                )
              : Container(),
          Container(
            padding: EdgeInsets.symmetric(vertical: 16),
            child: Column(
              children: [
                InkWell(
                  child: Row(
                    children: [
                      Container(
                        height: 18,
                        width: 18,
                        color: ThemeApp.borderColor,
                      ),
                      SizedBox(width: 10),
                      Text(
                        "LOGOUT",
                        style: ThemeApp.subTitleTextStyle(),
                      ),
                    ],
                  ),
                  onTap: () {},
                ),
                SizedBox(
                  height: 20,
                ),
                Row(
                  children: [
                    Expanded(
                      child: BorderedButton(
                        child: SvgPicture.asset(
                          "assets/icons/icon_whatsapp.svg",
                          color: ThemeApp.primaryColor,
                        ),
                        onTap: () {
                          openWhatsapp();
                        },
                      ),
                    ),
                    SizedBox(
                      width: 17,
                    ),
                    Expanded(
                      child: BorderedButton(
                        child: SvgPicture.asset(
                          "assets/icons/icon_instagram.svg",
                          color: ThemeApp.primaryColor,
                        ),
                        onTap: () {
                          openInstagram();
                        },
                      ),
                    ),
                    SizedBox(
                      width: 17,
                    ),
                    Expanded(
                      child: BorderedButton(
                        child: SvgPicture.asset(
                          "assets/icons/icon_mail.svg",
                          color: ThemeApp.primaryColor,
                        ),
                        onTap: () {
                          openMail();
                        },
                      ),
                    ),
                  ],
                ),
              ],
            ),
          )
        ],
      ),
    ),
  ],
);

Upvotes: 2

Views: 1107

Answers (3)

Mahdi Dahouei
Mahdi Dahouei

Reputation: 1941

You should use a Column inside of LayoutBuilder and with a ConstrainedBox, set The minHeight of the Column to maxHeight of LayoutBuilder:

  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (BuildContext context, BoxConstraints viewportConstraints) {
        return  SingleChildScrollView(
          physics: const AlwaysScrollableScrollPhysics(),
          child: ConstrainedBox(
            constraints: BoxConstraints(
              minHeight: viewportConstraints.maxHeight,
            ),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                YourListView(
                  physics: NeverScrollableScrollPhysics(),
                  shrinkWrap: true,
                ),
                YourFooter(),
              ],
            ),
          ),
        );
      },
    );
  }

Upvotes: 2

Zeshan Ul Haque
Zeshan Ul Haque

Reputation: 74

The footer you don't want to scroll, make the Column having two children and inside the column add another column and put the scrollable data inside that and wrap that with the SingleChildScrolView.

Column(
children: [
SingleChildScrollView(
child: Column(
children: [
// your scrollable data here
],
Column(
children: [
// Footer not scrollable
],),
],

Upvotes: 1

Navid Shokoufeh
Navid Shokoufeh

Reputation: 569

I didn't get your question correctly but i guess you need too use Stack widget which always stays your footer on it's place even your page is Scrollable.

Upvotes: 1

Related Questions