Jonathan Gómez
Jonathan Gómez

Reputation: 443

DefaultTabController without Scaffold?

I'm trying to use DefaultTabController in the middle of some widgets. So my TabBar could not be in AppBar and has to be down some widgets. So my problem is when I use TabBarView it crashes...

So here's an example of Flutter sample but no found how to do it without Scaffold.

final List<Tab> myTabs = <Tab>[
  Tab(text: 'LEFT'),
  Tab(text: 'RIGHT')];

Code

DefaultTabController(
  length: myTabs.length,
  child: Scaffold(
    appBar: TabBar(
      tabs: myTabs,
    ),
    body: TabBarView(
      children: myTabs.map((Tab tab) {
        final String label = tab.text.toLowerCase();
        return Center(
          child: Text(
            'This is the $label tab',
            style: const TextStyle(fontSize: 36),
          ),
        );
      }).toList(),
    ),
  ),
);

Here is another example of a TabBar I should do image

Real Code

class ProfileTabBarNavigation extends StatelessWidget {
 final List<Tab> myTabs = <Tab>[
   const Tab(text: kArtwork),
   const Tab(text: kPastJobs)];
@override
Widget build(BuildContext context) {
return DefaultTabController(
  length: 2,
  initialIndex: 0,
  child: Padding(
    padding: kPaddingTabBar,
    child: Container(
      padding: EdgeInsets.all(5.0),
      decoration: BoxDecoration(
        color: kLightGrey,
        borderRadius: BorderRadius.all(
          Radius.circular(50),
        ),
      ),
      child: Column(children: <Widget>[
        TabBar(
          tabs: myTabs,
          unselectedLabelColor: Colors.black54,
          labelColor: Colors.black,
          unselectedLabelStyle: kBoldText,
          labelStyle: kBoldText,
          indicatorSize: TabBarIndicatorSize.tab,
          indicator: BoxDecoration(
            shape: BoxShape.rectangle,
            borderRadius: BorderRadius.circular(50),
            color: Colors.white,
          ),
        ),
        TabBarView(
          children: myTabs.map((Tab tab) {
            final String label = tab.text.toLowerCase();
            return Center(
              child: Text(
                'This is the $label tab',
                style: const TextStyle(fontSize: 36),
              ),
            );
          }).toList(),
        ),
      ]),
    ),
  ),
);
}
}

Upvotes: 10

Views: 10471

Answers (4)

GraSim
GraSim

Reputation: 4210

You can put the TabBar and TabbarView in a Column as long as the TabBarView is enclosed with an Expanded widget.

return DefaultTabController(
  length: 2,
  child: Column(
    children: [
      TabBar(...),
      Expanded(
        child: TabBarView(...),
            ),
          ],
        ),
      );

Upvotes: 1

Kalpesh Khandla
Kalpesh Khandla

Reputation: 746

  Create a stateful widget like below

  import 'package:flutter/material.dart';
  import 'package:flutter_text_to_image/utils/app_colors.dart';
  
  /*
  Title: TabBarWidget
  Purpose: To Display TabBar in a Screen
  Created On : 16/11/2022
  Last Updated on : 16/11/2022
  Author : Kalpesh Khandla
  */

  class TabBarWidget extends StatefulWidget {
  final String firstTabTxt;
  final String firstTabViewTxt;
  final String secondTabTxt;
  final String secondTabViewTxt;
  const TabBarWidget({
  super.key,
  required this.firstTabTxt,
  required this.secondTabTxt,
  required this.firstTabViewTxt,
  required this.secondTabViewTxt,
  });
  @override
  State
  <TabBarWidget>
  createState() => _TabBarWidgetState();
  }
  class _TabBarWidgetState extends State
  <TabBarWidget>
  with SingleTickerProviderStateMixin {
  TabController? _tabController;
  @override
  void initState() {
  _tabController = TabController(length: 2, vsync: this);
  super.initState();
  }
  @override
  void dispose() {
  _tabController?.dispose();
  super.dispose();
  }
  @override
  Widget build(BuildContext context) {
  return Container(
  height: 100,
  child: Column(
  children: [
  Container(
  height: 35,
  decoration: BoxDecoration(
  border: Border.all(
  color: AppColors.tabBorderColor,
  ),
  borderRadius: BorderRadius.circular(
  5.0,
  ),
  ),
  child: TabBar(
  controller: _tabController,
  indicator: BoxDecoration(
  gradient: LinearGradient(
  colors: [
  AppColors.waterMelonColor,
  AppColors.mangoColor,
  AppColors.azureColor,
  AppColors.sapphireColor,
  ],
  begin: FractionalOffset(0.0, 0.0),
  end: FractionalOffset(1.0, 0.0),
  stops: [
  0.1,
  0.4,
  0.6,
  1.0,
  ],
  tileMode: TileMode.clamp,
  ),
  borderRadius: BorderRadius.circular(
  2.0,
  ),
  ),
  labelColor: AppColors.whiteColor,
  unselectedLabelColor: AppColors.blackColor,
  tabs: [
  Tab(
  text: widget.firstTabTxt,
  ),
  Tab(
  text: widget.secondTabTxt,
  ),
  ],
  ),
  ),
  Expanded(
  child: TabBarView(
  controller: _tabController,
  children: [
  Padding(
  padding: EdgeInsets.only(top: 10),
  child: Column(
  children: [
  Text(
  widget.firstTabViewTxt,
  ),
  ],
  ),
  ),
  Padding(
  padding: EdgeInsets.only(top: 10),
  child: Column(
  children: [
  Text(
  widget.secondTabViewTxt,
  ),
  ],
  ),
  ),
  ],
  ),
  ),
  ],
  ),
  );
  }
  }

and use it like a below :


TabBarWidget(
firstTabTxt: "Tab1",
firstTabViewTxt: "Tab1 View",
secondTabTxt: "Tab1",
secondTabViewTxt: "Tab2 View",
),

Upvotes: -1

Kahou
Kahou

Reputation: 3488

Wrap your TabBarView with Expanded.

Expanded(
 child: TabBarView(//...),
),

Try it on DartPad

Upvotes: 11

Amir
Amir

Reputation: 2355

you can use defaultTabView in middle of screen or use one of this packages

Bubble Tab Indicator

MD2 Tab Indicator

Upvotes: 1

Related Questions