Flutter: animate appbar color with bottomnavigationbar - flutter

I wonna animate my appbar color the same way as the bottomnavigationbar does with the shifting type. So the appbar and bottomnavigationbar change color together.
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _tabIndex = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Dash')),
body: Container(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _tabIndex,
onTap: (value) => setState(() => _tabIndex = value),
type: BottomNavigationBarType.shifting,
unselectedItemColor: Theme.of(context).unselectedWidgetColor,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.dashboard), title: Text('Dash'), backgroundColor: Colors.blue),
BottomNavigationBarItem(
icon: Icon(Icons.insert_chart), title: Text('Data'), backgroundColor: Colors.red),
BottomNavigationBarItem(
icon: Icon(Icons.monetization_on), title: Text('Income'), backgroundColor: Colors.orange),
]),
);
}
}
How can I do this? (I'm fairly new to flutter) Thanks!

It's very simple. Simply change color based on the selected index.
Here you go
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _tabIndex = 0;
var colors = [Colors.blue, Colors.red, Colors.orange];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Dash'),
backgroundColor: colors[_tabIndex],
),
body: Container(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _tabIndex,
onTap: (value) => setState(() => _tabIndex = value),
type: BottomNavigationBarType.shifting,
unselectedItemColor: Theme.of(context).unselectedWidgetColor,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.dashboard),
title: Text('Dash'),
backgroundColor: colors[0]),
BottomNavigationBarItem(
icon: Icon(Icons.insert_chart),
title: Text('Data'),
backgroundColor: colors[1]),
BottomNavigationBarItem(
icon: Icon(Icons.monetization_on),
title: Text('Income'),
backgroundColor: colors[2]),
]),
);
}
}
See the live demo here.

Related

Flutter: assertion: line 4269 pos 14 : 'owner!._debugCurrentBuildTarget == this': is not true

I'm making an "inventory" app, to keep track of objects food etc in my house. I wanted to use a navigator, to make multiple pages, without "modifying" the widgets in the scaffold.
This is my code: (i have as you can see multiple file, ask me if you need something else)
Just to be clear, the utils.dart is an export file that I use to import every thing else
import 'package:flutter/material.dart';
import 'package:storage_system/utils.dart';
import 'package:flutter_barcode_scanner/flutter_barcode_scanner.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Storage System',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.yellow,
),
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({Key? key}) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _index = 0;
void _onTap(int i) {
setState(() {
_index = i;
});
}
Future<void> getBarcodeData() async {
String resultData = await FlutterBarcodeScanner.scanBarcode(
"0xFFFFFF", "Close", false, ScanMode.BARCODE);
print(resultData);
}
Widget selectPage(int i) {
switch (i) {
case 0:
return MainPage();
case 1:
return SettingsPage();
default:
return Container();
}
}
#override
Widget build(BuildContext context) => Navigator(
onGenerateRoute: (settings) => MaterialPageRoute(
builder: (context) => Container(
child: Scaffold(
floatingActionButtonLocation:
FloatingActionButtonLocation.centerDocked,
floatingActionButton: FloatingActionButton(
onPressed: getBarcodeData,
child: Icon(Icons.add),
),
appBar: AppBar(
actions: <Widget>[],
title: Text(
"Storage System",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 28),
),
),
bottomNavigationBar: BottomNavigationBar(
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home), label: "Home"),
BottomNavigationBarItem(
icon: Icon(Icons.settings), label: "Setings")
],
currentIndex: _index,
onTap: _onTap,
elevation: 15,
),
body: Container(
child: selectPage(_index),
),
),
)),
);
}

How to use bottomNavigationBar in a separate file?

I have the following code that is working properly:
import 'package:flutter/material.dart';
import 'screen_curiosities.dart';
import 'screen_movies.dart';
import 'screen_releases.dart';
import '../utils/side_menu.dart';
import '../utils/bottom_menu.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int selectedIndex = 0;
List screens = [
ScreenMovies(),
ScreenReleases(),
ScreenCuriosities()
];
void onClicked(int index) {
setState(() {
selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Movies'),
backgroundColor: Colors.black,
),
body: Center(
child: screens.elementAt(selectedIndex),
),
drawer: SideMenu(),
bottomNavigationBar: BottomNavigationBar(
items:[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Movies',
),
BottomNavigationBarItem(
icon: Icon(Icons.new_releases),
label: 'Releases',
),
BottomNavigationBarItem(
icon: Icon(Icons.question_answer),
label: 'Curiosities',
)
],
currentIndex: selectedIndex,
onTap: onClicked,
selectedItemColor: Colors.red[800],
backgroundColor: Colors.black,
unselectedItemColor: Colors.white,
)
);
}
}
Now I am trying to separate the Widget BottomNavigationBar to another file and call him on the property "bottomNavigationBar" from Scaffold. It would be like this:
bottomNavigationBar: BottomMenu()
I did it with the Widget Drawer and it worked, but when I tried the same thing with bottomNavigationBar it wasn't successful.
When I try to use the variable selectedIndex in the new Widget it is always undefined.
I tried many things, but I couldn't solve this. Is there any way to use the Widget bottomNavigationBar in a separated file?
EDIT
Below, follow the 2 files that I need to make this link from the menu to the page in order to make them work together:
file home.dart
import 'package:flutter/material.dart';
import 'screen_curiosities.dart';
import 'screen_movies.dart';
import 'screen_releases.dart';
import '../utils/side_menu.dart';
import '../utils/bottom_menu.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int selectedIndex = 0;
List screens = [
ScreenMovies(),
ScreenReleases(),
ScreenCuriosities()
];
void onClicked(int index) {
setState(() {
selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Movies'),
backgroundColor: Colors.black,
),
body: Center(
child: screens.elementAt(selectedIndex),
),
drawer: SideMenu(),
bottomNavigationBar: BottomMenu() // Using the Widget here
}
}
file bottom_menu.dart
import 'package:flutter/material.dart';
class BottomMenu extends StatelessWidget {
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
items:[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Movies',
),
BottomNavigationBarItem(
icon: Icon(Icons.new_releases),
label: 'Releases',
),
BottomNavigationBarItem(
icon: Icon(Icons.question_answer),
label: 'Curiosities',
)
],
currentIndex: selectedIndex, // the variable is undefined
onTap: onClicked, // the function is undefined
selectedItemColor: Colors.red[800],
backgroundColor: Colors.black,
unselectedItemColor: Colors.white,
);
}
}
You can copy paste run two full code below
You can pass selectedIndex and onClicked to BottomMenu
code snippet
bottomNavigationBar: BottomMenu(
selectedIndex: selectedIndex,
onClicked: onClicked,
));
...
class BottomMenu extends StatelessWidget {
final selectedIndex;
ValueChanged<int> onClicked;
BottomMenu({this.selectedIndex, this.onClicked});
working demo
full code main.dart
import 'package:flutter/material.dart';
import 'bottom.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int selectedIndex = 0;
List screens = [ScreenMovies(), ScreenReleases(), ScreenCuriosities()];
void onClicked(int index) {
setState(() {
selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Movies'),
backgroundColor: Colors.black,
),
body: Center(
child: screens.elementAt(selectedIndex),
),
//drawer: SideMenu(),
bottomNavigationBar: BottomMenu(
selectedIndex: selectedIndex,
onClicked: onClicked,
));
}
}
class ScreenMovies extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: Text("ScreenMovies"),
);
}
}
class ScreenReleases extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: Text("ScreenReleases"),
);
}
}
class ScreenCuriosities extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Center(
child: Text("ScreenCuriosities"),
);
}
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Home(),
);
}
}
full code bottom.dart
import 'package:flutter/material.dart';
class BottomMenu extends StatelessWidget {
final selectedIndex;
ValueChanged<int> onClicked;
BottomMenu({this.selectedIndex, this.onClicked});
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Movies',
),
BottomNavigationBarItem(
icon: Icon(Icons.new_releases),
label: 'Releases',
),
BottomNavigationBarItem(
icon: Icon(Icons.question_answer),
label: 'Curiosities',
)
],
currentIndex: selectedIndex,
onTap: onClicked,
selectedItemColor: Colors.red[800],
backgroundColor: Colors.black,
unselectedItemColor: Colors.white,
);
}
}

How to change AppBar Title (between Image asset and Text) in flutter?

I want to set Title appbar with image assets in HomePage, and with text in ListPage. and I have try with this code
import 'package:flutter/material.dart';
import 'package:teld/page/homepage/homePage.dart';
import 'package:teld/page/listpage/listPage.dart';
import 'package:teld/page/settingPage.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(fontFamily: 'Roboto'),
home: NavStructure(),
);
}
}
class NavStructure extends StatefulWidget {
#override
_NavStructureState createState() => _NavStructureState();
}
class _NavStructureState extends State<NavStructure>{
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
int _currentIndex = 0;
var _title;
final _page = [
HomePage(),
ListPage(),
SettingPage(),
];
void onTapBar(int index) {
setState(() {
_currentIndex = index;
switch(index){
case 0:{
_title = Image.asset('assets/TDLogoNB.png', height: 38.0,);
}break;
case 1:{
_title = Text("List Page");
}break;
case 2:{
_title = Text("Setting Page");
}break;
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
elevation: 0,
centerTitle: true,
backgroundColor: Colors.white,
title: _title //this
),
body: _page[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
onTap: onTapBar,
currentIndex: _currentIndex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text('Home'),
),
BottomNavigationBarItem(
icon: Icon(Icons.list_view),
title: Text('List Page'),
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
title: Text('Setting Page'),
),
],
),
);
}
}
what I'm trying to do is
appbar title with image asset in HomePage
appbar title with text in ListPage/other page
from my code.
appbar title (as Text) in ListPage did not appear at all.
"Image asset" in HomePage didn't appear either, until the time I opened it for the second time, the "image asset" just appeared
how to solve this?
Maybe you can try this
AppBar(
title: 0 == _currentIndex ? Image.asset("/assets/....") : Text("..."),
// ....
),
In this case _title will not be necessary and you can omit it

How do I set a default tab in BottomNavigation bar in Flutter?

I have 5 tabs currently, how do I set the a default tab when launching the app? lets say I want the account tab to be the default tab when opening the app.
How to I do that? Btw, Im using WebView plugin to display a site's content.
Below is the code of my main.dart file. Ive tried searching and all but the solutions I found wont work for me (I think im searching the wrong words. Also, I am new to flutter) Thank you very much!
import 'package:syncshop/widgets/cart_page.dart';
import 'package:syncshop/widgets/categories_page.dart';
import 'package:syncshop/widgets/home_page.dart';
import 'package:syncshop/widgets/profile_account.dart';
import 'package:syncshop/widgets/search_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
int _selectedPage = 0;
final _pageOptions = [
HomeScreen(),
CategoriesPage(),
SearchPage(),
CartPage(),
ProfileAccount(),
];
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Sync Shop',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: _pageOptions[_selectedPage],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _selectedPage,
onTap: (int index) {
setState((){
_selectedPage = index;
});
},
items: [
BottomNavigationBarItem(icon: Icon(Icons.home), title: Text("Home"),
),
BottomNavigationBarItem(icon: Icon(Icons.category), title: Text("Categories"),
),
BottomNavigationBarItem(icon: Icon(Icons.search), title: Text("Search"),
),
BottomNavigationBarItem(icon: Icon(Icons.shopping_cart), title: Text("Cart"),
),
BottomNavigationBarItem(icon: Icon(Icons.account_circle), title: Text("Profile"),
),
],
),
),
);
}
}
You can override initState function of State and can put some initial codes there.
So for your example, can do this.
...
class MyAppState extends State<MyApp> {
int _selectedPage = 0;
#override
void initState() {
super.initState();
_selectedPage = 4;
}
...
When you creating BottomNavigationBar set this.currentindex to index that you want
bottomNavigationBar: BottomNavigationBar(
currentindex=1,//This line, it's default 0
type: BottomNavigationBarType.fixed,
currentIndex: _selectedPage,
onTap: (int index) {
setState(() {
_selectedPage = index;
});
},
You must use tab controller.
First you need to extend TickerProviderStateMixin in class.
class MyAppState extends State<MyApp> with TickerProviderStateMixin {
}
Then define TabController like,
_tabController = new TabController(length: _tabLength, vsync: this, initialIndex: 1);
and finally set controller in your TabBarView
controller: _tabController,
Here you initialize the default tab
int _selectedPage = 0;
You can change it to any tab you wish, If you want Profile
int _selectedPage = 4;
import 'package:flutter/material.dart';
import 'package:syncshop/widgets/cart_page.dart';
import 'package:syncshop/widgets/categories_page.dart';
import 'package:syncshop/widgets/home_page.dart';
import 'package:syncshop/widgets/profile_account.dart';
import 'package:syncshop/widgets/search_page.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return MyAppState();
}
}
class MyAppState extends State<MyApp> {
int _selectedPage = 4;
final _pageOptions = [
HomeScreen(),
CategoriesPage(),
SearchPage(),
CartPage(),
ProfileAccount(),
];
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Sync Shop',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: _pageOptions[_selectedPage],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: _selectedPage,
onTap: (int index) {
setState(() {
_selectedPage = index;
});
},
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text("Home"),
),
BottomNavigationBarItem(
icon: Icon(Icons.category),
title: Text("Categories"),
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text("Search"),
),
BottomNavigationBarItem(
icon: Icon(Icons.shopping_cart),
title: Text("Cart"),
),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle),
title: Text("Profile"),
),
],
),
),
);
}
}

How can I reuse the BottomNavigationBar Widget across multiple screens in Flutter?

So I want to know if it is possible to create a separate class using the BottomNavigationBar widget and then use it in other classes. A working example would be helpful.
You can write your own class:
class BottomNavigation extends StatelessWidget {
#override
Widget build(BuildContext context) {
return BottomNavigationBar(
...
);
}
Then import the page and use this inside the sacffold:
bottomNavigationBar: BottomNavigation,
maybe I don't really understand your problem. Is the BottomNavigationBar not supposed to be seen across many screens?
My BottomNavigationBar is in my MyApp class, which is called by the main. From the MyApp class, I start all the screens of my App. My code looks like:
class MyApp extends StatefulWidget
{
MyApp({Key key,}) : super(key: key);
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp>
{
int _selectedIndex = 1;
#override
Widget build(BuildContext context)
{
///////////Here are your different screens//////////////
final _widgetOptions = [
Screen1(),
Screen2(),
Screen3(),
];
/////////////////////////////////
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Name of your App',
theme: ThemeData(primarySwatch: Colors.grey,
accentColor: Colors.blueAccent,),
home: Scaffold(
backgroundColor: Colors.black12,
body: Center
(
child: _widgetOptions.elementAt(_selectedIndex),
),
//////////Bottom navigation////////////////
bottomNavigationBar: Theme
(
data: Theme.of(context).copyWith(
// sets the background color of the `BottomNavigationBar`
canvasColor: Colors.white,
// sets the active color of the `BottomNavigationBar`
primaryColor: Colors.blueAccent,
textTheme: Theme.of(context).textTheme.copyWith(
caption: new TextStyle(
color: Colors.grey))), // sets the inactive color of the
`BottomNavigationBar`
child: new BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: <BottomNavigationBarItem>
[
new BottomNavigationBarItem(icon: Icon(Icons.local_hospital), title: Text('Screen 1')),
new BottomNavigationBarItem(icon: Icon(Icons.search), title: Text('Screen 2')),
new BottomNavigationBarItem(icon: Icon(Icons.play_for_work), title: Text('Screen 3')),
],
currentIndex: _selectedIndex,
fixedColor: Colors.deepPurple,
onTap: _onItemTapped,
),
),
/////////////End of Bottom Navigation
),
);
}
void _onItemTapped(int index)
{
setState(()
{
_selectedIndex = index;
});
}
}
You have to define Screen1(), Screen2() and Screen3(). In my case, they are Statefulwidgets