well, I'm trying to create a really simple app with a bottom navigation bar and for so I created a list that lists what to be displayed in each page, the problem is that I wana have a floating button that increments a counter everytime I press it but when I do the thing to display on screen the counter inside the list, it gives me the error mesage: The instance member 'counter' can't be accessed in an initializer.
Just to clarify, the problem is right on the beggining of the code on the list, where I put the ${counter}
My code:
import 'package:flutter_speed_dial/flutter_speed_dial.dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
));
}
class MyApp extends StatefulWidget {
#override
_State createState() => new _State();
}
class _State extends State<MyApp> {
int counter = 0;
void resetCounter() {
setState(() {
counter = 0;
});
}
void incrementCounter() {
setState(() {
counter++;
});
}
List<Widget> _pages = <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Row(),
Container(
padding: EdgeInsets.all(15),
margin: EdgeInsets.all(10),
color: Colors.grey[300],
child: Text(
'lets see how many times you click it',
style: TextStyle(
fontSize: 15,
fontFamily: 'IndieFlower',
fontWeight: FontWeight.bold,
),
),
),
Text(
'button clicks - ${counter}',
style: TextStyle(
fontFamily: 'IndieFlower',
fontWeight: FontWeight.bold,
color: Colors.blue[600],
fontSize: 20,
letterSpacing: 3,
),
),
],
),
Icon(
Icons.camera,
size: 150,
),
];
int _selectedIndex = 0;
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('button test'),
centerTitle: true,
backgroundColor: Colors.blue[400],
),
body: Center(
child: _pages.elementAt(_selectedIndex),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
child: Icon(
Icons.restart_alt
),
onPressed: () {
resetCounter();
},
heroTag: null,
),
SizedBox(
height: 10,
),
FloatingActionButton(
child: Icon(
Icons.plus_one
),
backgroundColor: counter == 10 ? Colors.grey : Colors.blue,
onPressed: () =>
counter < 10 ? incrementCounter() : ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(
'limit reached',
style: TextStyle(
fontWeight: FontWeight.bold,
),
))),
heroTag: null,
)
]
),
bottomNavigationBar: BottomNavigationBar(
items: const<BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'home',
),
BottomNavigationBarItem(
icon: Icon(Icons.add_photo_alternate_outlined),
label: 'page 2',
),
],
currentIndex: _selectedIndex,
onTap: _onItemTapped,
),
);
}
}
Two solutions:
The quickest fix is to add late keyword, like so:
late List<Widget> _pages = <Widget>[
...
];
Another solution is to move your List<Widget> _pages = [...]; variable declaration inside the build method.
Both solutions achieves the same goal: delay accessing the variable ($counter) until when it's needed (i.e. when building the widget).
By the way, new keyword is no longer needed in Dart. You should remove all of them. For example, createState() => new _State() should just be createState() => _State().
Related
Good day! I have here some block of codes of my MainMenu page and Drawer.
I need to pass data from MainMenu which is a statefulwidget to Drawer which is also a statefulwidget so that I can use the datas and method from MainMenu.
Can someone help me or reproduce my code below.
class MainMenu extends StatefulWidget {
final VoidCallback signOut;
MainMenu(this.signOut);
#override
_MainMenuState createState() => _MainMenuState();
}
class _MainMenuState extends State<MainMenu> {
int index = 0;
List<Widget> list = [
HomeScreen(),
Stations(),
AccountPage(),
];
signOut() {
setState(() {
widget.signOut();
});
}
int currentIndex = 0;
String selectedIndex = 'TAB: 0';
String email = "", id = "", fname= "";
TabController tabController;
getPref() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
setState(() {
id = preferences.getString('id');
email = preferences.getString('email');
fname = preferences.getString('fname');
});
print("id:" + id);
print("user:" + email);
print("address:" + fname);
}
#override
void initState() {
// TODO: implement initState
super.initState();
getPref();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(
onPressed: () {
signOut();
},
icon: Icon(Icons.lock_open),
)
],
backgroundColor: Color(0xFF262AAA),
iconTheme: IconThemeData(color: Colors.lightBlue),
centerTitle: true,
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('DVO',
style: TextStyle(color: Colors.lightBlue,fontWeight: FontWeight.w700),
),
SizedBox(width: 1.3),
Text(
'REPORT',
style: TextStyle(color: Colors.white,fontWeight: FontWeight.w700),
),
],
),
elevation: 0,
),
body: list[index],
drawer: MyDrawer(onTap: (lol, i) {
setState(() {
index = i;
Navigator.pop(lol);
});
}),
),
);
}
}
class MyDrawer extends StatefulWidget {
#override
_MyDrawerState createState() => _MyDrawerState();
}
class _MyDrawerState extends State<MyDrawer> {
Function onTap;
_MyDrawerState(
{this.onTap
});
#override
Widget build(BuildContext context) {
return SizedBox(
width: MediaQuery
.of(context)
.size
.width * 0.7,
child: Drawer(
child: Container(
color: Colors.white,
child: ListView(
padding: EdgeInsets.all(0),
children: <Widget>[
UserAccountsDrawerHeader(
decoration: BoxDecoration(
color: Colors.white,
image: DecorationImage(
image: AssetImage("assets/badge.jpg"),
fit: BoxFit.cover,
colorFilter: new ColorFilter.mode(Colors.black.withOpacity(0.8), BlendMode.dstATop)),
),
accountEmail: Text("dummy#gmail.com"),
accountName: Text("Dummy",
style: TextStyle(color: Colors.white,fontWeight: FontWeight.w700, fontSize: 25),
),
currentAccountPicture: CircleAvatar(
backgroundColor: Colors.grey[400],
child: Icon(
Icons.perm_identity,
color: Colors.white,
),
),
),
ListTile(
selected: true,
leading: Icon(Icons.announcement, color: Colors.cyan,size: 26.0),
title: Text("News And Announcements",
style: TextStyle(color: Colors.black,fontWeight: FontWeight.w500, fontSize: 18),
),
onTap: () => onTap(context, 0),
),
ListTile(
leading: Icon(Icons.place,color: Colors.cyan, size: 30.0),
title: Text("Stations",
style: TextStyle(color: Colors.black,fontWeight: FontWeight.w500, fontSize: 18),
),
onTap: () => onTap(context, 1),
),
ListTile(
leading: Icon(Icons.settings,color: Colors.cyan, size: 30.0),
title: Text("Account Settings",
style: TextStyle(color: Colors.black,fontWeight: FontWeight.w500, fontSize: 18),
),
onTap: () => onTap(context, 2),
),
Divider(
height: 595,
thickness: 0.5,
color: Colors.white.withOpacity(0.3),
indent: 32,
endIndent: 32,
),
ListTile(
leading: Icon(Icons.exit_to_app,color: Colors.cyan, size: 30.0),
onTap: () {
//widget.signOut();
},
title: Text("Logout",
style: TextStyle(color: Colors.black,fontWeight: FontWeight.w500, fontSize: 18),
),
),
],
),
),
),
);
}
}
I'm getting this error on build widget in MainMenu.
The named parameter 'onTap' isn't defined.
Try correcting the name to an existing named parameter's name, or defining a named parameter with the name 'onTap'.
This part:
Function onTap;
_MyDrawerState({this.onTap});
This parameter and its presence in the constructor should be in the MyDrawer public class rather than a private State class.
The specified error comes because MyDrawer class doesn't have this.
You can access onTap function in _MyDrawerState through the widget variable which is an instance of MyDrawer class
I am completely new at coding and of course I am trying to tackle one of the largest projects I can think of.... anyways. I am running into a huge wall when it comes to my current stage of coding. I have a defaultTabController at the upper portion of the screen with the functionality to switch in between two tabs. I would also like to have a bottomNavigationBar at the bottom of the application with 5 buttons that navigate to additional pages.
I have been attempting to add this code PageView(controller: _pageController, children: <Widget>[],) to the body of my code, yet I am either getting an overload of errors or only the top or bottom nav bars are active. If someone could show me what I'm doing wrong, I would be so grateful!
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
int _currentTab = 0;
PageController _pageController;
#override
void initState() {
super.initState();
_pageController = PageController();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: DefaultTabController(
length: 2,
child: Scaffold(
extendBodyBehindAppBar: true,
extendBody: true,
appBar: AppBar(
backgroundColor:
Colors.grey.withOpacity(0.5),
title: Text(
'TREBLE',
style: TextStyle(
color: Colors.black,
fontFamily: "treblefont",
fontSize: (33.0)
),
),
bottom: TabBar(
tabs: <Widget>[
Tab(text: "Following"),
Tab(text: "trending"),
],
)
),
body:
TabBarView(
children: <Widget>[
FeedScreen(),
TrendingScreen(),
],
),
bottomNavigationBar: CupertinoTabBar(
currentIndex: _currentTab,
onTap: (int index) {
setState(() {
_currentTab = index;
});
},
activeColor: Colors.black,
backgroundColor: Colors.white.withOpacity(0.5),
items: [
BottomNavigationBarItem(
icon: Icon(
Icons.home,
size: 32.0,
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.search,
size: 32.0,
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.camera_enhance,
size: 32.0,
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.notifications,
size: 32.0,
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.account_circle,
size: 32.0,
),
),
],
),
),
),
);
}
}
I attempt to insert the code here:
)
),
body:
PageView(controller: _pageController, children: <Widget>[],)
TabBarView(
children: <Widget>[
FeedScreen(),
TrendingScreen(),
],
),
bottomNavigationBar: CupertinoTabBar(
currentIndex: _currentTab,
onTap: (int index) {
setState(() {
_currentTab = index;
});
},
line of code screenshot
Specific error readout screenshot
I have been trying to do what the title says but have found no information on the web at all. In regular Android code, this is as simple as finding the ViewID of the drawer/toolbar, getting the menu item, and either calling .setEnabled() or .setVisible() on the menu item. How can I do this in Flutter? Basically when a certain url is loaded in webView, I want to either enable/disable or show/hide programatically (in the onLoadStart and onLoadFinished methods for webview_flutter). For reference, my scaffold:
return new Scaffold(
appBar: new AppBar(
title: new Text(appBarTitle),
actions: <Widget>[
IconButton(
icon: Icon(
Icons.refresh,
color: Colors.white,
),
onPressed: () {
webView.reload();
},
),
PopupMenuButton<Choice> ( //showchoice??
onSelected: _select,
itemBuilder: (BuildContext context) {
return choices.map((Choice choice) {
return PopupMenuItem<Choice>(
value: choice,
child: Text(choice.title),
);
}).toList();
},
),
],
),
drawer: Drawer(
child: ListView(
children: <Widget>[
new DrawerHeader(
child: Column (
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget> [
Text(
'HLS Grades',
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
Text(
'Canvas Online Grading System',
style: TextStyle(
color: Colors.white,
fontSize: 12,
),
),
]),
decoration: BoxDecoration(
color: Colors.blue,
),
),
Divider(),
Text(
'Course Actions',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
ListTile(
leading: Icon(MyFlutterApp.assignment),
title: Text('Assignments'),
onTap: () {
setState(() => _selectedDrawerIndex = 0);
_onSelectNavItem(0);
},
),
ListTile(
leading: Icon(MyFlutterApp.grades),
title: Text('Grades'),
onTap: () {
setState(() => _selectedDrawerIndex = 1);
_onSelectNavItem(1);
},
),
ListTile(
leading: Icon(MyFlutterApp.people),
title: Text('Users'),
onTap: () {
setState(() => _selectedDrawerIndex = 2);
_onSelectNavItem(2);
},
),
ListTile(
leading: Icon(MyFlutterApp.syllabus),
title: Text('Syllabus'),
onTap: () {
setState(() => _selectedDrawerIndex = 3);
_onSelectNavItem(3);
},
),
ListTile(
leading: Icon(MyFlutterApp.discussions),
title: Text('Discussions'),
onTap: () {
setState(() => _selectedDrawerIndex = 4);
_onSelectNavItem(4);
},
),
Divider(),
Text(
'App Actions',
style: TextStyle(
color: Colors.black,
fontSize: 12,
),
),
ListTile(
leading: Icon(MyFlutterApp.logout),
title: Text('Logout'),
onTap: () {
_onSelectNavItem(5);
},
),
ListTile(
leading: Icon(MyFlutterApp.settings),
title: Text('Settings'),
onTap: () {
_onSelectNavItem(6);
},
),
],
),
),
And the code for my choice class:
class Choice {
const Choice({this.title, this.icon});
final String title;
final IconData icon;
}
const List<Choice> choices = const <Choice>[
const Choice(title: 'All Grading Periods'),
const Choice(title: 'Trimester 1'),
const Choice(title: 'Trimester 2'),
const Choice(title: 'Trimester 3'),
];
class ChoiceCard extends StatelessWidget {
const ChoiceCard({Key key, this.choice}) : super(key: key);
final Choice choice;
#override
Widget build(BuildContext context) {
final TextStyle textStyle = Theme.of(context).textTheme.headline4;
return Card(
color: Colors.white,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(choice.icon, size: 128.0, color: textStyle.color),
Text(choice.title, style: textStyle),
],
),
),
);
}
}
Any help would be appreciated!
For whoever is stumped by this and is looking for an answer, just wrap your ListTile in a
Visibility (
visible: _visible
child: ListTile(...)
);
and whenever you want to remove, just
setState(() {
_visible = false;
});
or whenever you want to show
setState(() {
_visible = true;
});
I want to work with textfields but it doesn't work. Visual Studio always shows an error and I don't know why. The string userText is static because Visual Studio Code wanted this. I even don't know what static means.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
double mph;
int _currentIndex = 0;
static String userText = '';
final _pageOptions = [
Center(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.all(8.0),
margin: EdgeInsets.only(bottom: 20.0),
child: Text(
'Km/h',
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
color: Colors.blue[400],
),
),
),
TextField(
decoration: InputDecoration(
hintText: 'Km/h',
focusColor: Colors.green[400],
),
onSubmitted: (String e){
setState(() {
userText = e;
});
},
),
Container(
margin: EdgeInsets.only(top: 10.0),
child: Text(
userText,
style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 20.0,
)
),
)
]
)
),
Text('Suche'),
Text('Kamera'),
Text('Profil'),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Test"),
backgroundColor: Colors.green[400],
),
body: _pageOptions[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
iconSize: 30,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text("Home"),
backgroundColor: Colors.blue[400],
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text("Suche"),
backgroundColor: Colors.green[400],
),
BottomNavigationBarItem(
icon: Icon(Icons.camera_alt),
title: Text("Kamera"),
backgroundColor: Colors.orange[400]
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
backgroundColor: Colors.purple[400]
),
],
onTap: (index){
setState(() {
_currentIndex = index;
});
},
),
);
}
}
Short answer:
You're initialising it as instance variable, so you can't use setState in it.
final _pageOptions = [...]; // incorrect way
You can simply use getter and setState works in it. Like:
List<Widget> get _pageOptions => [...]; // correct way
Full answer:
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
double mph;
int _currentIndex = 0;
static String userText = '';
List<Widget> get _pageOptions => [
Center(
child: Column(
children: <Widget>[
Container(
padding: const EdgeInsets.all(8.0),
margin: EdgeInsets.only(bottom: 20.0),
child: Text(
'Km/h',
style: TextStyle(
fontSize: 25.0,
fontWeight: FontWeight.bold,
color: Colors.blue[400],
),
),
),
TextField(
decoration: InputDecoration(
hintText: 'Km/h',
focusColor: Colors.green[400],
),
onSubmitted: (String e){
setState(() {
userText = e;
});
},
),
Container(
margin: EdgeInsets.only(top: 10.0),
child: Text(
userText,
style: TextStyle(
fontStyle: FontStyle.italic,
fontSize: 20.0,
)
),
)
]
)
),
Text('Suche'),
Text('Kamera'),
Text('Profil'),
];
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Test"),
backgroundColor: Colors.green[400],
),
body: _pageOptions[_currentIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _currentIndex,
iconSize: 30,
items: [
BottomNavigationBarItem(
icon: Icon(Icons.home),
title: Text("Home"),
backgroundColor: Colors.blue[400],
),
BottomNavigationBarItem(
icon: Icon(Icons.search),
title: Text("Suche"),
backgroundColor: Colors.green[400],
),
BottomNavigationBarItem(
icon: Icon(Icons.camera_alt),
title: Text("Kamera"),
backgroundColor: Colors.orange[400]
),
BottomNavigationBarItem(
icon: Icon(Icons.person),
title: Text("Profile"),
backgroundColor: Colors.purple[400]
),
],
onTap: (index){
setState(() {
_currentIndex = index;
});
},
),
);
}
}
I am making a flutter application that have shopping cart. Right now, i am just working on a single functionality of it when we select a particular product, after increase or decrease its quantity then our cart doesnot show the quantity of that item on the cart immediately. we have to go to another widget then it update the count on cart.
Note: HomeScreen comprise of two stateful widget, one is bottom navigation bar which have cart and other icons along with other icons and their respective UI's and other one is Product screen which is showing all our products, and in my product screen i used listview and in its UI i used - and + icons to increase or decrease its quantity. I am sharing the code of the widget - and +(a small portion of product screen) on which i want to implement this functionality.
This is the video link to show
https://youtu.be/3qqVpmWguys
HomeScreen:
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
//static _HomeScreenState of(BuildContext context) => context.ancestorStateOfType(const TypeMatcher<_HomeScreenState>());
int _currentindex = 0;
var cart;
final List<Widget> children = [
ProductScreen(),
OrderScreen(),
CartScreen(),
AccountScreen(),
];
List<BottomNavigationBarItem> _buildNavigationItems() {
var bloc = Provider.of<CartManager>(context);
int totalCount = bloc.getCart().length;
setState(() {
totalCount;
});
return <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: Icon(
Icons.reorder,
size: 30,
color: Colors.white,
),
title: Text(
'Product',
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.add_alert,
size: 30,
color: Colors.white,
),
title: Text(
'Order',
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
BottomNavigationBarItem(
icon: Stack(
children: <Widget>[
Icon(
Icons.shopping_cart,
size: 30,
color: Colors.white,
),
Positioned(
bottom: 12.0,
right: 0.0,
child: Container(
constraints: BoxConstraints(
minWidth: 20.0,
minHeight: 20.0,
),
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(10.0),
),
child: Center(
child: Text(
'$totalCount',
style: TextStyle(
fontSize: 12,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
)
],
),
title: Text(
'Cart',
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
BottomNavigationBarItem(
icon: Icon(
Icons.lock,
size: 30,
color: Colors.white,
),
title: Text(
'Account',
style: TextStyle(fontSize: 15, color: Colors.white),
),
),
];
}
#override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomPadding: true,
body: children[_currentindex],
bottomNavigationBar: BottomNavigationBar(
fixedColor: Colors.transparent,
backgroundColor: Colors.orange,
onTap: onNavigationTapbar,
currentIndex: _currentindex,
items: _buildNavigationItems(),
type: BottomNavigationBarType.fixed,
),
),
);
}
void onNavigationTapbar(int index) {
setState(() {
_currentindex = index;
});
}
}
ProductScreen incrementor or decrementor:
class TEProductIncrementor extends StatefulWidget {
var product;
TEProductIncrementor({
this.product,
});
#override
_TEProductIncrementorState createState() => new _TEProductIncrementorState();
}
class _TEProductIncrementorState extends State<TEProductIncrementor> {
int totalCount = 0;
#override
Widget build(BuildContext context) {
var cartmanager = CartManager();
void decrementsavecallback() {
// bloc.decreaseToCart(widget.ctlist);
//CartManager().updateToCart(totalCount.toString(), widget.ctlist);
setState(() {
if (totalCount > 0) {
totalCount--;
cartmanager.updateToCart(totalCount.toString(),widget.product);
}
});
}
void increasesavecallback() {
setState(() {
totalCount++;
cartmanager.updateToCart(totalCount.toString(),widget.product);
});
}
return Container(
margin: EdgeInsets.only(top: 8),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10), color: Colors.orange),
child: Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
iconSize: 30,
icon: new Icon(
Icons.remove,
),
onPressed: () {
decrementsavecallback();
},
),
Text(
totalCount.toString(),
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
IconButton(
iconSize: 30,
icon: new Icon(Icons.add),
onPressed: () {
increasesavecallback();
},
)
],
),
),
);
}
}
You can pass the entire function into a widget just implemented like below
class Parent extends StatefulWidget {
#override
_ParentState createState() => _ParentState();
}
class _ParentState extends State<Parent> {
#override
Widget build(BuildContext context) {
return Button(
(){
setState(() {
///define your logic here
});
}
);
}
}
class Button extends StatelessWidget {
final Function onTap;
Button(this.onTap);
#override
Widget build(BuildContext context) {
return FlatButton(
onPressed: onTap,
);
}
}
But if your project is pretty big then I will recommend you to use any state management libraries just like redux or mobx.
https://pub.dev/packages/mobx
You can use BLoC pattern for this,
Here is full answer and demo code that you can check.
Why not use keys?
Assign at both widget a GlobalKey and then, when you need to update that state you just need to call
yourGlobalKeyName.currentState.setState((){
//your code
});