How to move tabs to beneath the app title - flutter

Im creating a page which has a few tabs to sort food into categories. For some reason theres a large white section between the top app bar where the title is and the actual tabs. I want to move the tabs up so they're below the app bar and there is not a large white space there! Does anyone know how or why this is the case? Thank you!
I am using flutter.
class FoodPage extends StatefulWidget {
#override
_FoodPageState createState() => _FoodPageState();
}
class _FoodPageState extends State<FoodPage> {
#override
Widget build(BuildContext context){
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
//primarySwatch: Colors.teal,
),
home:DefaultTabController(
length:4,
child: Scaffold(
backgroundColor:Color.fromRGBO(51, 171, 160, 100),
appBar: AppBar(
backgroundColor: Colors.white,
elevation: 5,
bottom: TabBar(
isScrollable: true,
unselectedLabelColor: Color.fromRGBO(51, 171, 160, 100),
indicatorPadding: EdgeInsets.only(left: -30,right: -30),
indicatorSize: TabBarIndicatorSize.label,
indicator: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
color: Color.fromRGBO(51, 171, 160, 100),
),
tabs: [
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
),
child: Align(
alignment: Alignment.center,
child: Text('ALL'),
),
),
),
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
),
child: Align(
alignment: Alignment.center,
child: Text('FRIDGE'),
),
),
),
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
),
child: Align(
alignment: Alignment.center,
child: Text('FREEZER'),
),
),
),
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(topLeft: Radius.circular(10),topRight: Radius.circular(10)),
),
child: Align(
alignment: Alignment.center,
child: Text('CUPBOARD'),
),
),
),
],),
),
body: TabBarView(children: [
Text('ALL FOOD HERE'),
Text('FRIDGE FOOD HERE'),
Text('FREEZER FOOD HERE'),
Text('CUPBOARD FOOD HERE')
]),
)
)
) ;
}
}

Simply you can adjust tabbar height by changing below parameter.
toolbarHeight
...
appBar: AppBar(
toolbarHeight: 50,
backgroundColor: Colors.white,
elevation: 5,
bottom: TabBar(
isScrollable: true,
...

Related

How to customize tabBar?

I want to make tapBar looking like this:
But only got this:
This is my code(DefaultTabContainer is wrapped with container with height: 600 and width: 300):
DefaultTabController(
length: 3,
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(35.h),
child: Container(
margin: EdgeInsets.symmetric(horizontal: 10.w),
decoration: BoxDecoration(
//color: const Color(0xFF1C1B20),
borderRadius: BorderRadius.circular(12),
),
child: TabBar(
controller: _tabController,
indicatorPadding:
const EdgeInsets.symmetric(vertical: 5),
indicator: const ShapeDecoration(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(5)),
),
color: Color(0xFF4F4E51),
),
labelColor: Colors.white,
physics: const NeverScrollableScrollPhysics(),
labelStyle: const TextStyle(
color: Colors.white,
fontSize: 12
),
tabs: const [
Tab(
text: "Day",
),
Tab(
text: "Week",
),
Tab(
text: "Month (Soon)",
),
]),
),
)
)
)
TabController in initState:
_tabController = TabController(vsync: this, length: numberTabs); // numberTabs = 3
I tried to make it like I want but I cannot and I don't understand why...
You can set each tabs as below
tabs:[
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
color: Colors.red,
),
child: Align(
alignment: Alignment.center,
child: Text(
"Day",
),
),
),
),]

How to create a DraggableScrollableSheet with showModelBottomSheet?

I created with showModelBottomSheet with DraggableScrollableSheet(), But the problem is the there is no appBar for show some text while dragging, ie, the SingleChildsSrollView() will move up and down while dragging.
*bottomsheet(context) {
Size size = MediaQuery.of(context).size;
return showModalBottomSheet(
backgroundColor: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.vertical(top: Radius.circular(13)),
),
context: context,
builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.all(5),
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
foregroundColor: Colors.green,
backgroundColor: Colors.white,
elevation: 1,
shadowColor: Colors.grey.shade100,
automaticallyImplyLeading: false,
title: const Text('Connect with Reconnect'),
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(
25,
),
child: Container(
padding: const EdgeInsets.only(
left: 15,
right: 15,
top: 15,
),
height: size.height,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(13),
boxShadow: const [
BoxShadow(blurRadius: 2, color: Colors.grey),
],
),
child: Column(children: [
TextField(
cursorColor: Colors.green,
decoration: InputDecoration(
label: const Text('Name'),
labelStyle: TextStyle(color: Colors.grey.shade500),
icon: const Icon(
FontAwesomeIcons.user,
color: Color(0xff453e3d),
size: 22,
),
border: InputBorder.none,
),
),
Container(
width: 315,
height: 1,
margin: const EdgeInsets.only(top: 3, bottom: 3),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(100),
),
),
TextField(
cursorColor: Colors.green,
decoration: InputDecoration(
label: const Text('Email'),
labelStyle: TextStyle(color: Colors.grey.shade500),
icon: const Icon(
FontAwesomeIcons.envelope,
color: Color(0xff453e3d),
size: 22,
),
border: InputBorder.none,
),
),
Container(
width: 315,
height: 1,
margin: const EdgeInsets.only(top: 3, bottom: 3),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(100),
),
),
TextField(
cursorColor: Colors.green,
decoration: InputDecoration(
label: const Text('Phone Number'),
labelStyle: TextStyle(color: Colors.grey.shade500),
icon: const Icon(
FontAwesomeIcons.mobileAlt,
color: Color(0xff453e3d),
size: 22,
),
border: InputBorder.none,
),
),
Container(
width: 315,
height: 1,
margin: const EdgeInsets.only(top: 3, bottom: 3),
decoration: BoxDecoration(
color: Colors.grey[300],
borderRadius: BorderRadius.circular(100),
),
),
Container(
margin: const EdgeInsets.only(top: 10),
height: 25,
alignment: Alignment.bottomLeft,
child: Row(
children: [
const Icon(
FontAwesomeIcons.car,
color: Color(0xff453e3d),
),
const SizedBox(
width: 15,
),
Text(
'Services',
style: TextStyle(
color: Colors.grey.shade500, fontSize: 16),
),
],
),
),
]),
),
),
),
),
);
});
}*
I need a bar on top of the singlechildscrollview, I tried with column instead, but no result.
The Problem will solve by the following code!
body: Center(
child: Column(
children: [
const SizedBox(
height: 400,
),
ElevatedButton(
onPressed: () =>
//The showModelBottomSheet Will push a sheet to our page for show widgets and actions
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) =>
//The DraggableScrollableSeet will drag top to bottom or vise versa with respect to user interaction.
DraggableScrollableSheet(
initialChildSize: .6,
maxChildSize: .9,
minChildSize: .2,
builder: (context, controller) =>
//The customsheet method will return a widget with a child CustoomScrollView to Drag our DraggableScrollableSheet.
customSheet(context, controller),
),
),
child: const Text('clickme'),
),
],
),
),
//customSheet body
Widget customSheet(BuildContext context, ScrollController controller) {
return Container(
alignment: Alignment.bottomLeft,
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
// While use the CustomScrollView have an SliverAppBar for set our bar to constant, ie, the appBar will not move while dragging
child: CustomScrollView(
controller: controller,
slivers: [
SliverAppBar(
shadowColor: Colors.grey.shade100,
elevation: 1,
pinned: true,
backgroundColor: Colors.white,
automaticallyImplyLeading: false,
title: Container(
margin: const EdgeInsets.only(bottom: 45),
width: 60,
height: 4,
color: Colors.grey.shade300),
shape: RoundedRectangleBorder(
side: BorderSide(color: Colors.grey.shade200),
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
),
SliverFillRemaining(
hasScrollBody: false,
child: Column(
children: [
for (int i = 0; i < 10; i++)
Container(
width: 100,
height: 100,
color: Colors.green[i * 100],
),
],
),
)
],
),
);
}
Problem: The above code has a problem with an exit from the DraggableScrollableSheet(),
this is because if we use a GestureDetecter instead of DraggableScrollableSheet(), the child will pop by the following code
GestureDetector(onTap: ()=>Navigator.of(context).pop(),behavior: HitTestBehavior.opaque,
child: DraggableScrollableSheet(
initialChildSize: .6,
maxChildSize: .9,
minChildSize: .2,
builder: (context, controller) =>
customSheet(context, controller),
),
),
But we cannot pop the sheet with tapped by outside of the DraggableScrollabelSheet().
Note: the HitTestBehaviour.opaque will pop the sheet but if we tap anywhere in the Scaffold.
Thank You for following me up and If you have the solution, Please ping me #sureshm2suresh#gmail.com

Image not showing up in ListView

I know the code is a little messy, still learning.
I have placed the Image outside of the BoxDecoration but noting is showing up. Nothing shows up in the RUN as an error. I am guessing that it has something to do with the container inside the ListView but haven't been able to find out why its blank.
import 'package:flutter/material.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
elevation: 0.0,
title: Text("App"),
),
body: SafeArea(
child: Container(
height: 80,
decoration: new BoxDecoration(
color: Colors.blue,
borderRadius: new BorderRadius.only(
bottomLeft: const Radius.circular(40.0),
bottomRight: const Radius.circular(40.0))
),
child: ListView(
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 10.0),
width: 120,
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey[300],
offset: Offset(1, 1),
blurRadius: 0
),
], // BoxShadow
borderRadius: BorderRadius.all(Radius.circular(20))
),
child: ListTile(
leading: Icon(Icons.search, color: Colors.red),
title: TextField(
decoration: InputDecoration(
hintText: "What stuff do you want to seach for?",
hintStyle: TextStyle(fontSize: 16, color: Colors.grey),
border: InputBorder.none
),
),
trailing: Icon(Icons.filter_list, color: Colors.red),
),
),
SizedBox(height: 5),
Container(
height: 220,
width: 220,
child: Column(
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.red,
offset: Offset(1, 1),
blurRadius: 4
),
],
),
child: Image.asset("assets/images/1.jpg"),
),
],
),
),
],
),
),
)
);
}
}
This is what I am trying to do.
I updated the structure as a Column with two children:
The blue Container with the TextField
The ListView with the pictures
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter Demo',
home: Home(),
),
);
}
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(elevation: 0.0, title: Text("App")),
body: SafeArea(
child: Column(
children: [
Container(
padding: EdgeInsets.all(20.0),
decoration: const BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(40.0),
bottomRight: Radius.circular(40.0),
),
),
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20.0),
),
child: const ListTile(
leading: Icon(Icons.search),
title: TextField(
decoration: InputDecoration(
hintText: "What stuff do you want to seach for?",
hintStyle: TextStyle(fontSize: 16, color: Colors.grey),
border: InputBorder.none,
),
autofocus: true,
),
trailing: Icon(Icons.filter_list),
),
),
),
SizedBox(
height: 120.0,
child: ListView(
scrollDirection: Axis.horizontal,
shrinkWrap: true,
children: List.generate(
20,
(index) => Padding(
padding: const EdgeInsets.all(16.0),
child: Image.asset("assets/images/cartoon.jpg"),
),
),
),
),
],
),
),
);
}
}

Customize flutter Tab bar

I am using a TabBar widget and I'd like to customize the TabBar view like this image. I tried lot of times bus there are some spaces between two tabs.
this is the code I used to customize the tab view.
TabBar(
controller: _tabController,
labelColor: Colors.black12,
unselectedLabelColor: Colors.black12,
indicatorSize: TabBarIndicatorSize.label,
tabs: [
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.horizontal(
left: Radius.circular(50), right: Radius.zero),
border: _tabController.index == 1
? Border.all(color: Colors.black12, width: 2)
: Border.all(color: Colors.transparent, width: 2),
color: _tabController.index == 0
? Colors.indigo
: Colors.white,
),
child: Align(
alignment: Alignment.center,
child: Text("Income"),
),
),
),
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.horizontal(
left: Radius.zero, right: Radius.circular(50)),
border: _tabController.index == 1
? Border.all(color: Colors.transparent, width: 2)
: Border.all(color: Colors.black12, width: 2),
color: _tabController.index == 1
? Colors.indigo
: Colors.white,
),
child: Align(
alignment: Alignment.center,
child: Text("Expense"),
),
),
),
],
),
output
if you need to customize your tabs,my beautiful tabs source code may be help you,this is not relevent to this post
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class StudentScreen extends StatefulWidget {
#override
_StudentScreenState createState() => _StudentScreenState();
}
class _StudentScreenState extends State<StudentScreen> with SingleTickerProviderStateMixin {
TabController controller;
int activeTabIndex = 1;
#override
void initState() {
super.initState();
controller = TabController(
length: 2,
initialIndex: 1,
vsync: this,
);
controller.addListener(() {
setState(() {
activeTabIndex = controller.index;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: Column(
children: <Widget>[
TabBar(
indicatorColor: Colors.transparent,
tabs: [
Tab(
child: Container(
width: 100,
height: 36,
decoration: activeTabIndex == 0
? BoxDecoration(
border: Border.all(color: Colors.blue, width: 2),
borderRadius: BorderRadius.all(Radius.circular(16)),
)
: null,
child: Padding(
padding: EdgeInsets.fromLTRB(8, 4, 8, 0),
child: Center(child: Text("Tab one", style: TextStyle(color: Colors.black))),
)),
),
Tab(
child: Container(
width: 100,
height: 36,
decoration: activeTabIndex == 1
? BoxDecoration(
border: Border.all(color: Colors.blue, width: 2),
borderRadius: BorderRadius.all(Radius.circular(16)),
)
: null,
child: Padding(
padding: EdgeInsets.fromLTRB(8, 4, 8, 0),
child: Center(child: Text("Tab two", style: TextStyle(color: Colors.black))),
)),
),
],
controller: controller,
),
Container(
child: Row(
children: <Widget>[],
),
),
Expanded(
child: Container(
child: TabBarView(
controller: controller,
children: <Widget>[
Center(child: Text("Tab one")),
Center(child: Text("Tab two")),
],
),
),
)
],
),
),
);
}
}
you can give radius to whole bottom not only the two tabs
you can do something like this
just give radius to all sides I need to give only top right and top left in my case
PreferredSize(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(30),
topRight: Radius.circular(30),
),
),
child: TabBar(
// indicatorPadding: EdgeInsets.all(30),
tabs: [
Tab(
child: Text(
"Expnanse",
style: TextStyle(color: Colors.black),
),
),
Tab(
child: Text(
"Income",
style: TextStyle(color: Colors.black),
),
),
],
),
),
preferredSize: const Size.fromHeight(70.0),
),
),
You neee to add:
labelPadding: EdgeInsets.all(0),
to your TabBar!

Why whole TabBar not working when added to scaffold body?

I am trying to add TabBar in body, inside a Container but an error seems to come.
ERROR:
RenderFlex children have non-zero flex but incoming width constraints are unbounded.
Code:
Container(
margin: EdgeInsets.only(top: 20),
child: DefaultTabController(
length: 3,
child: Row(children: [
TabBar(
unselectedLabelColor: Colors.redAccent,
indicatorSize: TabBarIndicatorSize.label,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.redAccent),
tabs: [
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(
color: Colors.redAccent, width: 1)),
child: Align(
alignment: Alignment.center,
child: Text("APPS"),
),
),
),
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(
color: Colors.redAccent, width: 1)),
child: Align(
alignment: Alignment.center,
child: Text("MOVIES"),
),
),
),
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(
color: Colors.redAccent, width: 1)),
child: Align(
alignment: Alignment.center,
child: Text("GAMES"),
),
),
),
]),
TabBarView(children: [
Icon(Icons.apps),
Icon(Icons.movie),
Icon(Icons.games),
])
])),
)
As, you can see I have DefaultTabController inside child of container, having a row where first is TabBar and second is TabBarView.
So, what am I doing wrong here?
Also, I know the usual convention is to have tabbar in a appbar. but that doesn't work with my design. Even if I have to add tabbar in appbar then I have to increase the height of appbar as per my design which is why opted for this kind of approach.
Thanks
Replace Row with Column
DefaultTabController(
length: 3,
child: Column(children: [ // Column Here
Wrap TabBarView with Expanded
Expanded(
child: TabBarView(children: [
Icon(Icons.apps),
Icon(Icons.movie),
Icon(Icons.games),
]),
)
I think you should add the TabBar to the appbar field in the Scaffold, as this:
Scaffold(
appBar: AppBar(
title: const Text('Tabbed AppBar'),
bottom: TabBar(
unselectedLabelColor: Colors.redAccent,
indicatorSize: TabBarIndicatorSize.label,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(50),
color: Colors.redAccent),
tabs: [
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(
color: Colors.redAccent, width: 1)),
child: Align(
alignment: Alignment.center,
child: Text("APPS"),
),
),
),
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(
color: Colors.redAccent, width: 1)),
child: Align(
alignment: Alignment.center,
child: Text("MOVIES"),
),
),
),
Tab(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50),
border: Border.all(
color: Colors.redAccent, width: 1)),
child: Align(
alignment: Alignment.center,
child: Text("GAMES"),
),
),
),
),