Why whole TabBar not working when added to scaffold body? - flutter

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"),
),
),
),
),

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 move tabs to beneath the app title

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,
...

Flutter container inside a container using a widget

I want to add two boxes, one inside another. Here's my code and its not working for two boxes. how should I correct this. doc UI in this doc you can see the UI I implement so far and the UI I want to be implement.
Widget DetailBox() => Padding(
padding: const EdgeInsets.only(left: 25, right: 25),
child:Column(
children: [
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: Colors.white,
),
// alignment: Alignment.bottomCenter,
height: 400,
width: 300,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(30.0),
color: Colors.lightBlue,
),
// alignment: Alignment.bottomCenter,
height: 100,
width: 300,
),
),
],
),
);
May it help you
Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(25),
),
elevation: 5,
shadowColor: Colors.blue.shade200,
child: Column(
children: [
Expanded(
flex: 1,
child: Container(
decoration: BoxDecoration(
color: Colors.lightBlueAccent,
borderRadius: BorderRadius.only(topLeft:Radius.circular(25),topRight:Radius.circular(25))
),
),
),
Expanded(
flex: 3,
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(bottomRight:Radius.circular(25),bottomLeft:Radius.circular(25))
),
),
)
],
),
),
According to the design of the app, put the image in the bule box.

Add border to a Container with borderRadius in Flutter

Container(
child: Text(
'This is a Container',
textScaleFactor: 2,
style: TextStyle(color: Colors.black),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
border: Border(
left: BorderSide(
color: Colors.green,
width: 3,
),
),
),
height: 50,
),
This is supposed to show a rounded-edged container with a green left border 3px wide, and the child Text "This is a Container". However, it just shows a rounded-edged container with an invisible child and an invisible left border.
When I take out the borderRadius object, the child Text and the green left border is visible, but introducing it hides the left border and child Text again.
The major problem seems to be the custom left border, because using border: Border.all(width: 0) and borderRadius: BorderRadius.circular(10) makes the edges rounded as needed and also shows the child. But now I cant apply the green left border which is quite important in this particular setup.
So is there something I'm doing wrong, or is this a bug in flutter, or is it just something that is not allowed?
Thank you in advance.
Edit: The image below is the end result. The colors don't matter
It's not possible to add border: and borderRadius: at the same time, you'll get this error:
A borderRadius can only be given for uniform borders.
You can achieve what you want using the borderRadius: and a boxShadow: instead of border: like this:
boxShadow: [
BoxShadow(color: Colors.green, spreadRadius: 3)
]
Your sample code would be like this:
Container(
child: Text(
'This is a Container',
textScaleFactor: 2,
style: TextStyle(color: Colors.black),
),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Colors.white,
boxShadow: [
BoxShadow(color: Colors.green, spreadRadius: 3),
],
),
height: 50,
),
Edit: To achieve the example you now provided, you could do this:
Container(
padding: EdgeInsets.only(left: 12.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.green,
),
height: 50,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topRight: Radius.circular(10.0),
bottomRight: Radius.circular(10.0)),
color: Colors.white,
),
child: Text(
'This is a Container',
textScaleFactor: 2,
style: TextStyle(color: Colors.black),
),
),
),
Another solution:
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Colors.white,
),
height: 50,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
width: 12.0,
decoration: BoxDecoration(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(10.0),
bottomLeft: Radius.circular(10.0)),
color: Colors.green,
),
),
Text(
'This is a Container',
textScaleFactor: 2,
style: TextStyle(color: Colors.black),
)
],
),
),
There is an answer here
Container(
decoration: BoxDecoration(
border: Border.all(
color: Color(0xFFF05A22),
style: BorderStyle.solid,
width: 1.0,
),
color: Colors.transparent,
borderRadius: BorderRadius.circular(30.0),
),
),
This might be so late but also it might be useful for others.
You can wrap your Container inside a ClipRRect, give the ClipRRect the radius and give the Container the border!
Example:
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
child: Container(
height: 100,
width: double.maxFinite,
padding: const EdgeInsets.all(16.0),
decoration: BoxDecoration(
border: Border(
left: BorderSide(width: 8.0, color: Colors.green),
),
),
),
),
This should do the UI you lastly posted.
If you want to achieve borderRadius you could also use a PhysicalModel, but you'll have to provide colour. You also can have a shadow for your widget.
PhysicalModel(
color: Colors.red,
elevation: 5,
shadowColor: Colors.blue,
borderRadius: BorderRadius.circular(20),
child: SizedBox(width: 75, height: 75),
)
I think an easier way inspired by #pablo 's answer would be to just make a boxShadow with and offset but without any blur.
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.vertical(
top: Radius.circular(10),
),
boxShadow: [
// to make elevation
BoxShadow(
color: Colors.black45,
offset: Offset(2, 2),
blurRadius: 4,
),
// to make the coloured border
BoxShadow(
color: Colors.blue,
offset: Offset(0, 4),
),
],
),
The decoration above will give us an elevated box which has a blue border in the bottom.
Another benefit of this approcah is that you can use it with
borderRadius: BorderRadius.circular(num)
Which means you can have a container with all rounded sides + a colored border.
Please note that the coloured border comes under the original shadow. This is done to prevent the elevation color from darkening the border.
I archieve do a Inkwell (that simulate a button) circular with an icon inside :
InkWell(
onTap: (){},
child: Container(
width: 50,
height: 50,
decoration: ShapeDecoration(
shape: CircleBorder(), //here we set the circular figure
color: Colors.red
),
child: Center(
child: Icon(
Icons.email,
size: 30,
color: Colors.white,
)
),
)
)
link example of result: https://images.vexels.com/media/users/3/140138/isolated/preview/88e50689fa3280c748d000aaf0bad480-icono-de-ronda-de-correo-electronico-1.png
////Hope this will work for you,Thanks
import 'package:flutter/material.dart';
class System extends StatefulWidget {
const System({Key? key}) : super(key: key);
#override
_SystemState createState() => _SystemState();
}
class _SystemState extends State<System> {
#override
Widget build(BuildContext context) {
return Scaffold(
body:Padding(
padding: const EdgeInsets.only(top:80.0),
child: Column(
children: [
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
height: 100,
width: double.maxFinite,
padding: const EdgeInsets.all(16.0),
decoration: const BoxDecoration(
color: Color(0xffF6EBEC),
border: Border(
bottom: BorderSide(width: 8.0, color: Color(0xffA24949)),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircleAvatar(
backgroundColor: Color(0xffA24949),
child: Icon(Icons.close,
color: Color(0xffF6EBEC), size: 40),
),
const SizedBox(width: 10),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text("Invalid",
style: TextStyle(color: Color(0xffA24949), fontSize: 18)),
SizedBox(
width: 243,
child: Text("Details do not match the issuer records",overflow: TextOverflow.ellipsis,maxLines: 1,))
])
],
),
),
),
),
),
SizedBox(height: 20,),
ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(16.0)),
child: Padding(
padding: const EdgeInsets.all(15.0),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
height: 100,
width: double.maxFinite,
padding: const EdgeInsets.all(16.0),
decoration: const BoxDecoration(
color: Color(0xFFE9F6EB),
border: Border(
bottom: BorderSide(width: 8.0, color: Color(0xFF69A258),),
),
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
const CircleAvatar(
backgroundColor: Color(0xFF69A258),
child: Icon(Icons.check_rounded,
color: Color(0xFFE9F6EB), size: 40),
),
const SizedBox(width: 15),
Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text("Valid",
style: TextStyle(color: Color(0xFF69A258), fontSize: 18)),
Text("Document successfully validated.")
])
]),
),
),
),
),
],
),
),
);
}
}

border radius not apply inside container widget

Border radius not apply inside child Container.
Tried with SizedBox & Stack widget.
I need border view inside container.
Scaffold(
appBar: AppBar(
title: new Text("ListView"),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(15.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
border: Border.all(
color: Colors.green,
width: 2.0
)
),
child: Container(
color: Colors.red,
)
),
)
)
)
Try this,
Use ClipRRect and nest inside another Container and now you can add non-uniform borders
Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(color: Colors.black12, blurRadius: 5)],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10),
child: Container(
padding: EdgeInsets.all(20),
decoration: BoxDecoration(
border: Border(
left: BorderSide(color: Colors.indigo, width: 5),
),
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Icon(Icons.home),
Text("Home"),
],
),
),
),
)
Other answers already state that you need to use ClipRRect to apply the border radius to the child widget of Container.
However, Container widget now has its clipBehaviour property to clip its child:
Container(
// Add the line below
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
border: Border.all(color: Colors.green, width: 2.0)),
child: Container(
color: Colors.red,
),
);
It's a good pratice to use this property rather than nest the widgets for a clean code.
decoration is painted behind the child. If you want the decoration to be applied in front of the container's child, use foregroundDecoration
Scaffold(
appBar: AppBar(
title: new Text("ListView"),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(15.0),
child: Container(
foregroundDecoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
border: Border.all(
color: Colors.green,
width: 2.0
)
),
child: Container(
color: Colors.red,
)
),
)
)
)
above code paints border in front of the child container. Please note that, even with foregroundDecoration child container would still have sharp corners.
If you want the child container to have rounded corners, either you need apply borderRadius to the child container or use ClipRRect with same border radius as the parent container
Instead of
Container
widget use
ClipRRect
Before (not working):
Center(
child: Container(
decoration: BoxDecoration(
borderRadius: _getAllRoundedBorderRadius(),
),
child: Hero(
tag: "CossackHero",
child: TweenImage(
last: AssetImage("images/background/cossack_0.jpg"),
first: AssetImage("images/background/c_cossack_0.jpg"),
duration: 2,
height: height,
),
),
),
),
After:
Center(
child: ClipRRect(
borderRadius: getAllRoundedBorderRadius(),
child: Hero(
tag: "CossackHero",
child: TweenImage(
last: AssetImage("images/background/cossack_0.jpg"),
first: AssetImage("images/background/c_cossack_0.jpg"),
duration: 2,
height: height,
),
),
),
),
Screenshot:
With ClipRRect (Using 2 Container)
ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Container(
width: 100,
height: 100,
color: Colors.black,
child: Container(
margin: EdgeInsets.all(8),
color: Colors.blue,
),
),
)
Without ClipRRect (Using 1 Container)
Container(
width: 100,
height: 100,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(16),
border: Border.all(
color: Colors.black,
width: 4,
),
color: Colors.blue,
),
)
Replace your code with this
Scaffold(
appBar: AppBar(
title: new Text("ListView"),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(15.0),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
border: Border.all(
color: Colors.green,
width: 2.0
)
),
child: Container(
decoration: new BoxDecoration(borderRadius:
BorderRadius.circular(15.0),
color: Colors.red,),
)
),
)
)
)
const innerRadius = 15.0;
const borderWidth = 2.0;
const borderColor = Colors.green;
const color = Colors.red;
const size = 100.0;
Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(innerRadius + borderWidth),
color: borderColor,
),
padding: EdgeInsets.all(borderWidth),
child: ClipRRect(
borderRadius: BorderRadius.circular(innerRadius),
child: Container(
color: color,
width: size,
height: size,
),
),
);
This is how it looks:
And how it works: https://codepen.io/mshibanami/pen/LYyQJXa
By the way, some answers suggest you using one Container that has decoration including border and color like this:
Container(
width: size,
height: size,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(innerRadius),
border: Border.all(
color: borderColor,
width: borderWidth,
),
color: color,
),
)
It's OK but not ideal because the inner color appears slightly outside the border. So when the border is close to the background color, it may stand out like this:
try
decoration: BoxDecoration(
gradient: new LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
stops: [0.02, 0.02],
colors: [Colors.red, Colors.white],
),
borderRadius: BorderRadius.all(Radius.circular(10)),
color: Colors.white,
boxShadow: [
BoxShadow(color: Colors.grey, blurRadius: 5.0),
],
),
you have to just add these line of code clipBehavior:Clip.hardEdge,
Scaffold(
appBar: AppBar(
title: new Text("ListView"),
),
body: Center(
child: Padding(
padding: EdgeInsets.all(15.0),
child: Container(
clipBehavior:Clip.hardEdge,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
border: Border.all(
color: Colors.green,
width: 2.0
)
),
child: Container(
color: Colors.red,
)
),
)
)
)
I guess your container might just not be visible because it has no child/height/width.
Try adding some Text as a child or if you want it to expand, you can force with SizedBox.expand.
See this answer for example on borders.