Currently I am trying to implement a tab controller instead of the list view that I am using in the CategorySelector() function. However, I would like to maintain the same design. How can I move the default text title to the location where the arrow is pointing. and for it to be responsive based on the tab selected.
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Color(0xffDCE3E5),
appBar: AppBar(
title: Text('DISCOVER', style:
TextStyle(color: kOnyx,
fontFamily: 'Baukasten'),),
backgroundColor: kSnow,
leading: IconButton(
icon: Icon(Icons.menu),
iconSize: 30.0,
color: kOnyx,
onPressed: () {},
),
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
icon: Icon(
Icons.person,
color: kOnyx,
size: 30.0,
),
label: Text('Log Out'),
onPressed: () {
_auth.signOut();
Navigator.push(context, MaterialPageRoute(builder: (context) => Authentication()));
},
),
],
),
body: Column(
children: <Widget>[
Container(
color: kSnow,
padding: EdgeInsets.only(left: 15.0, top: 15.0),
child: FractionallySizedBox(
widthFactor: 1.0,
child: Text(
'DISCOVER',
style: TextStyle(
color: kOnyx,
fontSize: 30.0,
//fontWeight: FontWeight.w600,
fontFamily: 'Baukasten'),
),
),
),
CategorySelector(),
],
),
);
}
}
use tabbarView
for example :)
class _MainPage extends State<MainPage> with SingleTickerProviderStateMixin {
TabController controller;
#override
void initState() {
super.initState();
controller = TabController(length: 3, vsync: this);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('App bar'),
),
body: TabBarView(
children: <Widget>[FirstPage(), SecondPage() , ThirdPage()],
controller: controller,
),
bottomNavigationBar: TabBar(tabs: <Tab>[
Tab(icon: Icon(Icons.looks_one),) ,
Tab(icon: Icon(Icons.looks_two),) ,
Tab(icon: Icon(Icons.looks_3),) , ] ,
controller: controller,),
);
}
#override
void dispose() {
controller.dispose();
super.dispose();
}
}
Related
I was trying the navigator.push but it didn't work. The code executed without errors but my emulator won't navigate when I push the button. I tried all the three methods, the direct navigation with materialrootpage, static navigation with route map, Dynamic Navigation with onGeneratedRoute
import 'package:flutter/material.dart';
import 'submit_id.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text('Bits mess'
,style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
letterSpacing: 5
),),
backgroundColor: Colors.black,
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
child: Image(
image: NetworkImage('https://www.google.com/maps/uv?pb=!1s0x3bbfb9a68009cf11%3A0x312ca93e696b7ee0!3m1!7e115!4shttps%3A%2F%2Flh5.googleusercontent.com%2Fp%2FAF1QipNjLLtffoDS_xSU6ZBOflCueMzOhW_10s6udnm0%3Dw162-h108-n-k-no!5smess%20food%20-%20Google%20Search!15sCgIgAQ&imagekey=!1e10!2sAF1QipNjLLtffoDS_xSU6ZBOflCueMzOhW_10s6udnm0&hl=en&sa=X&ved=2ahUKEwiuw4HCwsn6AhWc9DgGHWgYCJoQ7ZgBKAF6BAgSEAM#',
scale:0.6 ),
)
),
SizedBox(height: 140,width: 12),
Container(
//margin: EdgeInsets.symmetric(vertical: 60,horizontal: 150),
//padding: EdgeInsets.symmetric(horizontal: 0.5,vertical: 0.5),
child: SizedBox
(width: 300,
height: 70,
in this widget I used the navigator widget
child: ElevatedButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Submitid())
);
},
child: Text('Submit ID')),
Ignore from here if you want to
)),
SizedBox(height: 70,width: 10),
Container(
//margin: EdgeInsets.symmetric(vertical: 60,horizontal: 150),
//padding: EdgeInsets.symmetric(horizontal: 0.5,vertical: 0.5),
child: SizedBox(
width: 300,
height: 70,
child: ElevatedButton(onPressed: () {},
child: Text('Get ID'),
style: ElevatedButton.styleFrom(backgroundColor: Colors.orange),
)),
),
SizedBox(height: 50,width: 10),
]
),
)
)
);
}
}
The screen I want to navigate to
import 'package:flutter/material.dart';
class Submitid extends StatefulWidget {
const Submitid({Key? key}) : super(key: key);
#override
State<Submitid> createState() => _SubmitidState();
}
class _SubmitidState extends State<Submitid> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text('Bits mess'
,style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
letterSpacing: 5
),),
backgroundColor: Colors.black,
centerTitle: true,
),
),
);
}
}
You need to wrap your Scaffold widget in MaterialApp to reach different context. You can extract your Scaffold into a class:
class Home extends StatelessWidget{
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text('Bits mess',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
letterSpacing: 5
)),
backgroundColor: Colors.black,
centerTitle: true,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
child: Image(
image: NetworkImage('https://www.google.com/maps/uv?pb=!1s0x3bbfb9a68009cf11%3A0x312ca93e696b7ee0!3m1!7e115!4shttps%3A%2F%2Flh5.googleusercontent.com%2Fp%2FAF1QipNjLLtffoDS_xSU6ZBOflCueMzOhW_10s6udnm0%3Dw162-h108-n-k-no!5smess%20food%20-%20Google%20Search!15sCgIgAQ&imagekey=!1e10!2sAF1QipNjLLtffoDS_xSU6ZBOflCueMzOhW_10s6udnm0&hl=en&sa=X&ved=2ahUKEwiuw4HCwsn6AhWc9DgGHWgYCJoQ7ZgBKAF6BAgSEAM#',
scale:0.6 ),
)
),
SizedBox(height: 140,width: 12),
Container(
//margin: EdgeInsets.symmetric(vertical: 60,horizontal: 150),
//padding: EdgeInsets.symmetric(horizontal: 0.5,vertical: 0.5),
child: SizedBox
(width: 300,
height: 70,
child: ElevatedButton(
onPressed: () =>
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => Submitid()))
,
child: Text('Submit ID')),
)),
SizedBox(height: 70,width: 10),
Container(
//margin: EdgeInsets.symmetric(vertical: 60,horizontal: 150),
//padding: EdgeInsets.symmetric(horizontal: 0.5,vertical: 0.5),
child: SizedBox(
width: 300,
height: 70,
child: ElevatedButton(onPressed: () {},
child: Text('Get ID'),
style: ElevatedButton.styleFrom(),
)),
),
SizedBox(height: 50,width: 10),
]
),
)
);
}
}
And call this widget in your MaterialApp:
MaterialApp(
home: Home(),
debugShowCheckedModeBanner: false,
)
The space between tab bar view and bottom navigation bar is the extra space that I want to remove.
in the image, you can see the space that shouldn't be there
class Tab_Bar2 extends StatefulWidget {
const Tab_Bar2({Key? key}) : super(key: key);
#override
_Tab_Bar2State createState() => _Tab_Bar2State();
}
class _Tab_Bar2State extends State<Tab_Bar2> with SingleTickerProviderStateMixin {
final bodyGlobalKey = GlobalKey();
final List<Widget> myTabs = [
Text(..),
Text(..),
Text(..),
Text(..),
Text(..),
Text(..),
];
late TabController _tabController;
late ScrollController _scrollController;
#override
void initState() {
_scrollController = ScrollController();
_tabController = TabController(length: 6, vsync: this);
super.initState();
}
#override
void dispose() {
_tabController.dispose();
_scrollController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Dashboard"),
centerTitle: true,
backgroundColor: const Color(0xffFFC36A),
actions: [
IconButton(
onPressed: () {},
icon: const Icon(Icons.notifications),
),
]),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
const DrawerHeader(
decoration: BoxDecoration(
color: Color(0xffFFC36A),
),
child: Padding(
padding: EdgeInsets.only(top: 20.0, left: 60),
child: Text(
'Drawer',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 20),
),
),
),
ListTile(
title: const Text('Log Out'),
onTap: () {
},
),
ListTile(
title: const Text('Item 2'),
onTap: () {
Navigator.pop(context);
},
),
],
),
),
body: NestedScrollView(
controller: _scrollController,
headerSliverBuilder: (BuildContext context, value) {
return [
SliverToBoxAdapter(child: Column(
children: [img1(), grid(), rsp(), LiveChart()],
),),
SliverToBoxAdapter(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
margin: EdgeInsets.symmetric(horizontal: 15,vertical: 15),
child: Text('Latest',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
fontFamily: 'railway',
color: Theme_Data.font_color,
),
),
),
Container(
margin: EdgeInsets.symmetric(horizontal: 3.5),
padding: EdgeInsets.symmetric(horizontal: 2.5,vertical: 2.5),
height: 35,
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade200),
borderRadius: BorderRadius.all(
Radius.circular(25),
),
),
child: TabBar(
controller: _tabController,
labelPadding: EdgeInsets.symmetric(horizontal: 2.0, vertical: 5),
indicator: BoxDecoration(
borderRadius: BorderRadius.circular(50), // Creates border
color: Theme_Data.th_light_color),
tabs: myTabs,
),
),
],
),
),
];
},
body: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Theme(
data: Theme.of(context).copyWith(
dividerColor: Colors.white
),
child: TabBarView(
controller: _tabController,
children: <Widget>[
SalesTable(),
QuotationsTable(),
PurchasesTable(),
TransfersTable(),
ConsumersTable(),
SuppliersTable(),
],
),
),
),
),
);
}
}
in above code i think there might be the issues between the usage of SviverToBoxAdapter what widget should i use instead to achieve the required design
I want to change background color of the tabs when it tapped ?
How can I change the color
I have this test project :
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
backgroundColor: Colors.pink,
bottom: TabBar(
labelColor: Colors.yellow,
indicatorColor: Colors.yellow,
onTap: (index) {
// Should not used it as it only called when tab options are clicked,
// not when user swapped
},
controller: _controller,
tabs: list,
),
title: Text('Tabs Demo'),
),
body: TabBarView(
controller: _controller,
children: List<Widget>.generate(3, (int index){
return Center(
child: Text(index.toString()),
);
}),
),
),
);
You can use the index property of the controller to check which tab is currently active and listen to the controller to know when it changed.
For instance by using an AnimatedBuilder around the Tab widget
These things to consider:
Use tab controller and check indexIsChanging
Wrap text inside Tab with a widget for the color change
Remove labelPadding
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage>
with SingleTickerProviderStateMixin {
TabController tabController;
List<Color> tabBackground;
List colors = [Colors.red, Colors.green, Colors.yellow];
Random random = Random();
#override
void initState() {
super.initState();
tabController = TabController(length: 3, vsync: this);
tabBackground = [Colors.blue, Colors.pink, Colors.cyan];
tabController.addListener(() {
if (tabController.indexIsChanging) {
setState(() {
tabBackground[tabController.index] = colors[random.nextInt(3)];
});
}
});
}
#override
void dispose() {
tabController.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.pink,
bottom: TabBar(
labelPadding: EdgeInsets.zero,
labelColor: Colors.yellow,
indicatorColor: Colors.black,
controller: tabController,
tabs: [
Tab(
child: Container(
alignment: Alignment.center,
constraints: BoxConstraints.expand(),
color: tabBackground[0],
child: Text(
'Tab 1',
style: TextStyle(
color: Colors.white,
),
),
),
),
Tab(
child: Container(
alignment: Alignment.center,
constraints: BoxConstraints.expand(),
color: tabBackground[1],
child: Text(
'Tab 2',
style: TextStyle(
color: Colors.white,
),
),
),
),
Tab(
child: Container(
alignment: Alignment.center,
constraints: BoxConstraints.expand(),
color: tabBackground[2],
child: Text(
'Tab 3',
style: TextStyle(
color: Colors.white,
),
),
),
),
],
),
title: Text('Tabs Demo'),
),
body: TabBarView(
controller: tabController,
children: List<Widget>.generate(3, (int index) {
return Center(
child: Text(index.toString()),
);
}),
),
);
}
}
When ever I run the following code, I receive the error: A RenderFlex overflowed by 99523 pixels on the bottom.. I have tried various fixes to error like putting expanded widgets as children of the TabView and other combinations but none seems to work. I am trying to achieve the picture below. I have seen various solutions where the TabView widget is wrapped in an expanded widget but nothing is working.
below is my current code.
class Discover extends StatefulWidget {
#override
_DiscoverState createState() => _DiscoverState();
}
class _DiscoverState extends State<Discover> {
final _auth = FirebaseAuth.instance;
String request;
FirebaseUser loggedInUser;
#override
void initState() {
// TODO: implement initState
super.initState();
getCurrentUser();
}
void getCurrentUser () async {
try{
final user = await _auth.currentUser();
if (user != null){
loggedInUser = user;
print(loggedInUser.email);
}
} catch (e){
print(e);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kSnow,//Color(0xffDCE3E5),
appBar: AppBar(
backgroundColor: kSnow,
leading: IconButton(
icon: Icon(Icons.menu),
iconSize: 30.0,
color: kOnyx,
onPressed: () {},
),
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
icon: Icon(
Icons.person,
color: kOnyx,
size: 30.0,
),
label: Text('Log Out'),
onPressed: () {
_auth.signOut();
Navigator.push(context, MaterialPageRoute(builder: (context) => Authentication()));
},
),
],
),
body: Column(
children: <Widget>[
Container(
color: kSnow,
padding: EdgeInsets.only(left: 15.0, top: 15.0, bottom: 30.0),
child: FractionallySizedBox(
widthFactor: 1.0,
child: Text(
'DISCOVER',
style: TextStyle(
color: kOnyx,
fontSize: 30.0,
//fontWeight: FontWeight.w600,
fontFamily: 'Baukasten'),
),
),
),
DefaultTabController(
length: 4,
child: Column(
children: <Widget>[
TabBar(
isScrollable: true,
labelColor: kOnyx,
unselectedLabelColor: kFossil,
indicatorSize: TabBarIndicatorSize.label,
indicator: BoxDecoration(
color: kSnow),
tabs: [Tab(text: 'HOME'), Tab(text: 'CREATE'), Tab(text: 'PROFILE'), Tab(text: 'SETTINGS')],
indicatorColor: kOnyx,
labelStyle: TextStyle(
//ntSize: 10.0,
fontFamily: 'Baukasten'
),
),
TabBarView(
children: <Widget>[
Text('hello'),
Text('hello'),
Text('hello'),
Text('hello')
],
)
],
),
),
//Container(height: 45, color: kOnyx,),
],
),
);
}
}
current ouput:
The widget causing the overflow was the nested Column which was given an unbounded height, I added a demo code using yur widget tree as an example.
Check below:
class Discover extends StatefulWidget {
#override
_DiscoverState createState() => _DiscoverState();
}
class _DiscoverState extends State<Discover> with SingleTickerProviderStateMixin {
final _auth = FirebaseAuth.instance;
String request;
FirebaseUser loggedInUser;
// create a tab controller
TabController _tabController;
#override
void initState() {
// create a tab controller
_tabController = TabController(length: 4, vsync: this);
// TODO: implement initState
super.initState();
getCurrentUser();
}
void getCurrentUser () async {
try{
final user = await _auth.currentUser();
if (user != null){
loggedInUser = user;
print(loggedInUser.email);
}
} catch (e){
print(e);
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: kSnow,//Color(0xffDCE3E5),
appBar: AppBar(
backgroundColor: kSnow,
leading: IconButton(
icon: Icon(Icons.menu),
iconSize: 30.0,
color: kOnyx,
onPressed: () {},
),
elevation: 0.0,
actions: <Widget>[
FlatButton.icon(
icon: Icon(
Icons.person,
color: kOnyx,
size: 30.0,
),
label: Text('Log Out'),
onPressed: () {
_auth.signOut();
Navigator.push(context, MaterialPageRoute(builder: (context) => Authentication()));
},
),
],
),
body: Column(
children: <Widget>[
Container(
color: kSnow,
padding: EdgeInsets.only(left: 15.0, top: 15.0, bottom: 30.0),
child: FractionallySizedBox(
widthFactor: 1.0,
child: Text(
'DISCOVER',
style: TextStyle(
color: kOnyx,
fontSize: 30.0,
//fontWeight: FontWeight.w600,
fontFamily: 'Baukasten'),
),
),
),
DefaultTabController(
length: 4,
child: TabBar(
controller: _tabController,
isScrollable: true,
labelColor: kOnyx,
unselectedLabelColor: kFossil,
indicatorSize: TabBarIndicatorSize.label,
indicator: BoxDecoration(color: kSnow),
tabs: [
Tab(text: 'HOME'),
Tab(text: 'CREATE'),
Tab(text: 'PROFILE'),
Tab(text: 'SETTINGS')
],
indicatorColor: kOnyx,
labelStyle: TextStyle(
//ntSize: 10.0,
fontFamily: 'Baukasten'),
),
),
Expanded(
child: TabBarView(
controller: _tabController,
children: <Widget>[
Text('hello'),
Text('hello'),
Text('hello'),
Text('hello')
],
),
),
//Container(height: 45, color: kOnyx,),
],
),
);
}
}
OUTPUT:
Note, I used different colors as I could not get your exact colors:
Is possible to position an hyperlink created with url_launcher on the appbar? Here a screen of what i mean https://ibb.co/X28TzNN "Sito Web" is the hyperlink i want to change position, need move it in the red cirle. Here my AppBar
class BackgroundImage extends StatelessWidget{
final Widget body;
BackgroundImage({this.body});
#override
Widget build(BuildContext context){
return Scaffold(
appBar: AppBar(
elevation: 0,
title: Text('Blumax', style: TextStyle(
fontWeight: FontWeight.w500,
fontFamily: 'DancingScript',
fontSize: 40
),),
centerTitle: false,
),
body: Stack(
children: <Widget>[Container(
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage("assets/whiteimage.jpg"), fit: BoxFit.cover),
),
),
body
]
)
);
}
}
And that's is what i did for position the text in the top right
Widget build(BuildContext context) {
return InkWell(
child: Container(
alignment: Alignment(0.9, -1.0),
child: Text(
_text,
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'RobotoMono',
fontSize: 20,
color: Colors.white,
decoration: TextDecoration.underline),
)),
onTap: _launchURL,
);
}
}
#andrea, you don't need to use InkWell/Container. You can use actions in appBar with simple button and try something like this,
class MyAppState extends State<MyApp> {
String _text = 'Link';
String _url = 'https://www.test.com';
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Test'),
actions: <Widget>[
FlatButton(
child: Text(_text, style: TextStyle(fontSize: 18.0, color: Colors.white)),
onPressed: _launchURL,
),
IconButton(icon: Icon(Icons.more_vert, color: Colors.white), onPressed: (){})
]
),
body: Padding(
padding: EdgeInsets.all(20.0),
child: Center(
child: Text('')
)
)
)
);
}
_launchURL() async {
if (await canLaunch(_url)) {
await launch(_url);
} else {
throw 'Could not launch $_url';
}
}
}
try actions in AppBar, You can have FlatButton or Inkwell or any Widget that gives you a touch event inside.
appBar: AppBar(
title: Text(Lang.treeView),
actions: <Widget>[
InkWell(
child: Container(
alignment: Alignment(0.9, -1.0),
child: Text(
"ABC",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'RobotoMono',
fontSize: 20,
color: Colors.white,
decoration: TextDecoration.underline),
))),
],
)