Accessing Classes in different pages - flutter

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
}
}

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,
],
);
}
}

Call Navigator from outside state or call child state method from parent

I ended up with a parent calling a child method, which is fine, but I can't call Navigator outside the state class. My goal is either to move the child method in it's state and somehow access it, or to call Navigator form outside the state in a Stateful widget.
What is the best approach to this problem?
import 'package:flutter/material.dart';
class ParentClass extends StatefulWidget {
const ParentClass({Key? key}) : super(key: key);
#override
_ParentClassState createState() => _ParentClassState();
}
class _ParentClassState extends State<ParentClass> {
ChildClass childclass = ChildClass();
#override
Widget build(BuildContext context) {
return Container(
child: ElevatedButton(
child: Text('Button'),
onPressed: () => {
childclass.callNavigator(),//or call callNavigatorState
}),
);
}
}
class ChildClass extends StatefulWidget {
const ChildClass({Key? key}) : super(key: key);
void callNavigator() {
//call navigator from here
}
#override
_ChildClassState createState() => _ChildClassState();
}
class _ChildClassState extends State<ChildClass> {
void callNavigatorState(){
//access from parent widget?
}
#override
Widget build(BuildContext context) {
return Container();
}
}
you can access a stateful's state, using Globalkey.currentState...
check this sample code:
class MyHomePage extends StatelessWidget {
MyHomePage({Key? key}) : super(key: key);
final child = ChildWidget(key: GlobalKey());
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
child,
ElevatedButton(
onPressed: () {
(((child as ChildWidget).key as GlobalKey).currentState!
as _ChildWidgetState)
.someFunction();
},
child: Text("childWidget someFunction"))
],
),
);
}
}
class ChildWidget extends StatefulWidget {
const ChildWidget({Key? key}) : super(key: key);
#override
_ChildWidgetState createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
void someFunction() {
print("childWidget someFunction");
}
#override
Widget build(BuildContext context) {
return Container();
}
}

How to add custom values in inside expression in flutter math_fork library

class ResultPage extends StatefulWidget {
DataModel dataModel;
ResultPage({Key? key, required this.dataModel}) : super(key: key);
#override
_ResultPageState createState() => _ResultPageState();
}
class _ResultPageState extends State<ResultPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Math.tex("m=/frac "${widget.datamodel.value}"")
);
}
}
but the math.tex is showing error in flutter how to pass custom values in any equation
class ResultPage extends StatefulWidget {
DataModel dataModel;
ResultPage({Key? key, required this.dataModel}) : super(key: key);
#override
_ResultPageState createState() => _ResultPageState();
}
class _ResultPageState extends State<ResultPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body:Math.tex(
"m = ${r'\frac'} {${widget.datamodel.value1}}
{$widget.datamodel.value2}",
textStyle: textStyle,
),
);}}
that is how you can add custom values in the equation in flutter math_fork
The 'Scaffold' need to have a 'body'. Try to add 'Math.text' under 'body'.
Here is a package's sample code that use 'Math.tex'.
https://github.com/simpleclub-extended/flutter_math_fork/blob/9015c77bc79f5e21820de3c927f43ff275b35078/test/helper.dart#L30
https://github.com/simpleclub-extended/flutter_math_fork/blob/9015c77bc79f5e21820de3c927f43ff275b35078/example/lib/display.dart#L29
class ResultPage extends StatefulWidget {
DataModel dataModel;
ResultPage({Key? key, required this.dataModel}) : super(key: key);
#override
_ResultPageState createState() => _ResultPageState();
}
class _ResultPageState extends State<ResultPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Math.tex("m=/frac "${widget.datamodel.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())
}