Related
I am using DefaultTabController widget in Flutter and the output is as below :
I want to remove left and right white background portion as you can see it in above image.
How can I remove that portion or can change the color to dark ?
So far I am trying it as below :
return ThemeData(
tabBarTheme: const TabBarTheme(
),
);
Now, here I am not able to find property that changes the white color to dark color. Please guide. Thanks.
Code :
return DefaultTabController(
length: 3,
child: Scaffold(
backgroundColor: Theme.of(context).backgroundColor,
appBar: AppBar(
titleSpacing: 24.w,
centerTitle: false,
title: Text(
Localization.of(context).labelFacilities,
style: TextStyle(
fontWeight: FontWeight.w600,
color: getBool(isDarkMode) ? whiteColor : textColorBlack,
fontSize: 20.sp),
),
actions: <Widget>[
Container(
margin: EdgeInsets.only(right: 28.w),
child: Image.asset(icSearch,
width: 18.w,
height: 18.h,
color: getBool(isDarkMode) ? whiteColor : textColorBlack),
)
],
backgroundColor: Theme.of(context).backgroundColor,
elevation: 0,
bottom: PreferredSize(
preferredSize: _tabBar.preferredSize,
child: Material(
borderRadius: BorderRadius.circular(10.w), //<-- SEE HERE
child: Container(
child: _tabBar,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: lightYellowColor,
borderRadius: BorderRadius.circular(10.w)),
margin: EdgeInsets.symmetric(horizontal: 24.w),
),
),
),
),
body: Container(
margin: EdgeInsets.only(top: 24.h, right: 24.w, left: 24.w),
child: TabBarView(
children: [
AttractionsScreen(),
EventsScreen(),
UtilitiesScreen(),
],
),
),
));
Tabbar widget is created as below :
TabBar get _tabBar => TabBar(
labelPadding: EdgeInsets.zero,
indicatorWeight: 1,
padding: EdgeInsets.zero,
indicatorPadding: EdgeInsets.zero,
labelStyle: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 14.h,
fontFamily: 'Poppins',
),
//For Selected tab
unselectedLabelStyle: TextStyle(
fontWeight: FontWeight.w400,
fontSize: 14.h,
fontFamily: 'Poppins',
),
labelColor: Colors.white,
unselectedLabelColor: textColorBlack,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(10.w), color: yellowColor),
tabs: [
Tab(
child: Align(
alignment: Alignment.center,
child: Text(Localization.of(context).labelAttractions),
),
),
Tab(
child: Align(
alignment: Alignment.center,
child: Text(Localization.of(context).labelEvents),
),
),
Tab(
child: Align(
alignment: Alignment.center,
child: Text(Localization.of(context).labelUtilities),
),
),
]);
You can find some padding properties on TabBar and set it zero.
TabBar(
padding: EdgeInsets.zero,
labelPadding: EdgeInsets.zero,
indicatorPadding: EdgeInsets.zero,
tabs: [....],
),
#1 You can add color in
Material(
color: "YOUR_COLOR",
)
#2 Remove that portion
Code:
PreferredSize(
preferredSize: _tabBar.preferredSize,
child: Material(
color: lightYellowColor, // <-- Change color HERE
borderRadius: BorderRadius.circular(10.w), //<-- SEE HERE
child: Container(
child: _tabBar,
decoration: BoxDecoration(
shape: BoxShape.rectangle,
color: lightYellowColor,
borderRadius: BorderRadius.circular(10.w)),
margin: EdgeInsets.symmetric(horizontal: 24.w), //<--Remove that portion
),
),
),
I'm trying to get an expandableTextFormField in bottomNavBar that will automatically increase in height as the user types into a new line. In my bottomNavBar code below, I gave the container a height of 60px so it doesn't take up the whole screen.
bottomNavigationBar: SafeArea(
child: Container(
height: 60,
color: Colors.white,
margin: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom),
padding: const EdgeInsets.only(
left: 12,
right: 8,
),
child: Row(
children: [
CircleAvatar(
backgroundImage: NetworkImage(url),
radius: 15,
),
Flexible(
child: Padding(
padding: const EdgeInsets.only(
left: 16,
right: 8,
top: 2,
bottom: 2,
),
child: TextFormField(
expands: true,
maxLines: null,
minLines: null,
style: TextStyle(
fontSize: 14,
),
textCapitalization: TextCapitalization.sentences,
controller: commentEditingController,
decoration: InputDecoration(
filled: true,
fillColor: Color(0x27AFAFAF),
hintText: 'Comment as $displayName...',
hintStyle: TextStyle(color: Color(0xFFAFAFAF)),
),
),
),
),
InkWell(
onTap: () {
},
child: Container(
padding: const EdgeInsets.symmetric(
vertical: 8, horizontal: 8),
child: const Text(
'Post',
style: TextStyle(color: Colors.blue),
),
),
)
],
),
);
},
),
),
I also attached a screenshot for more explanation of what I'm talking about:
here's my implementation
Container(
margin: const EdgeInsets.only(top: 20, bottom: 8),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.1),
borderRadius: BorderRadius.circular(2),
),
constraints: BoxConstraints(
minWidth: MediaQuery.of(context).size.width,
maxWidth: MediaQuery.of(context).size.width,
minHeight: 25.0,//min height you want to take by container
maxHeight: 100.0,//max height you want to take by container
),
child: Scrollbar(
child: TextField(
keyboardType: TextInputType.multiline,
textInputAction: TextInputAction.done,
onSubmitted: (value) {
},
maxLines: null,
// focusNode: focusNode,
controller: _message,
style: const TextStyle(color: Colors.white),
decoration: const InputDecoration(
border: InputBorder.none,
contentPadding:
EdgeInsets.symmetric(horizontal: 13, vertical: 13),
hintText: "Message(optional)",
hintStyle:
TextStyle(color: Colors.white24, fontSize: 14),
),
),
),
),
I want to make a top navigation bar with this effect, but it's very difficult to modify the default tab style of tabcontroller! Then I try to use container to modify it by myself. It's very simple, but the problem is that I can't support left and right swiping to switch pages. Because the gesture has been blocked by pageview. So in the end, I think it's better to use the tab provided by the system and then modify the style, some one help me!
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: TabBar(
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
],
),
),
),
);
The indicator property of TabBar can be used to achieve the look.
In your case, try this-
DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
bottom: Container(
color: Colors.grey[200],
width: 200,
child:TabBar(
labelColor: Colors.red,
unselectedLabelColor: Colors.grey,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: Colors.white),
tabs: [
Tab(icon: Icon(Icons.directions_car)),
Tab(icon: Icon(Icons.directions_transit)),
],
),
),
),
);
my code is here
DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: PreferredSize(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Color(0xfff0f4f7)),
width: 193,
height: 36,
child: Padding(
padding: const EdgeInsets.all(2.0),
child: TabBar(
labelColor: ThemeColor,
unselectedLabelColor: MainTextColor,
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(5),
color: Colors.white),
labelPadding: EdgeInsets.all(0),
indicatorSize: TabBarIndicatorSize.label,
tabs: [
Tab(
child: Padding(
padding: const EdgeInsets.all(2.0),
child: Container(
width: 95,
child: Text(
"transfer_upload_list".tr,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w600),
)),
)),
Tab(
child: Container(
width: 95,
child: Text(
"transfer_download_list".tr,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16, fontWeight: FontWeight.w600),
),
)),
]),
)),
preferredSize: Size(193, 36),
)),
));
I am trying to design the ui page and i successfully reduces the width of bottomnavigationbar buy using padding on left and right. But the problem is if i reduces the with of bottomnavigationbar then it is take space at each corner of navigationbar which is in second image (black arrow). Below i have added the code and two images,the first image is the image from adobe xd which i trying to achieve this and second image is after trying to reduce the width of bottomnavigationbar.
class _SettingsState extends State<Settings> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
color: Colors.yellow,
child: ListView(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
left: 8.0, right: 8.0, top: 65.0),
child: TextField(
decoration: new InputDecoration(
isDense: true,
hintText: "اسمك (اسم صفحتك)",
fillColor: Colors.black,
suffixIcon: Container(
margin: EdgeInsets.only(bottom: 23),
width: 0.1,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
child: Text('تعديل', style: TextStyle(color: Colors.white),),
),
),
keyboardType: TextInputType.text,
style: new TextStyle(color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(
left: 8.0, right: 8.0, top: 5.0),
child: TextField(
decoration: new InputDecoration(
isDense: true,
hintText: "التصنيف",
fillColor: Colors.black,
suffixIcon: Container(
margin: EdgeInsets.only(bottom: 23),
width: 0.1,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
child: Text('تعديل', style: TextStyle(color: Colors.white),),
),
),
keyboardType: TextInputType.text,
style: new TextStyle(color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(
left: 8.0, right: 8.0, top: 5.0),
child: TextField(
decoration: new InputDecoration(
isDense: true,
hintText: "حساب تويتر",
fillColor: Colors.black,
suffixIcon: Container(
margin: EdgeInsets.only(bottom: 23),
width: 0.1,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
child: Text('تعديل', style: TextStyle(color: Colors.white),),
),
),
keyboardType: TextInputType.number,
style: new TextStyle(color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(
left: 8.0, right: 8.0, top: 5.0),
child: TextField(
decoration: new InputDecoration(
hintText: "حساب انستقرام",
isDense: true,
fillColor: Colors.black,
suffixIcon: Container(
margin: EdgeInsets.only(bottom: 23),
width: 0.1,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
child: Text('تعديل', style: TextStyle(color: Colors.white),),
),
),
obscureText: true,
keyboardType: TextInputType.visiblePassword,
style: new TextStyle(color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(
left: 8.0, right: 8.0, top: 5.0),
child: TextField(
decoration: new InputDecoration(
hintText: "موقع الكتروني",
isDense: true,
fillColor: Colors.black,
suffixIcon: Container(
margin: EdgeInsets.only(bottom: 23),
width: 0.1,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
child: Text('تعديل', style: TextStyle(color: Colors.white),),
),
),
obscureText: true,
keyboardType: TextInputType.visiblePassword,
style: new TextStyle(color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(
left: 8.0, right: 8.0, top: 5.0),
child: TextField(
decoration: new InputDecoration(
hintText: "وصف",
isDense: true,
fillColor: Colors.black,
suffixIcon: Container(
margin: EdgeInsets.only(bottom: 23),
width: 0.1,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10),
),
child: Text('تعديل', style: TextStyle(color: Colors.white),),
),
),
obscureText: true,
keyboardType: TextInputType.visiblePassword,
style: new TextStyle(color: Colors.black),
),
),
Padding(
padding: const EdgeInsets.only(top: 25.0,left: 5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
Text(
'مشاركة صفحتي',
style: TextStyle(
color: Colors.redAccent, fontSize: 18.0,
decoration: TextDecoration.underline,),
),
],
),
),
Padding(
padding: const EdgeInsets.only(top: 30.0),
child: MaterialButton(
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(10.0),
),
minWidth: 280.0,
height: 47.0,
onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => Home1()));
},
textColor: Colors.white,
color: Colors.redAccent,
child: Text(
'تسجيل خروج ',
style: TextStyle(
fontWeight: FontWeight.bold, fontSize: 25.0),
),
),
),
],
),
),
bottomNavigationBar: Padding(
padding: const EdgeInsets.only(left: 50.0,right: 50.0),
child: ClipPath(
clipper: ShapeBorderClipper(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(40),
topLeft: Radius.circular(40)))),
child: BottomNavigationBar(
backgroundColor: Colors.grey[200],
currentIndex: 3,
type: BottomNavigationBarType.fixed,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.add,color: Colors.grey,size: 35.0,),
title: Text(''),
),
BottomNavigationBarItem(
icon: Icon(Icons.search,color: Colors.grey,size: 35.0,),
title: Text(''),
),
BottomNavigationBarItem(
icon: Icon(Icons.star_border,color: Colors.grey,size: 35.0,),
title: Text(''),
),
BottomNavigationBarItem(
icon: Icon(Icons.person_outline,color: Colors.redAccent,size: 35.0,),
title: Text(''),
),
],
),
),
),
);
}
The vertical unwanted space is because the Text() widget.
Please try changing this, inside each BottomNavigationBarItem
Replace your --> title: Text('')
With this --> title: Container()
To reduce or increase the left and right space in the bottomNavigationBar, change the values of Padding() like
Padding(padding: const EdgeInsets.only(left: 10.0,right: 10.0),
I have a tab bar and i need to put a vertical line as a divider between tabs, how to do that?
this how i used my tabbar:
new TabBar(
unselectedLabelColor: Color.fromRGBO(119, 119, 119, 1),
labelColor: Colors.black,
controller: controller,
tabs: <Tab>[
new Tab(text: "Girls"),
new Tab(text: "Hero"),
new Tab(text: "Open"),
]),
and I need it to be like this:
Finally It worked for me
TabBar(
tabs: [
_individualTab('assets/icons/bottom_nav/Home.png'),
_individualTab('assets/icons/bottom_nav/Guys.png'),
_individualTab('assets/icons/bottom_nav/Notes.png'),
Tab(
icon: ImageIcon(
AssetImage('assets/icons/bottom_nav/Email.png')
),
),
],
labelColor: STColors.PRIMARY_COLOR,
unselectedLabelColor: Colors.grey,
indicatorColor: Colors.white,
indicatorSize: TabBarIndicatorSize.tab,
labelPadding: EdgeInsets.all(0),
indicatorPadding: EdgeInsets.all(0),
),
Individual Tab Function
Widget _individualTab(String imagePath) {
return Container(
height: 50 + MediaQuery
.of(context)
.padding
.bottom,
padding: EdgeInsets.all(0),
width: double.infinity,
decoration: BoxDecoration(border: Border(right: BorderSide(color: STColors.LIGHT_BORDER, width: 1, style: BorderStyle.solid))),
child: Tab(
icon: ImageIcon(AssetImage(imagePath)),
),
);
}
To achieve small size separator you can use this.
Widget _individualTab(String imagePath) {
return Container(
height: 50,
width: double.infinity,
decoration: BoxDecoration(
border: Border(right: BorderSide(color: STColors.LIGHT_BORDER,
width: 0,
style: BorderStyle.solid),
),
),
child: Stack(children: <Widget>[
Center(
child: Tab(
icon: ImageIcon(AssetImage(imagePath)),
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
color: STColors.appBlackMedium,
width: 1,
height: 25,
),
)
],)
);
}
All you need is
indicator: BoxDecoration(
border: Border(
left: BorderSide(color: Colors.grey), // provides to left side
right: BorderSide(color: Colors.grey), // for right side
),
),
Your solution:
new TabBar(
indicator: BoxDecoration(border: Border(right: BorderSide(color: Colors.orange))),
unselectedLabelColor: Color.fromRGBO(119, 119, 119, 1),
labelColor: Colors.black,
controller: controller,
tabs: <Tab>[
new Tab(text: "Girls"),
new Tab(text: "Hero"),
new Tab(text: "Open"),
]),
Here is the Header I want to achieve
Yea, so I added a var called rightDivider which lets you render divider but the last tab on my custom tab widget.
import 'package:flutter/material.dart';
class TabWidget extends StatelessWidget {
final String label;
final bool rightDivider;
TabWidget({
required this.label,
required this.rightDivider,
});
#override
Widget build(BuildContext context) {
return Container(
height: 32 + MediaQuery.of(context).padding.bottom,
width: double.infinity,
padding: EdgeInsets.all(0),
decoration: (rightDivider)
? BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.grey,
width: 1,
style: BorderStyle.solid,
),
),
)
: null,
child: Center(child: Text(label)),
);
}
}
And called this widget like this
TabBar(
controller: _tabController,
tabs: [
TabWidget(
label: 'Today',
rightDivider: true,
),
TabWidget(
label: 'Calendar',
rightDivider: true,
),
TabWidget(
label: 'Report',
rightDivider: false,
),
],
)
That's how I achieve this behavior...
HomeTab({required String title, bool isSeprator = true}) {
return Tab(
child: Container(
width: 100,
height: 20,
child: Center(
child: Text(title),
),
decoration: isSeprator
? BoxDecoration(
border: Border(
left: BorderSide(
color: Colors.grey,
width: 1,
style: BorderStyle.solid,
),
),
)
: null,
),
);
}
isSeparator is to show separator or not ... because on the last index I am not showing...
Following is the list of tabs ...
List<Widget> _tabScroll() => [
HomeTab(title: "Tab1"),
HomeTab(title: "Tab2"),
HomeTab(title: "Tab3", isSeparator: false),
];
and following is the most important TabBar Code...
TabBar(
labelPadding: EdgeInsets.symmetric(horizontal: 0), //removing extra space
controller: _controller,
isScrollable: true,
indicatorColor: Colors.black,
indicatorSize: TabBarIndicatorSize.label,
indicator: UnderlineTabIndicator(
borderSide: BorderSide(width: 3.0), //hight of indicator
insets: EdgeInsets.symmetric(horizontal: 30.0), //give some padding to reduce the size of indicator
),
unselectedLabelColor: Colors.grey,
tabs: _tabScroll(), //list of tabs
),
The end result looks like this...
Working solution is to create border for individual tabs. Tabs parameter actually accept other elements as a child. So you can use custom containers. That way you can control which side border you want to show (left, rigth or any side):
TabBar(
controller: _tabController,
indicator: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.red,
offset: Offset(0, 2.0),
)
],
color: Colors.white,
),
labelColor: Colors.red,
unselectedLabelColor: Colors.grey.shade900,
labelPadding: EdgeInsets.symmetric(horizontal: 1.0),
isScrollable: false,
tabs: [
Container(
child: Center(
child: Text('T1'),
),
decoration: BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.grey,
width: 2,
style: BorderStyle.solid,
),
),
)),
Container(
child: Center(
child: Text('T2'),
),
decoration: BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.grey,
width: 2,
style: BorderStyle.solid,
),
),
)),
Container(
child: Center(
child: Text('T3'),
),
decoration: BoxDecoration(
border: Border(
right: BorderSide(
color: Colors.grey,
width: 2,
style: BorderStyle.solid,
),
),
)),
Tab(
text: 'T4',
),
],
),
Thats how i have done this
I am using screenutils package from pub you can also use it
SizedBox(
width: 342.w,
height: 41.h,
child: Material(
color: const Color(0xffE2E2E2),
borderRadius: BorderRadius.circular(5),
child: Padding(
padding: EdgeInsets.all(2),
child: TabBar(
padding: EdgeInsets.zero,
indicatorPadding: EdgeInsets.zero,
labelPadding: EdgeInsets.zero,
indicator: BoxDecoration(
color: Color(0xffFFFFFF),
// borderRadius: BorderRadius.circular(5.0)
),
labelColor: Colors.black,
unselectedLabelColor: Color(0xff999BA2),
tabs: [
Container(
width: 1.sw,
decoration: BoxDecoration(
// color: Colors.black,
border: Border(right: BorderSide(color: Colors.white))
),
child: Tab(
text: 'Call',
),
),
Container(
width: 1.sw,
decoration: BoxDecoration(
border: Border(right: BorderSide(color: Colors.white))
),
child: Tab(
text: 'Missed Call',
),
// child: Tab(text: 'Phone',),
),
Container(
child: Tab(
text: 'No Call',
),
// child: Tab(text: 'No Call'),
),
],
),
),
),
)
enter image description here