Push trailing widget to bottom of Flutter Navigation Rail
Asked Answered
B

3

10

How can one push the trailing widget within a Flutter Navigation Rail to the bottom of the rail? I thought it would be as simple as wrapping the trailing widget with an Expanded widget, but I get the usual flutter needs paint error message.

I can get it working if I add a Column with a first child of SizedBox with a fixed height, and then the widget I want to display, but I need the spacer to fill the available space, not a fixed height. Here's the SizedBox example which does indeed fill 200px of space, but how do I get it to fill the available space?

// other navrail properties....

     trailing: Column(
        children: [
          SizedBox(
            height: 200,
          ),
          IconButton(icon: Icon(Icons.settings), onPressed: () {})
        ],
      ),
Belvia answered 15/7, 2020 at 20:10 Comment(3)
Unfortunately you can't! One way would be to copy the NavigationRail code and tweak the trailing part so that it would be Expanded.Attune
wow, that's a pain. I might be looking at submitting my first feature request then!Belvia
I tried until I realized its not possible. Did you found any solution?Malherbe
P
18

This is not hard, use Expanded with Align widgets:

NavigationRail(
  selectedIndex: _selectedIndex,
  destinations: _destinations,
  trailing: Expanded(
    child: Align(
      alignment: Alignment.bottomCenter,
      child: Padding(
        padding: const EdgeInsets.only(bottom: 8.0),
        child: IconButton(icon: const Icon(Icons.help), onPressed: (){}),
      ),
    ),
  ),
);
Pitching answered 9/6, 2022 at 11:57 Comment(2)
As side effect, "destinations" end pushed up to top...Clitoris
This works well. Any idea on how to make it work when you have a Column within the trailing section? (e.g. when you need some text alongside the button)?Northwards
M
0

I found a solution (or workaround):

Put the NavigationRail and an Positioned widget in a Stack:

  Scaffold(
    body: Row(
      children: [
        Stack(
          children: [
            NavigationRail(
              selectedIndex: _selectedIndex,
              extended: Styling.isLargeScreen(context),
              destinations: _destinations
                  .map((d) => d.toNavigationDestination)
                  .toList(),
              onDestinationSelected: (index) => _onItemTapped(index),
            ),
            Positioned(
              bottom: 0,
              left: 0,
              right: 0,
              child: Container(
                color: Colors.amber,
                height: 100,
              ),
            )
          ],
        ),
        Expanded(
          child: _buildPage(_destinations.elementAt(_selectedIndex).key),
        ),
      ],
    ),
  );

Hopefully it gets fixed soon!

Malherbe answered 16/6, 2021 at 20:56 Comment(0)
D
0

I tried Ricardo's answer, a widget I put aligned in the center of NavigationRail.

Inside the NavigationRail, it uses Column, which is where destinations and trailing are placed. As you know, the default value of the crossAxisAlignment of Column is crossAxisAlignment.center.

But I want my widget to be aligned from the left side, Below worked fine.

Row(
  children: [
    // left area
    Column(
      // You can choose start, center, left.
      // baseline, strech results runtime error!
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // NavigationRail
        Expanded(
          child: NavigationRail(
            selectedIndex: _selected,
            destinations: _destinations,
          ),
        ),
        // bottom
        Padding(
          padding: const EdgeInsets.all(16.0),
          child: Text('bottom-left text'),
        )
      ],
    ),
    // right area
    Expanded(
      child: _content,
    ),
  ],
)
Dagall answered 14/11, 2023 at 7:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.