I have some variables in one page and i want to pass it to another page when navigate.
first page codes with variables:
int groupValue = -1;
int idButton = 0;
onTap: (){
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => SearchResault(),
settings: RouteSettings(
arguments: {
IdButton,
groupValue
}
)
));
},
the problem is that every time i get {-1,0} but i want to choose what i want to RECIVE.
EDITED
This is the edited code down here:
You can just pass the argument through the constructor of your widget, as such:
Navigator.of(context).push(
MaterialPageRoute(builder:
(BuildContext context) =>
SearchResault(idButton: IdButton, groupValue: groupValue),
),
);
You can then define your stateless widget :
class SearchResault extends StatelessWidget {
final int idButton;
final int groupValue;
const SearchResault({this.idButton, this.groupValue});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Text("${idButton} - ${groupValue}")
);
}
}
You can just pass the argument through the constructor of your widget, as such:
Navigator.of(context).push(
MaterialPageRoute(builder:
(BuildContext context) =>
SearchResault(idButton: IdButton, groupValue: groupValue),
),
);
You can then define your stateless widget :
class SearchResault extends StatelessWidget {
final int idButton;
final int groupValue;
const SearchResault({this.idButton, this.groupValue});
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Text("${idButton} - ${groupValue}")
);
}
}
Related
Please help.
I'm trying to display the photo captured in 'Generated1Group1Widget1.dart' to 'GeneratedResultsWidget.dart'. However, 'main.dart' is having some errors.
GeneratedGroup1Widget1.dart
class GeneratedGroup1Widget1 extends StatefulWidget {
#override
_GeneratedGroup1Widget1State createState() => _GeneratedGroup1Widget1State();
}
class _GeneratedGroup1Widget1State extends State<GeneratedGroup1Widget1> {
XFile? _image;
Future _pickImage() async {
final imageSource = await showDialog<ImageSource>(
context: context,
builder: (context) => SimpleDialog(
title: const Text('Select Image Source'),
children: [
SimpleDialogOption(
onPressed: () => Navigator.pop(context, ImageSource.camera),
child: const Text('Camera'),
),
SimpleDialogOption(
onPressed: () => Navigator.pop(context, ImageSource.gallery),
child: const Text('Gallery'),
),
],
),
);
if (imageSource != null) {
final image = await ImagePicker().pickImage(source: imageSource);
setState(() {
_image = image;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => GeneratedResultsWidget(image: _image),
),
);
}
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => _pickImage(),
...
GeneratedResultsWidget.dart
class GeneratedResultsWidget extends StatelessWidget {
final XFile? image;
GeneratedResultsWidget({
required this.image,
});
#override
Widget build(BuildContext context) {
return Material(
child: ClipRRect(
...
main.dart
void main() {
runApp(food_classifierApp());
}
class food_classifierApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: Size(360, 640),
builder: (BuildContext context,child) => MaterialApp(
title: 'food-classifier',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/GeneratedHomepageWidget',
routes: {
'/GeneratedScanWidget': (context) => GeneratedScanWidget(),
'/GeneratedResultsWidget': (context) => GeneratedResultsWidget(image: _image),
'/GeneratedHomepageWidget': (context) => GeneratedHomepageWidget(),
'/GeneratedFoodlistWidget': (context) => GeneratedFoodlistWidget(),
},
),
);
}
}
Error
Undefined name '_image'.
Try correcting the name to one that is defined, or defining the name.
I already searched up google but I can't find answers to my question. Thanks in advance!
Where exactly you define _image variable in your food_classifierApp class?
You should use state management to access your image or ... in every where of your app
You need to create model to store your picked image file from GeneratedGroup1Widget1.
class AppModel {
String fileName;
AppModel(this.fileName);
}
Now you can call it from GeneratedGroup1Widget1
Navigator.pushNamed(context, '/GeneratedResultsWidget',
arguments: AppModel('your file or file name'));
And recieve it here
class GeneratedResultsWidget extends StatelessWidget {
const GeneratedResultsWidget({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
final args = ModalRoute.of(context)!.settings.arguments as AppModel;
return Scaffold(body: Center(child: Text(args.fileName)));
}
}
Route should be
routes: {
//***
'/GeneratedResultsWidget': (context) => GeneratedResultsWidget(),
//***
}
I'm having problems with my code as I'm getting undefined_identifier errors.
I'm trying to pass the image I captured from 'GeneratedGroup1Widget1.dart' using 'flutter_screenutils' to 'GeneratedResultsWidget.dart'. However, my route in 'main.dart' doesn't define the image variable inside my parameter. I've been trying to fix this error for 10 hours now. Please help. Thanks in advance!
Error: (main.dart)
Undefined name 'image'.
Try correcting the name to one that is defined, or defining the name.
Here are my codes:
'GeneratedGroup1Widget1.dart'
class GeneratedGroup1Widget1 extends StatefulWidget {
#override
_GeneratedGroup1Widget1State createState() => _GeneratedGroup1Widget1State();
}
class _GeneratedGroup1Widget1State extends State<GeneratedGroup1Widget1> {
Future _pickImage() async {
final imageSource = await showDialog<ImageSource>(
context: context,
builder: (context) => SimpleDialog(
title: const Text('Select Image Source'),
children: [
SimpleDialogOption(
onPressed: () => Navigator.pop(context, ImageSource.camera),
child: const Text('Camera'),
),
SimpleDialogOption(
onPressed: () => Navigator.pop(context, ImageSource.gallery),
child: const Text('Gallery'),
),
],
),
);
if (imageSource != null) {
final image = await ImagePicker().pickImage(source: imageSource);
Navigator.pushNamed(context, '/GeneratedResultsWidget', arguments: image);
}
}
#override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => _pickImage(),
child: Container(
....
'GeneratedResultsWidget.dart'
class GeneratedResultsWidget extends StatelessWidget {
final XFile file;
const GeneratedResultsWidget({required Key key, required this.file})
: super(key: key);
#override
Widget build(BuildContext context) {
if (file == null) {
return Scaffold(body: Center(child: Text('No Image selected')));
} else {
return Scaffold(body: Center(child: Text(file.path)));
}
}
}
class GeneratedResultsWidget1 extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Material(
...
'main.dart'
void main() {
runApp(FoodClassifierApp());
}
class FoodClassifierApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return ScreenUtilInit(
designSize: Size(360, 640),
builder: (BuildContext context, child) => MaterialApp(
title: 'food-classifier',
theme: ThemeData(
primarySwatch: Colors.blue,
),
initialRoute: '/GeneratedHomepageWidget',
routes: {
'/GeneratedScanWidget': (context) => GeneratedScanWidget(),
'/GeneratedResultsWidget': (context) =>
GeneratedResultsWidget(key: UniqueKey(), file: image),
'/GeneratedHomepageWidget': (context) => GeneratedHomepageWidget(),
'/GeneratedFoodlistWidget': (context) => GeneratedFoodlistWidget(),
},
),
);
}
}
This is my first time coding in flutter and I used figma to generate my widgets.
In the code below I am trying to build a basic ToDo list app using flutter. I have a FAB and when it is pressed, it asks the user to enter a text in the popped up alert dialog that contains a TextField. I also use a TextEditingController to get the text and add it to a list of strings.
I have a counter variable to keep track of items being added to the list and to use it as index of the list when I want to show the item from the list and add it to the ListView as a ListTile.
When I run the code it says the index is out of range and I really don't know what else should I take care of. Sorry if my question is basic, I am newbie.
My Code:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'ToDo List',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyTaskList(),
);
}
}
class MyTaskList extends StatefulWidget {
#override
_MyTaskListState createState() => _MyTaskListState();
}
class _MyTaskListState extends State<MyTaskList> {
final _taskItems = <String>[];
var _counter = 0;
final myController = TextEditingController();
#override
void dispose(){
myController.dispose();
super.dispose();
}
void _addTask(String task){
setState(() {
_taskItems.add(task);
});
myController.clear();
}
Widget _buildTaskList() {
return new ListView.builder(
itemCount: _taskItems.length,
itemBuilder: (BuildContext context, _) {
print(_taskItems);
return _buildTask(_taskItems[_counter]);
}
);
}
Widget _buildTask(String task) {
return new ListTile(
title: new Text(task),
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("ToDo List"),
),
floatingActionButton: FloatingActionButton(
onPressed: () => showDialog<String>(
context: context,
builder: (context) => AlertDialog(
title: Text("New Task"),
content: TextField(
controller: myController,
decoration: InputDecoration(
border: OutlineInputBorder(),
hintText: "Enter New Task",
),
),
actions: <Widget>[
TextButton(
onPressed: () => {
_addTask(myController.text),
Navigator.pop(context, "ok"),
_counter++,
print(_counter),
print(_taskItems),
},
child: const Text("OK")),
],
)
),
child: Center(child:Icon(Icons.add)),
),
body: _buildTaskList(),
);
}
}
Edit as below. You can use the ListViewBuilder index, why do you use counter? I think, your initial counter value is 0 but the list is empty. You try to get element 0 (or first)` of empty list, but there is no element.
Widget _buildTaskList() {
return new ListView.builder(
itemCount: _taskItems.length,
itemBuilder: (BuildContext context, index) {
print(_taskItems);
return _buildTask(_taskItems[index]);
}
);
}
I have an app where I cant to add a new item on ListView by clicking on FAB.
But I want fab and body of MetarialApp be in other classes. I don't want to smash them in one.
I'm trying to change count of children for ListView in Stateful widget, using Notification. But it doesn't work.
How to communicate with different widgets (like add an item to ListView widget by clicking on fab)?
What's the best approach? I've heard about global keys but I don't nderstand how to use them.
main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
var list = MyList();
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(title: Text("My App")),
body: list,
floatingActionButton: FloatingActionButton(
onPressed: () {
MyNotification(count: 1).dispatch(context);
},
child: Icon(Icons.add)),
),
theme: ThemeData(primarySwatch: Colors.green),
);
}
}
class MyList extends StatefulWidget {
#override
State<StatefulWidget> createState() => ListState();
}
class ListState extends State {
int count = 3;
#override
Widget build(BuildContext context) {
return NotificationListener<MyNotification>(
onNotification: onCountPush,
child: ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int index) {
return BodyCard();
}),
);
}
bool onCountPush(MyNotification notify) {
setState(() {
count += notify.count;
});
return true;
}
}
class MyNotification extends Notification {
final int count;
const MyNotification({this.count});
}
body and FAB are properties of Scaffold. So when you are trying to control the state of the body from FAB, the one that should be handling it is not the body but the Scaffold itself. Look, the Scaffold extends StatefulWidget and on the other hand the MyList extends StatelessWidget. Hope you get my point.
main() => runApp(App());
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: MyScaffold(),
theme: ThemeData(primarySwatch: Colors.green),
);
}
}
class MyScaffold extends StatefulWidget {
#override
State<StatefulWidget> createState() => MyScaffoldState();
}
class MyScaffoldState extends State {
int count = 3;
void changeCount() {
setState(() {
count = count == 3 ? 5 : 3;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("My App")),
body: MyList(count),
floatingActionButton: FloatingActionButton(
onPressed: changeCount,
child: Icon(Icons.add),
),
);
}
}
class MyList extends StatelessWidget {
final int count;
const MyList(this.count);
#override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: count,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: const EdgeInsets.all(10),
height: 30,
color: Colors.red,
);
},
);
}
}
Note:
Later when your states get more complex, you don't wanna stick with using setState to manage the states. Like others said, you can learn BLoC, ChangeNotifier or anything that suits you.
you should use Provider or BLoc in your code so you can do that
I'm trying to send data from a page to another in flutter project, tried all methods I found in another question but all failed, here is my code :
The first page :
Navigator.pushNamed(context, '/line_details', arguments: {'line':line,});
The second page:
class _LineDetailsState extends State<LineDetails> {
Map data = {};
#override
Widget build(BuildContext context) {
data = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepPurple,
title: Text("$data"),
),
);
}
}
note: the line is a custom object created.
the error : always returns null, even when tried to send a single string as {"test": "test string"} it returns a null too
your Example is working fine
route in MaterialApp
routes: { "/line_details": (context) => LineDetails(), },
Push on FlatButton:
onPressed: () => Navigator.pushNamed(context, '/line_details', arguments: {'line':'test',}),
class LineDetails
class LineDetails extends StatefulWidget {
#override
_LineDetailsState createState() => _LineDetailsState();
}
class _LineDetailsState extends State<LineDetails> {
Map data = {};
#override
Widget build(BuildContext context) {
data = ModalRoute.of(context).settings.arguments;
print(data);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepPurple,
title: Text("$data"),
),
);
}
}
with GestureDetector is also working
new GestureDetector(
onTap: () => Navigator.pushNamed(context, '/line_details', arguments: {'line':'test',}),
child: new Container(child: new Text("GestureDetector"),),
),
try this:
Navigator.push(
context,
LineDetailsState(
builder: (context) => LineDetailsState(
line: line
)))
and
class LineDetailsState extends StatefulWidget {
LineDetailsState(this.line);
Line line;
#override
_LineDetailsState createState() => _LineDetailsState();
}
class _LineDetailsState extends State<LineDetails> {
Map data = {};
#override
Widget build(BuildContext context) {
data = ModalRoute.of(context).settings.arguments;
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepPurple,
title: Text("$data"),
),
);
}
}
instead of "Line" replace it with name of your custom object
Your example looks proper one other thing you can try is typecast your argument
like below which help dart for linting. Note this is not related that you are getting null
class LineDetails extends StatefulWidget {
#override
_LineDetailsState createState() => _LineDetailsState();
}
class _LineDetailsState extends State<LineDetails> {
Map data = {};
#override
Widget build(BuildContext context) {
data = ModalRoute.of(context).settings.arguments as Map<String,object>;
print(data);
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.deepPurple,
title: Text("$data"),
),
);
}
}