How to acces parameter value from constructor in flutter? - flutter

I'm having trouble with accessing the value of a parameter from a constructor in my code. I access to this page from another one where I get the value of the parameter:
final route = MaterialPageRoute(
builder: (context) => AnadirJugadores(idPagina: respuesta['id'],));
Navigator.push(context, route);
This is the code of AnadirJugadores:
class AnadirJugadores extends StatefulWidget {
final String idPagina;
AnadirJugadores({required this.idPagina });
String cogerID() {
return this.idPagina;
}
#override
State<AnadirJugadores> createState() => _AnadirJugadoresState();
}
class _AnadirJugadoresState extends State<AnadirJugadores> {
#override
Widget build(BuildContext context) {
.... more code
ElevatedButton(
child: Text(idPartida), // this is the line of the error
onPressed: () {
final data = ClipboardData(text: '25342756374');
Clipboard.setData(data);
},
),
I'm trying to access the value of idPagina. How could I do that?
Thanks in advance.

When using stateful widgets you need to use widget to access the parameters.
child: Text(widget.idPartida),

In StatefulWidget your constructor exists in upper class (it's not in State class), so to access data in this constructor in your state class you should do this:
ElevatedButton(child: Text(widget.idPartida), ...),

Related

Is it possible to share and update one screen's reactive value in another screen without Provider?

So I have this block of code in a widget that navigates to another screen:
screen_one.dart
class ScreenOne extends StatefulWidget {
const ScreenOne({ super.key });
#override
State<ScreenOne> createState() => _ScreenOneState();
}
class _ScreenOneState extends State<ScreenOne> {
List<String> state = [''];
#override
Widget build(BuildContext context) {
return Column(
MaterialButton(
onPressed: () => Navigator.pushNamed(context, '/screen-two'),
child: Text('Click here.')
),
Text(state[0]),
);
}
}
screen_two.dart
class ScreenTwo extends StatelessWidget {
const ScreenTwo({ super.key });
#override
Widget build(BuildContext context) {
return Container();
}
}
Basically I need to pass the state variable from ScreenOne to ScreenTwo and then update it there (in ScreenTwo)
ScreenTwo needs to display the same thing as ScreenOne and add() a new item to the state list when some button is clicked which should show on both the screens.
Its just one simple List so I am trying to avoid using provider.
Is it possible to do though?
I'm currently just passing it through the Navigator:
screen_one.dart
Navigator.pushNamed(
context,
'/post-info',
arguments: state,
),
screen_two.dart
Widget build(BuildContext context) {
final List<String> post = ModalRoute.of(context)!.settings.arguments as List<String>;
// ...
}
first I want to recommend you when things go bigger and more complex, it's better to use a state management approach, However since you did say that you have only one List you can simply use a ValueNotifier, with ValueListenableBuilder:
// this should be outside widget classes, maybe in a custom-made class or just in a global scope.
ValueNotifier stateNotifier = ValueNotifier([""]);
now in the places you want to use that state, you can use ValueListenableWidget like this:
ValueListenableBuilder(
valueListenable: stateNotifier,
builder: (context, value, child) {
return Column(
children: [
Text('${state[0]}'),
MaterialButton(
onPressed: () {
Navigator.pushNamed(context, '/screen-two'),
},
child: Text('click'),
),
],
);
},
);
}
}
and any other place where you want to see that state get updates, you need to use ValueListenableWidget.
Now, for executing a method like add() on the List and notify the widgets, you need to assign a new value for it like this:
void addInTheList(String elem) {
List current = stateNotifier.value;
current.add(elem);
// this exactly what will be responsible for updating.
stateNotifier.value = current;
}
now, you can just call addInTheList and expect it to update in all of them:
addInTheList("Example");

Read nested widget/class properties value in flutter

I'm building a simple app with lots of nested widgets/classes from different specialised files
list of files:
main.dart -> the menu file used to start the activity
"Activity()"
group_widgets.dart -> the file that contains the custom widget
"CustomWidget()"
file_a.dart -> the file that uses the custom widgets
inside the "Activity()"
other.dart -> other files that needs to manage data changed in CustomWidget()
inside main.dart:
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const Activity(),
));
},
inside group_widgets.dart:
class CustomWidget extends StatefulWidget {
const CustomWidget({Key? key}) : super(key: key);
#override
State<CustomWidget> createState() => _CustomWidgetState();
}
class _CustomWidgetState extends State<CustomWidget> {
var _boolean = false;
bool switchBoolean(bool state) => !state;
#override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () => {
setState(() {
_boolean = switchBoolean(_boolean);
})
},
child: Container(
color: _boolean == true ? Colors.green : Colors.red,
),
);
}
}
inside file_a.dart
class Activity extends StatefulWidget {
const Activity({Key? key}) : super(key: key);
#override
State<Activity> createState() => _ActivityState();
}
class _ActivityState extends State<Activity> {
#override
Widget build(BuildContext context) {
bool boolean = true;
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
CustomWidget(),
Text('Here where to show the variable from CustomWidget'
'and prove I can retrieve it')
],
),
),
);
}
}
inside other.dart
if ( booleanFromCustomWidget == true) {
Something ...
}
What is the best practice to achieve it?
I've read a lot here but nothing seems to well fit my needing.
Just comment if my request is not as clear as it seems to me))
Please correct me if I am wrong, but if you want to access data from parent widgets from inside their descendants (children or even nested children) you can either pass them down via parameter arguments:
Child(int age, String name);
And then accept it in the new file, where the Child widget lives, via its constructor:
class Child {
String name;
int age;
// Constructor
Child(String passedName, int passedAge) {
this.name = passedName;
this.age = passedAge;
}
}
Inside the parent.dart you then have to import the children.dart to use it.
Or use a popular package like the provider package: https://pub.dev/packages/provider
This allows you to store data containers, which you can access basically anywhere in your code. Feel free to google it & watch some tutorials to get started, as it is the preferred approach to avoid passing data to widget which really do not care about the passed parameters.
Note: You can transfer the idea to output the String data like in your example code above.
you can use a state manager like provider, or bloc
At the top level, you set up the data services

error: The return type 'CategoryState' isn't a 'Widget', as required by the closure's context

I tried to put the route to Another Class on the Same Page and wrote this code as mentioned in the flutter Doc, but I get this:
error: The return type CategoryState isn't a Widget, as required
by the closure's context.
Page code:
Navigation code:
According to the documentation: the builder function of the MaterialPageRoute class should return a widget. Both StatelessWidget and StatefulWidget extend the Widget class and thus can be used here.
But in your case the CategoryState class does not extend any of them, and it's the reason you are having that error.
You need to use the Category class instead.
It should then look like:
PAGE :
class Category extends StatefulWidget {
#override
_CategoryState createState() => _CategoryState();
}
class _CategoryState extends State<Category> {
#override
Widget build(BuildContext context) {
return Column(
children: [
Container(child: Text("Music")),
Container(child: Text("Projects")),
Container(child: Text("Essay")),
],
);
}
}
NAVIGATION
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Category())
);
Furthermore, I would advise you to add a suffix to this class name (e.g. CategoryScreen) in order to avoid name conflicts in case you have another class (e.g. a model) with the same name.
class CategoryState is not a widget it's just a Dart class you want to navigate to Category()

How do i access a varible from another class in Flutter

I'm making my first flutter app.
it asks for some information then when you click a button it shows the information you entered on another page, I wanted to ask. How do I get a variable from another class?
so I can use the information entered on another page
It seems like you want to pass some data while navigating to another page. If I'm not wrong You should define a variable in the destination like this:
class NewPage extends StatefulWidget {
final int someInt;
NewPage({Key key, this.someInt}) : super(key: key);
#override
_NewPageState createState() => _NewPageState();
}
class _NewPageState extends State<NewPage> {
#override
Widget build(BuildContext context) {
return Container(
child: Container(child: Text("${widget.someInt}"),),
);
}
}
In the above code I passed someInt to NewPage class.
In the first page you should navigate like this:
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => NewPage(someInt: 293,),
));
put above code in the onPressed and pass the data with constructor.

How do I navigate to a page that has a constructor parameter?

I have a flutter stateful page. Here it is:
class TestPage extends StatefulWidget {
static const String id = 'TestPage';
final String testString;
TestPage(this.testString);
#override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(child: Text('Hello ${widget.testString}'))
);
}
}
The page has a constructor that takes in a string as a default value.
final String testString;
From another page, I make a call to that page. I want to open it and give it or pass to it a String value:
Navigator.pushNamed(context, TestPage(myString));
However, it is telling me:
that the argument type 'TestPage' cannot be assigned to the parameter type String.
What am I doing wrong? Is this not the correct way to instantiate this class and make it appear?
Thank you
Try with this,
Navigator.push( context, MaterialPageRoute( builder: (context) => TestPage(testString: 'Hello',), ));