NoSuchMethodError: The getter was called on null - flutter

`
class MainPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider( //Comes from provider class
create: (context) => LocaleProvider(),
builder: (context, child) {
final provider = Provider.of<LocaleProvider>(context);
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Forts In Maharashtra',
locale: provider.locale,
supportedLocales: L10n.all,
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
home: MyApp(),
);
});
}
}
class MyApp extends StatefulWidget {
//static const String _title = 'Forts in Maharashtra';
MyApp({Key key, this.title}) : super(key: key);
final String title;
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
new FirebaseNotifications().setUpFirebase();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(accentColor: Colors.deepOrange),
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: Text(
AppLocalizations.of(context).apptitle, //Translates the text
style: TextStyle(fontSize: 23.0),
),
backgroundColor: Colors.deepOrange,
actions: [
Icon(Icons.language, size: 28),
LanguagePick(),
const SizedBox(width: 12),
],
),
body: MyBottomNavigationBar()),
);
}
}
class MyBottomNavigationBar extends StatefulWidget {
class _MyBottomNavigationBarState extends State<MyBottomNavigationBar> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: _children[_currentindex],
bottomNavigationBar: BottomNavigationBar(
type: BottomNavigationBarType.fixed,
selectedItemColor: Colors.deepOrange,
onTap: onTappedBar,
currentIndex: _currentindex,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.explore),
label: AppLocalizations.of(context).exploreforts), //Giving error here
BottomNavigationBarItem(
icon: Icon(MdiIcons.waves), label: 'Sea Forts'),
BottomNavigationBarItem(
icon: Icon(Icons.terrain), label: 'Attractions'),
BottomNavigationBarItem(
icon: Icon(Icons.location_city), label: 'City Forts'),
],
));
}
}`
I am trying to use the Localization feature in my application. I am able to change the AppBar title to another language but I am unable to change the language on the BottomNavigationBar. I am having trouble changing the language in BottomNavigationBar. The App language is changed on the AppBar but I am facing issues while using the same in the BottomNavigationBar. I have added comments where required.

This is because you are defining two MaterialApp. You only need to define one in the main and render it in the entire app, remove the MaterialApp from the _MyAppState class

Related

How can i change theme of my widget in this situation?

Im not sure that my code is correct for using themes and easylocalization together and im open for any help too, but my main goal is creating a custom navigation bar inside of MyApp. When i do it like example down below, i cant change my NavBarItem theme with my theme provider because of its outside of MaterialApp. How can i handle this situation ?
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(EasyLocalization(
supportedLocales: [
Locale('en'),
Locale('tr'),
],
path: 'assets/translations',
saveLocale: true,
fallbackLocale: Locale('en'),
child: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => CustomThemeData(),
builder: (context, _) {
return MaterialApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
theme: Provider.of<CustomThemeData>(context).getThemeData,
home: Scaffold(
body: _ActivePage,
bottomNavigationBar: Container(child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
NavBarItem(),
NavBarItem(),
NavBarItem(),
],
),),
),
//
);
},
);
}
Widget NavBarItem(){}
}
You can try this below codebase, I think you will get your solution.
main.dart
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:theme_changer/custom_theme_data.dart';
final callMenuTheme = ThemeData(
primarySwatch: Colors.orange,
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.orange),
iconTheme: const IconThemeData(
color: Colors.orange,
),
);
final cameraMenuTheme = ThemeData(
primarySwatch: Colors.red,
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.red),
iconTheme: const IconThemeData(
color: Colors.red,
),
);
final chatMenuTheme = ThemeData(
primarySwatch: Colors.green,
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.green),
iconTheme: const IconThemeData(
color: Colors.green,
),
);
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(EasyLocalization(
supportedLocales: const [
Locale('en'),
Locale('tr'),
],
path: 'assets/translations',
saveLocale: true,
fallbackLocale: const Locale('en'),
child: ChangeNotifierProvider(
create: (context) => CustomThemeData(0, callMenuTheme),
builder: (context, _) {
return MaterialApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
theme: Provider.of<CustomThemeData>(context).getThemeData(),
home: const MyApp(),
//
);
},
)));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
var themeNotifier = Provider.of<CustomThemeData>(context,listen: false);
List<Widget> _pages = <Widget>[
const Icon(
Icons.call,
size: 150,
),
const Icon(
Icons.camera,
size: 150,
),
const Icon(
Icons.chat,
size: 150,
),
];
void _onItemTapped(int index) async{
setState(() {
switch(index) {
case 0:
{
themeNotifier.setNavigationIndexData(0);
themeNotifier.setThemeData(callMenuTheme);
}
break;
case 1:
{
themeNotifier.setNavigationIndexData(1);
themeNotifier.setThemeData(cameraMenuTheme);
}
break;
case 2:
{
themeNotifier.setNavigationIndexData(2);
themeNotifier.setThemeData(chatMenuTheme);
}
break;
default:
{
themeNotifier.setNavigationIndexData(0);
themeNotifier.setThemeData(callMenuTheme);
}
break;
}
});
}
return MaterialApp(
debugShowCheckedModeBanner: false,
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
theme: themeNotifier.getThemeData(),
home: Scaffold(
appBar: AppBar(
title: const Text('BottomNavigationBar Demo'),
),
body: Center(
child: _pages.elementAt(themeNotifier.getNavigationIndexData()),
),
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.call),
label: 'Calls',
),
BottomNavigationBarItem(
icon: Icon(Icons.camera),
label: 'Camera',
),
BottomNavigationBarItem(
icon: Icon(Icons.chat),
label: 'Chats',
),
],
currentIndex: themeNotifier.getNavigationIndexData(),
onTap: _onItemTapped,
),
),
);
}
}
custom_theme_data.dart
import 'package:flutter/material.dart';
class CustomThemeData with ChangeNotifier {
ThemeData? _themeData;
int? _navigationIndex;
CustomThemeData(this._navigationIndex, this._themeData);
getNavigationIndexData() => _navigationIndex;
setNavigationIndexData(int navigationIndex) async {
_navigationIndex = navigationIndex;
notifyListeners();
}
getThemeData() => _themeData;
setThemeData(ThemeData themeData) async {
_themeData = themeData;
notifyListeners();
}
}
If you need a better idea about the project, here is the GitHub link to this project. Also, you will check the screenshots(1,2,3) of this project.

Pass function with parameter to child. Parameter should come from child

Imagine I have a parent widget and a child widget. In the parent widget, there is a variable: 'page index'. And the child widget needs to change that variable in a set state method (because it has to be refreshed). How can I do this?
The body of the scaffold renders content based on the pageindex.
The code
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int pageIndex = 0;
List<Widget> pageList = <Widget>[
HomeScreen(),
ProfileScreen(),
CartScreen(),
ProfileScreen(),
ProfileScreen()
];
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CartViewModel()),
],
child: MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Home page',
theme: theme(),
onGenerateRoute: generateRoute,
home: Scaffold(
bottomNavigationBar: BottomNavBar(pageIndex, setPageIndex()),
body: pageList[pageIndex],
),
),
);
}
void setPageIndex(newValue) {
setState(() {
pageIndex = newValue;
});
}
}
class BottomNavBar extends StatefulWidget {
BottomNavBar(this.pageIndex, this.setPageIndexFunction);
int pageIndex;
VoidCallback setPageIndexFunction;
#override
State<BottomNavBar> createState() => _BottomNavBarState();
}
class _BottomNavBarState extends State<BottomNavBar> {
#override
Widget build(BuildContext context) {
CartViewModel cartViewModel = context.watch<CartViewModel>();
return BottomNavigationBar(
elevation: 5,
backgroundColor: Colors.white,
currentIndex: widget.pageIndex,
type: BottomNavigationBarType.fixed,
fixedColor: kAccentColor,
items: [
const BottomNavigationBarItem(
label: "Home", icon: Icon(Icons.home_outlined)),
const BottomNavigationBarItem(
label: "Search", icon: Icon(Icons.search_outlined)),
BottomNavigationBarItem(
label: "Cart",
icon: buildCustomBadge(
counter: cartViewModel.loading == false
? cartViewModel.cart!.count
: 0,
child: Icon(Icons.shopping_bag_outlined),
)),
const BottomNavigationBarItem(
label: "Favorite",
icon: Icon(Icons.favorite_border_outlined)),
const BottomNavigationBarItem(
label: "Profile", icon: Icon(Icons.person_outline))
],
onTap: (value) {
widget.setPageIndexFunction(value);
},
);
}
}
What is the problem
I am trying to call the function: "setPageIndexFunction(value)" and pass in the clicked value. Then it should call the function "setState" in the parent.
How can I do this?
The reason I put the bottomnavbar in a separate widget is because I could not write this line of code in the MyApp class: "CartViewModel cartViewModel = context.watch();". I need this line to check if an item has been added to my cart and show it in the bottomnavbar.
Or should I use provider for this?
Thanks!
Try these steps:
Use ValueChanged<int> instead of VoidCallback
class BottomNavBar extends StatefulWidget {
BottomNavBar(this.pageIndex, this.setPageIndexFunction);
int pageIndex;
ValueChanged<int> setPageIndexFunction;
#override
State<BottomNavBar> createState() => _BottomNavBarState();
}
Use setPageIndex in _MyAppState as a tear-off.
bottomNavigationBar: BottomNavBar(pageIndex, setPageIndex),

How To Fix Bottom navigation in flutter?

How to fix Bottom Navigation in Flutter?
MediaQuery.Of() called with context That does not contain a
MediaQuery.Bottom Navigation Not working.
This code Showing Error What is MediaQuery.Of() called with context That does not contain a MediaQuery?
import 'package:flutter/material.dart';
void main(){
runApp(Home());
}
class Home extends StatefulWidget{
#override
State<StatefulWidget> createState() => _HomeState();
}
class _HomeState extends State<Home>{
int currindex=0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Bottom Nav "),
),
body: Container(),
bottomNavigationBar: BottomNavigationBar(
currentIndex: currindex,
items:[BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text("Home"),
backgroundColor: Colors.blue
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text("Search"),
backgroundColor: Colors.blue
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
backgroundColor: Colors.blue
),],
onTap: (index){
setState(() {
currindex=index;
});
},
));
}
}
it is because you are not using MaterialApp(), you need to use MaterialApp() in your widget tree
look at this demo....
void main() => runApp(Home());
class Home extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: //your Title,
theme: //your theme,
home: HomePage(),
);
}
}
class HomePage extends StatefulWidget{
#override
State<StatefulWidget> createState() => _HomePageState();
}
//and your _HomePageState widget goes here

Flutter: animate appbar color with bottomnavigationbar

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.

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