Search code examples
flutter

Flutter Dynamic Tabs with Expanded/Flex Widget in a row


I am trying to create custom titlebar layout for my windows version of flutter app. The blank space between open file button and windows action buttons is MoveWindow Widget which acts as a drag handle.

When tabs are added the tabbar should grow to the maxwidth and if started to overflow, the tabbar should be scrollable.

Initial State End State

These two images indicate the initial and final state of my UI.

class DynamicTabs extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(body: DefaultTabController(
      length: 6,
      child: Row(children: [
        IconButton(icon: Icon(Icons.home), onPressed: (){}),
        Flexible(child: TabBar(
          isScrollable: true,
          tabs: [
          Tab(text: "Tab 1"),
          Tab(text: "Tab 1"),
          Tab(text: "Tab 1"),
          Tab(text: "Tab 1"),
          Tab(text: "Tab 1"),
          Tab(text: "Tab 1"),
          Tab(text: "Tab 1"),
        ])),
        Expanded(child: MoveWindow()),
        WindowsActionButtons()
      ])
    ));
  }
}

This is the code snippet I am trying to achieve that behavior. Currently, both [tabbar and MoveWindow] are taking equal space. I know that when there is more than one flex widget inside row/col, they divide the space equally but unable to find any way to implement this.

The expected behavior is that initially there will be no tabs and the MoveWindow() widget will take all remaining space. If files are open, tabs should grow gradually until there is little space between tabs and Windows action buttons. If there is no growing space, tabs should be scrollable.


Solution

  • you may try this

    DefaultTabController(
      length: 6,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Row(children: [
              Icon(Icons.home),
              ConstrainedBox(
                constraints: BoxConstraints(
                    maxWidth: MediaQuery.sizeOf(context).width -
                        120), //120 is estimation of total your home, action button and openfile width
                child: SingleChildScrollView(
                  scrollDirection: Axis.horizontal,
                  child: TabBar(
                    isScrollable: true,
                    tabs: [
                      Tab(text: 'Tab 1'),
                      Tab(text: 'Tab 2'),
                      Tab(text: 'Tab 3'),
                      Tab(text: 'Tab 4'),
                      Tab(text: 'Tab 5'),
                      Tab(text: 'Tab 6'),
                    ],
                  ),
                ),
              ),
              SizedBox(width: 12),
              Text("Open file"),
              Spacer(), // Use this instead divede flex the tab and button
              Icon(Icons.cancel)
            ]),
            Divider(),
          ],
        ),
      ),
    ),
    

    result:

    with tabs: enter image description here

    empty tabs: enter image description here