Ying Ying
Ying Ying

Reputation: 35

Responsive Container inside Row Flutter

I'm currently trying to learn Flutter. I want to create a layout like this Layout with side navigation bar and upper navigation bar in a row

I have created a class HomeScreen where it'll contains Row of the sidebar and upperbar. Like this:

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Row(
        children: <Widget>[
          SideNav(),
          RightContainer(),
        ],
      ),
    );
  }
}

Then, in side_nav.dart, I create another class like this:

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 330,
      //constraints: BoxConstraints.expand(),
      color: kBlackColor,
      child: Column(
        children: <Widget>[
          headerlogo,
        ],
      ),
    );
  }
}

Then, I create upper_nav.dart for the upper navbar.

class UpperNav extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        width: 950,
      decoration: BoxDecoration(
        color: kUpperNavbar,
        //borderRadius: BorderRadius.circular(46),
        boxShadow: [
          BoxShadow(
            offset: Offset(0, -2),
            blurRadius: 20,
            color: Colors.black.withOpacity(0.16),
          ),
        ],
      ),
      child: LayoutBuilder(builder: (context, constraints) {
        if (constraints.maxWidth > 955) {
          return DesktopNavbar();
        } else if (constraints.maxWidth > 600 && constraints.maxWidth < 955) {
          return DesktopNavbar();
        } else {
          return MobileNavbar();
        }
      }),
    );
  }
}

class DesktopNavbar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      // constraints: BoxConstraints(maxWidth: 890),
      child: Row(
        //mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          SizedBox(
            width: 700,
            height: 50,
          ),
          Text(
            'Docs',
            style: TextStyle(
              fontSize: 16,
              color: Colors.black,
              fontFamily: 'Segoe Ui',
              decoration: TextDecoration.none,
            ),
          ),
          SizedBox(
            width: 50,
          ),
          Text(
            'Getting Started',
            style: TextStyle(
              fontSize: 16,
              color: Colors.black,
              fontFamily: 'Segoe Ui',
              decoration: TextDecoration.none,
            ),
          ),
        ],
      ),
    );
  }
}

class MobileNavbar extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

I have to set the width to 950 so that the upper navbar fit to the screen. I wonder how can I adjust the width so that it fitted to screen even if I changed the width of the sidebar and also make it responsive? Appreciate if anyone could help me. Thanks!

Upvotes: 1

Views: 1166

Answers (2)

Mohamed Irshad
Mohamed Irshad

Reputation: 2186

For those who are using go_router, use StatefulShellRoute.indexedStack to define the Screens and then use navigationShell in different screen sizes to build body, maintain current index across all screen sizes and to navigate between screens.

and then use BottomNavigationBar for Mobile, TabBar for Browser/Desktop, and NavigationRail for iPad/Tablet.

@override
Widget build(BuildContext context) {
  if (MediaQuery.of(context).size.width < 500) {

    // Mobile phones
    return Scaffold(
      body: widget.navigationShell,
      bottomNavigationBar: BottomNavigationBar(
        items: widget.phoneBarButtons,
        onTap: (int index) => widget.navigationShell.goBranch(index),
        currentIndex: widget.navigationShell.currentIndex,
      ),
    );
  } else if (MediaQuery.of(context).size.width > 1024) {
    _tabController.index = widget.navigationShell.currentIndex;
    
    // Web Browser / Desktop
    return Scaffold(
      body: Column(
        children: [
          TabBar(
            tabs: widget.webBarButtons,
            onTap: (int index) => widget.navigationShell.goBranch(index),
            controller: _tabController,
            tabAlignment: TabAlignment.center,
          ),
          Expanded(child: widget.navigationShell),
        ],
      ),
    );
  } else {

    // iPads / Tablets
    return Scaffold(
      body: Row(
        children: [
          NavigationRail(
            destinations: widget.tabletBarButtons,
            onDestinationSelected: (int index) =>
                widget.navigationShell.goBranch(index),
            labelType: NavigationRailLabelType.all,
            selectedIndex: widget.navigationShell.currentIndex,
          ),
          Expanded(child: widget.navigationShell),
        ],
      ),
    );
  }
}

This article has more details Adaptive Navigation in Flutter: Bottom for Mobile, Side for Tablet, Top for Web with GoRouter

Upvotes: 0

Igniti0n
Igniti0n

Reputation: 151

I am guessing that this RightContainer is UpperNav? You can wrap RightContainer() with the Expanded widget, to take the rest of the space left in the Row. Then I think you don't need to set Container width explicitly and the LayoutBuilder will get the constraints based on how much space is left, and therefore you should be able to display different layouts.

Upvotes: 1

Related Questions