three clases use setState callback to update var on other class - flutter

I have next thre classes:
Shortly the scenario: have two classes MyApp1, MyApp2 and MyApp3,
MyApp3 updates the var count with callback (indeed updated), I would like to print it (count) on MyApp2, how can I setState also on MyApp2 so it will take effect?
my_app1.dart
class MyApp1 extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp1> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final int count = 0;
void callbakc() {
setState(() {
count++;
});
}
#override
Widget build(BuildContext context) {
return Container(
Row(
children:[
MyApp2(),
MyApp3(callback: callback), //suppose I have button on MyApp3, pressed it, and indded count increased by 1
]
),
);
}
}
my_app2.dart
class MyApp2 extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp2> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Container(
child: Text(count), how can I see the update count? from MyApp1?
);
}
}
my_app3.dart
class MyApp3 extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<MyApp3> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Container();
}
}

use state management to do this. for example GetX. Type GetX in pub.dev and search.
Avoid setState. because it will increase the workload of your program.
For the answer to your question, see the link below.
Flutter Back button with return data

Just pass the count parameter to MyApp2 so when your callback function run then it again render MyApp2 and update the count on MyApp2 also
here is an example -
Code in MyApp1
MyApp2(count:count),
MyApp2 Code
class MyApp2 extends StatefulWidget {
const MyApp({Key? key,this.count}) : super(key: key);
final int count;
#override
State<MyApp2> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Container(
child: Text($`enter code here count), how can I see the update count? from MyApp1?
);
}
}

Related

How to use a method in a Stateful Widget from another Widget

So i have this toggle() method in the Stateful SideBar class
class SideBar extends StatefulWidget {
const SideBar({super.key});
#override
State<SideBar> createState() => _SideBarState();
}
class _SideBarState extends State<SideBar> with SingleTickerProviderStateMixin{
void toggle() {
if (_controller.isCompleted) {
_controller.reverse();
}
else {_controller.forward();}
}
}
and i want to use it in
class SideBarWidget extends StatelessWidget {
SideBarWidget({Key? key}) : super(key: key);
final SideBar sideBarWidget = SideBar(...);
void toggle() {
// here i want to use the toggle() method
}
#override
Widget build(BuildContext context) {
return sideBarWidget;
}
}
I cannot use sideBarWidget.toggle()
I also cannot pass it as a parameter becasue the _controller is in the SideBar() widget
There are many ways, but the most common and simple is to create an instance of the SideBar class inside the SideBarWidget class, for example:
var side = SideBar();
And then you can access the toggle() method like this: side.toggle().
remove underscore from SideBarState
to use method of SideBarState in SideBarWidget use: SideBarState().toggle();
**screen1.dart**
class ParentWidget extends StatefulWidget {
const ParentWidget({Key? key}) : super(key: key);
#override
State<ParentWidget> createState() => ParentWidgetState();
}
class ParentWidgetState extends State<ParentWidget> {
void printData() {
print("parent");
}
#override
Widget build(BuildContext context) {
return const Placeholder();
}
}
**screen2.dart**
import 'package:demo/screen_1.dart';
import 'package:flutter/material.dart';
class ChildWidget extends StatelessWidget {
const ChildWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
ParentWidgetState().printData();
return const Placeholder();
}
}
One way is to give the SideBar a GlobalKey and get the state from the key afterwards. An example:
class SideBar extends StatefulWidget {
const SideBar({super.key});
#override
State<SideBar> createState() => SideBarState();
}
class SideBarState extends State<SideBar> with SingleTickerProviderStateMixin{
#override
Widget build(BuildContext context) {
return Container();
}
void toggle() {
print('toggle');
}
}
class SideBarWidget extends StatelessWidget {
SideBarWidget({Key? key}) : super(key: key);
final GlobalKey<SideBarState> sideBarKey = GlobalKey();
late final SideBar sideBarWidget = SideBar(key: sideBarKey);
void toggle() {
sideBarKey.currentState?.toggle();
}
#override
Widget build(BuildContext context) {
return Column(
children: [
TextButton(onPressed: toggle, child: const Text('click')),
sideBarWidget,
],
);
}
}

No Directionality widget found ; I want to use only Container and Text

I just run the basic flutter code.
I want to make stateful widget, only containing Text("hi")
so I write my code like below
import 'package:flutter/material.dart';
void main() {
runApp(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) {
return Container(child: Text("hi");
}
}
but I got error
No Directionality widget found.
RichText widgets require a Directionality widget ancestor
I can fix my error to add textDirection attribute,
but I wonder when I use Text I didn't get that error even if I don't use that attribute.
I just want to use only Text, Container
i think its because you dont have MaterialApp
try it like this will work
void main() {
runApp(const MyApp1());
}
class MyApp1 extends StatelessWidget {
const MyApp1({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: 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 Container(child: Text("hi"));
}
}
Text needs a Directionality widget to provide information on whether the text is "left-to-right" or "right-to-left". Usually this is done (behind the scene) by MaterialApp widget. If you don't want to use that, you could provide one yourself, and specify the text direction.
Minimal code for a hello world:
import 'package:flutter/material.dart';
void main() {
runApp(
Directionality(
textDirection: TextDirection.ltr,
child: Text("Hello world."),
),
);
}

Accessing Classes in different pages

can somebody explain me when we have one file like Home.dart i have access to extends state classes and it's static variables
Home.dart
import 'package:flutter/material.dart';
class FirstClass extends StatefulWidget {
const FirstClass({Key? key}) : super(key: key);
#override
State<FirstClass> createState() => _FirstClassState();
}
class _FirstClassState extends State<FirstClass> {
static void someFunc() {
print('nothing');
}
#override
Widget build(BuildContext context) {
return Container();
}
}
class SecondClass extends StatefulWidget {
const SecondClass({Key? key}) : super(key: key);
#override
State<SecondClass> createState() => _SecondClassState();
}
class _SecondClassState extends State<SecondClass> {
#override
Widget build(BuildContext context) {
return ElevatedButton(onPressed: _FirstClassState.someFunc, child: Text(' '));
}
}
but when we have two different file like home1.dart and home2.dart we cant access to extends state classes?
Home1.dart
import 'package:flutter/material.dart';
class FirstClass extends StatefulWidget {
const FirstClass({Key? key}) : super(key: key);
#override
State<FirstClass> createState() => _FirstClassState();
}
class _FirstClassState extends State<FirstClass> {
static void someFunc() {
print('nothing');
}
#override
Widget build(BuildContext context) {
return Container();
}
}
Home2.dart
import 'package:flutter/material.dart';
import 'Home1.dart';
class SecondClass extends StatefulWidget {
const SecondClass({Key? key}) : super(key: key);
#override
State<SecondClass> createState() => _SecondClassState();
}
class _SecondClassState extends State<SecondClass> {
#override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: **_FirstClassState.someFunc?????**, child: Text(' '));
}
}
i know i can have access to FirstClass but why can not have access to _FirstClassState ?
I think it is better to separate your widget classes and logic classes that contains some function.
Since you are extending Stateless/Stateful widget, the class is becoming a widget.
Create you method or function in another class and don't extend anything if you don't have to then use static keyword in front of the functions so that you can access those functions inside another class or let's say in your stateful widget class.
However, if you need to pass values from one Stateful widget to another then add that object to your widget's constructor. Example as follows:
class FirstClass extends StatefulWidget {
String username = ""; //Creating & initializing username variable
//Adding username variable inside constructor
const FirstClass({Key? key, required this.username}) : super(key: key);
#override
State<FirstClass> createState() => _FirstClassState();
}
class _FirstClassState extends State<FirstClass> {
static void someFunc() {
print('nothing');
}
#override
Widget build(BuildContext context) {
return Text(widget.username); //Accessing username
}
}
Then, pass your value in the widget like this:
class SecondClass extends StatefulWidget {
const SecondClass({Key? key}) : super(key: key);
#override
State<SecondClass> createState() => _SecondClassState();
}
class _SecondClassState extends State<SecondClass> {
#override
Widget build(BuildContext context) {
return FirstClass(username: "Tricolore"); //Passing username value
}
}

Is there a way to access the instance of a StatefulWidget inside of it's state?

I have a list of widgets which I want to update if a button on the inside of one of those widgets is pressed.
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
void initState() {
super.initState();
init();
}
List<Training> finalTrainings = [];
void addTraining(Training training){
setState(() {
finalTrainings.add(training);
});
}
#override
Widget build(BuildContext context) {
return Training(addTraining);
}
}
addTraining is the callback function I use
class Training extends StatefulWidget {
const Training({Key? key, required this.addTraining}) : super(key: key);
final Function addTraining;
#override
State<Training> createState() => _TrainingState();
}
class _TrainingState extends State<Training> {
#override
Widget build(BuildContext context) {
ElevatedButton(
child: Text("add training",),
onPressed: () {
widget.addTraining(this);
},
)
}
}
Here I use "this" trying to reference the Training instance but obviously this doesn't work, since it just returns the "_TrainingState" instance. Is there a way I can access the Training instance from within _TrainingState?
If you want to access the instance of a widget from where you use that widget, you should make the state class public by removing its underscore:
class Training extends StatefulWidget {
const Training({Key? key, required this.addTraining}) : super(key: key);
final Function addTraining;
#override
State<Training> createState() => TrainingState();
}
// state class should be public
class TrainingState extends State<Training> {
#override
Widget build(BuildContext context) {
ElevatedButton(
child: Text("add training",),
onPressed: () {
widget.addTraining(this);
},
)
}
}
then use global key:
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
final trainingKey = GlobalKey<TrainingState>();
#override
void initState() {
super.initState();
init();
}
List<Training> finalTrainings = [];
void addTraining(Training training){
// widget instance that you want to access
final trainingWidget = trainingKey.currentWidget;
}
#override
Widget build(BuildContext context) {
return Training(key: trainingKey);
}
}

Is there a way to access a field from the state of a StatefulWidget?

I have a field that changes in the state of a StatefulWidget but I want to access it in the widget itself.
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
#override
Widget build(BuildContext context) {
return Training();
}
}
class Training extends StatefulWidget {
const Training({Key? key}) : super(key: key);
String trainingToString(){
return('people selected: ' + //Here I would need to access the variable from _TrainingState);
}
#override
State<Training> createState() => _TrainingState();
}
class _TrainingState extends State<Training> {
int peopleSelected = 0;
void updatePeopleSelected(int peopleSelected){
setState((){
this.peopleSelected = peopleSelected;
}
}
#override
Widget build(BuildContext context) {
return Container();
}
}
So I have the field peopleSelected and a function to update it in _TrainingState and when I call Training.trainingToString() I want it to print this field but I can't access the field through Training.
Is there a way you can do it or what would be some alternatives?
you must to call this function you can use only for now
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){updatePeopleSelected()}
child: Container())
}