Flutter bloc not working after hot reload - flutter

My app using bloc/cubit to display a list of Todo items works fine until I hot reload/hot restart the application!
I have two buttons, when i click these, the cubit state is set to having 3 todo items. Additionally I have two periodic timer which sets the cubit state to having only 1 or 0 todo items again. So the number of items is constantly changing from 1 to 0 until, or if i press a button it momentarily becomes 3.
This works fine until hot reload/restart after which the buttons no longer work! The periodic changes do work however. I can only alleviate this problem by creating my ToDoBloc as a field Initializer within my "MyApp" base widget.
main.dart:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:todo/todo_api_controller.dart';
import 'package:todo/todo_bloc.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
late TodoBloc _todoBloc; //!!----IF I CREATE THE TODOBLOC HERE EVERYTHING WORKS--!!
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
_todoBloc = TodoBloc(
apiController: TodoApiController(),
);
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(_todoBloc),
);
}
}
class MyHomePage extends StatelessWidget {
TodoBloc _todoBloc;
MyHomePage(this._todoBloc, {Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: BlocProvider<TodoBloc>.value(
value: _todoBloc,
child: BlocBuilder<TodoBloc, TodoBlocState>(
builder: (context, state) {
return Builder(
builder: (context) => Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () => context.read<TodoBloc>().LoadAll(),
child: Text(
'pressme',
style: TextStyle(color: Colors.red),
)),
ListView.builder(
shrinkWrap: true,
itemCount: state.todos.length,
itemBuilder: (context, index) {
var todo = state.todos[index];
return CheckboxListTile(
value: todo.isFinished,
onChanged: (newvalue) {},
);
}),
],
));
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await _todoBloc.LoadAll();
},
),
);
}
}
todo_api_controller.dart
class TodoApiController {
List<Todo> GetAll() {
return [
Todo(id: "asfsdf", name: "this is todo", isFinished: true, finishedOn: DateTime.now()),
Todo(id: "asfsdf", name: "this is todo", isFinished: true, finishedOn: DateTime.now()),
];
}
void Delete(String id) {}
void Update(Todo todo) {}
Todo Create() {
return Todo(id: "asdfsdf");
}
}
class Todo {
final String id;
String name;
bool isFinished;
DateTime? finishedOn;
Todo({required String id, String name = "", bool isFinished = false, DateTime? finishedOn = null})
: id = id,
name = name,
isFinished = isFinished,
finishedOn = finishedOn {}
}
todo_bloc.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:todo/todo_api_controller.dart';
class TodoBloc extends Cubit<TodoBlocState> {
static int numberOfInstances = 0;
int myInstance = -1;
TodoApiController _apiController;
List<Todo> todos = [];
TodoBloc({required TodoApiController apiController})
: _apiController = apiController,
super(TodoBlocState(todos: [TodoItemState(id: "asdfsdf", name: "sdfsdf", isFinished: true, finishedOn: null)])) {
numberOfInstances++;
myInstance = numberOfInstances;
Timer.periodic(Duration(seconds: 2), (s) => emit(TodoBlocState()));
Future.delayed(
Duration(seconds: 1),
() => Timer.periodic(
Duration(seconds: 2), (s) => emit(TodoBlocState(todos: [TodoItemState(id: "asdfsdf", name: "sdfsdf", isFinished: true, finishedOn: null)]))));
}
Future<void> LoadAll() async {
/* var newTodos = _apiController.GetAll();
todos.clear();
todos.addAll(newTodos);
var newState = MakeState();
emit(newState);*/
emit(TodoBlocState(todos: [
TodoItemState(id: "asdfsdf", name: "sdfsdf", isFinished: true, finishedOn: null),
TodoItemState(id: "asdfsdf", name: "sdfsdf", isFinished: true, finishedOn: null),
TodoItemState(id: "asdfsdf", name: "sdfsdf", isFinished: true, finishedOn: null),
]));
}
TodoBlocState MakeState() {
return TodoBlocState(
todos: todos
.map((e) => TodoItemState(
id: e.id,
finishedOn: e.finishedOn,
isFinished: e.isFinished,
name: e.name,
))
.toList(),
);
}
}
class TodoBlocState {
final List<TodoItemState> todos = [];
TodoBlocState({List<TodoItemState>? todos}) {
this.todos.addAll(todos ?? []);
}
}
class TodoItemState {
final String id;
final String name;
final bool isFinished;
final DateTime? finishedOn;
TodoItemState({required this.id, required this.name, required this.isFinished, required this.finishedOn});
}
I cant figure out why this is, especially with hot restart, as this should reset all application state.
EDIT: the issue appears after a hot reload(not hot restart) but cannot be fixed by hot restart
EDIT2: the issue is fixed by adding a GlobalKey() to the MyHomePage class. Though I cannot understand why. Can someone explain this to me?

This is happening because you're initializing your TodoBloc inside a build function.
Hot reload rebuilds your widgets so it triggers a new call to their build functions.
You should convert it into a StatefulWidget and initilize your TodoBloc inside the initState function:
class MyApp extends StatefulWidget {
MyApp({Key? key}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late TodoBloc _todoBloc;
#override
void initState() {
super.initState();
_todoBloc = TodoBloc(
apiController: TodoApiController(),
);
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(_todoBloc),
);
}
}

You really don't need to declare and initialize your TodoBloc at the top of the widget tree then pass it all the way down. BlocProvider creates a new instance that is accessible via context.read<TodoBloc>().
Your MyApp could look like this.
class MyApp extends StatelessWidget {
MyApp({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: BlocProvider(
create: (context) => TodoBloc(apiController: TodoApiController()), // this is your bloc being created and initialized
child: MyHomePage(),
),
);
}
}
And MyHomePage could be simplified. Note the lack of BlocProvider.value and Builder. All you need is a BlocBuilder and the correct instance of TodoBloc is always accessible with context.read<TodoBloc>().
class MyHomePage extends StatelessWidget {
MyHomePage({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: BlocBuilder<TodoBloc, TodoBlocState>(
builder: (context, state) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () => context.read<TodoBloc>().LoadAll(),
child: Text(
'pressme',
style: TextStyle(color: Colors.red),
),
),
ListView.builder(
shrinkWrap: true,
itemCount: state.todos.length,
itemBuilder: (context, index) {
var todo = state.todos[index];
return CheckboxListTile(
value: todo.isFinished,
onChanged: (newvalue) {},
);
},
),
],
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
await context.read<TodoBloc>().LoadAll();
},
),
);
}
}

Related

How to show updated list in shared preferences on UI - Flutter

I am making an app in a flutter in which I can select the contacts from phone book and saving them in shared preferences. No problem in data saving and retrieving but i m struggling with showing the updated list on my UI. It is showing the contacts list but every time I click on Load button it duplicates the list and showing 2 lists , 1 previous and other updated .
how can i show just updated list on UI ?
here is my code:
import 'package:contacts_test/select_contacts.dart';
import 'package:contacts_test/shared_pref.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'contact_model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
SharedPref sharedPref = SharedPref();
ContactModel modelLoad = ContactModel(displayName: 'saniya' , phoneNumber: '324235 ');
List _list = [];
#override
initState() {
super.initState();
// Add listeners to this clas
// loadSharedPrefs();
}
loadSharedPrefs() async {
try {
print('in load shared pref-- getting keys ');
final prefs = await SharedPreferences.getInstance();
final keys = prefs.getKeys();
print('now load shared pref ');
for (String key in keys) {
ContactModel user = ContactModel.fromJson(await sharedPref.read(key));
_list.add(user);
}
print('done load shared pref ');
}
catch (Excepetion) {
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("contacts "),
),
body: Builder(
builder: (context) {
return Column(children: [
RaisedButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Plugin1()));
},
child: const Text('fluttercontactpicker - plugin1'),
),
RaisedButton(
onPressed: () async {
await loadSharedPrefs();
},
child: Text('Load', style: TextStyle(fontSize: 20)),
),
Expanded(
child: _list.isNotEmpty ?
ListView.builder(
shrinkWrap: true,
itemCount: _list.length,
itemBuilder: (context, position) {
return ListTile(
leading: Icon(Icons.contacts),
title: Text(
_list[position].displayName.toString()
),
trailing: Icon(Icons.delete));
},
) : Center(child: Text('No list items to show')),
),
]);
}
),
);
}
}
Your loadSharedPrefs(); function adds each contact to the list you show. Every time you press the button, the same elements are added again to the list. There are multiple ways to avoid that. You can: empty the list before filling it, you can write a for loop to loop over the length of the incoming contacts and for each to add it to the list by always starting from index 0. In case you use some kind of replacement or removing method, make sure you call setState(()=> { });
Base on the answer, here is a possible solution:
import 'package:contacts_test/select_contacts.dart';
import 'package:contacts_test/shared_pref.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
import 'contact_model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
SharedPref sharedPref = SharedPref();
ContactModel modelLoad = ContactModel(displayName: 'saniya' , phoneNumber: '324235 ');
List _list = [];
#override
initState() {
super.initState();
// Add listeners to this clas
// loadSharedPrefs();
}
loadSharedPrefs() async {
try {
print('in load shared pref-- getting keys ');
final prefs = await SharedPreferences.getInstance();
final keys = prefs.getKeys();
print('now load shared pref ');
var newList = [];
for (String key in keys) {
ContactModel user = ContactModel.fromJson(await sharedPref.read(key));
newList.add(user);
}
setState(()=> { _list = newList; });
print('done load shared pref ');
}
catch (Excepetion) {
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("contacts "),
),
body: Builder(
builder: (context) {
return Column(children: [
RaisedButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => Plugin1()));
},
child: const Text('fluttercontactpicker - plugin1'),
),
RaisedButton(
onPressed: () async {
await loadSharedPrefs();
},
child: Text('Load', style: TextStyle(fontSize: 20)),
),
Expanded(
child: _list.isNotEmpty ?
ListView.builder(
shrinkWrap: true,
itemCount: _list.length,
itemBuilder: (context, position) {
return ListTile(
leading: Icon(Icons.contacts),
title: Text(
_list[position].displayName.toString()
),
trailing: Icon(Icons.delete));
},
) : Center(child: Text('No list items to show')),
),
]);
}
),
);
}
}

How to display data from nested list in Flutter

When I try display data from nested list it gives me that data which is not list at all.
Please help how to get that options data as list and display on Flutter widget.
class QuizData {
List<BrainData> getData = [
BrainData(
questionID: "biology1",
question:
"Pine, fir, spruce, cedar, larch and cypress are the famous timber-yielding plants of which several also occur widely in the hilly regions of India. All these belong to",
options: [
"angiosperms",
"gymnosperms",
"monocotyledons",
"dicotyledons",
],
answer: [false, true, false, false],
),
];
}
From the question, I have created a sample example for you.
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Test App',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
List<BrainData> list = [];
var selectedValue;
List<BrainData> getData = [
BrainData(
questionID: "biology1",
question:
"Pine, fir, spruce, cedar, larch and cypress are the famous timber-yielding plants of which several also occur widely in the hilly regions of India. All these belong to",
options: [
"angiosperms",
"gymnosperms",
"monocotyledons",
"dicotyledons",
],
answer: [false, true, false, false],
),
];
#override
void initState() {
super.initState();
setState(() {
list = getData;
});
}
void showInSnackBar(String value, bool isCorrect) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
backgroundColor: isCorrect ? Colors.green : Colors.red,
content: Text(value),
duration: const Duration(milliseconds: 200),
));
}
#override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
body: list.isEmpty
? Container()
: ListView.builder(
itemCount: list.length,
itemBuilder: (context, index) {
var item = list[index];
return Column(
children: [
Padding(
padding: const EdgeInsets.all(15.0),
child: Text('${index + 1} : ${item.question}'),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: item.options.map((e) {
return RadioListTile(
title: Text(e),
value: e,
groupValue: selectedValue,
onChanged: (value) {
setState(() {
selectedValue = value;
var correctAnswerIndex = item.answer.indexWhere((element) => element == true);
var selectedItemIndex =
item.options.indexWhere((element) => element == value);
if (correctAnswerIndex == selectedItemIndex) {
showInSnackBar('Selected Correct Value', true);
} else {
showInSnackBar('Better luck next time', false);
}
});
},
);
}).toList(),
),
)
],
);
}),
);
}
}
class BrainData {
final String questionID;
final String question;
final List<String> options;
final List<bool> answer;
BrainData({
required this.questionID,
required this.question,
required this.options,
required this.answer,
});
}
This is the Sample UI:
Check the example and let me know if it works for you.

Flutter - How to call an API every n minutes?

I need to call an API every n minutes. The data should be available across all screens. How can I implement this at app level. I am not using any state management tools.
void main() {
periodicSub = Stream.periodic(const Duration(seconds: 10))
.listen((_) {
///fetch data
someFuture =
Future<List<someObject>>.delayed(
const Duration(milliseconds: 500), () async {
return someFunction();
});
});
someFuntions returns a list. I want a certain FutureBuilder on HomePage to execute whenever the list is updated.
Here is an example using "https://pub.dev/packages/provider"
First create a Notifier:
import 'dart:async';
import 'package:flutter/material.dart';
class CustomNotifier with ChangeNotifier {
int counter = 0;
CustomNotifier() {
Stream.periodic(const Duration(seconds: 10)).listen((_) {
///fetch data
Future<List<dynamic>>.delayed(const Duration(milliseconds: 500),
() async {
return someFunction();
});
});
}
someFunction() {
counter++;
notifyListeners();
}
}
Then you could use it like:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'notifier.dart';
void main() {
final customNotifier = CustomNotifier();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => customNotifier,
),
//You could add more providers
],
builder: (context, _) {
return const MyApp();
},
),
);
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
var customNotifier = Provider.of<CustomNotifier>(
context,
);
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'someFunction runs this many times:',
),
Text(
'${customNotifier.counter}',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
);
}
}

Trying to create animated list but not sure how to get listKey from another script file?

I am trying to make my list animated, so when i delete task it plays animation. I watched few tutorials however i am not sure how to implement this into my code because they had the animatedlist and void deleteitem in the same script, where i am having in 2 different one.
Here is my code from the task_data script file
void removeItem(Task task) {
//removedTask = task;
final item = _tasks.remove(task);
listKey.currentState!.removeItem(
task,
(context, animation) => TaskTile(
//taskTitle: task.name,
//isChecked: task.isDone,
//checkboxCallback: (checkboxState) {
//taskData.updateTask(task);
taskTitle: task.name,
isChecked: task.isDone,
animation: animation, checkboxCallback: (bool) {},
longPressCallback: () {},
));
notifyListeners();
saveData();
}
Here is my code from task_tile script
class TaskTile extends StatelessWidget {
final bool isChecked;
final String taskTitle;
final Function(bool?) checkboxCallback;
final VoidCallback longPressCallback;
final Animation<double> animation;
TaskTile({
required this.isChecked,
required this.taskTitle,
required this.checkboxCallback,
required this.longPressCallback,
required this.animation,
});
And here is my code from tasks_list script file
#override
Widget build(BuildContext context) {
return Consumer<TaskData>(
builder: (context, taskData, child) {
return AnimatedList(
key: _listKey,
initialItemCount: taskData.tasks.length,
itemBuilder: (context, index, animation) {
return TaskTile(
animation: animation,
taskTitle: taskData.tasks[index].name,
//isChecked: Provider.of<TaskData>(context).tasks[index].isDone,
//Provider.of<TaskData>(context).tasks = task_data. we would use LHS when we did not wrap with Consumer
isChecked: taskData.tasks[index].isDone,
checkboxCallback: (checkboxState) {
HapticFeedback.mediumImpact();
taskData.updateTask(taskData.tasks[index]);
},
longPressCallback: () {
ScaffoldMessenger.of(context).showSnackBar(snackBar(taskData));
taskData.deleteTask(taskData.tasks[index]);
HapticFeedback.heavyImpact();
},
);
},
//itemCount: taskData.taskCount,
);
},
);
Would really appreciate if someone can help me with this!
EDIT
--- I am getting this error right now "The argument type 'Task' can't be assigned to the parameter type 'int'."
on the actual screen it displays red box range error and I'm not sure how to fix those
Use it as a global key to access the keys from other classes
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
//Create it as Global key
final myListKey = GlobalKey<AnimatedListState>();
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final widgets = [
Container(color: Colors.red),
Container(color: Colors.green),
Container(color: Colors.yellow),
];
int currentIndex = 0;
#override
void initState() {
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: AnimatedList(
key: myListKey,
initialItemCount: widgets.length,
itemBuilder: (_, index, animation) {
return Container(
height: 100,
child: widgets[index],
);
},
),
);
}
}

Flutter use one Variable in different classes Error: Getter not found: 'allJobs'

I have a Variable in one Class but and i want to use it in all.
In this Example is the allJobs Variable which is declared in Muesnterboerse ore MuensterboerseAAAngebote and i want to use it in senddate().
class Muensterboerse extends StatelessWidget {
var allJobs = 1;
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App with MYSQL',
home: new MyHomePage(),
);
}
}
class MuensterboerseAAAngebote extends StatelessWidget {
var allJobs = 0;
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App with MYSQL',
home: new MyHomePage(),
);
}
}
Future<dynamic> senddata() async {
final response = await http.post(
"https://www.bumsbirnbe.php", body: {
"status": allJobs,
});
var datauser = json.decode(response.body);
String jsonsDataString = datauser.toString();
dynamic jsonData = jsonDecode(jsonsDataString);
print(jsonData);
return jsonData;
}
Update
Now i added your changes to my code but i get the
Error: Unhandled Exception: NoSuchMethodError: The getter 'allJobs' was called on null.
This is my whole code:
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
GlobalKey _key1 = GlobalKey();
class Muensterboerse extends StatelessWidget {
Muensterboerse({Key key}) : super(key: key);
int allJobs = 1;
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App with MYSQL',
home: new MyHomePage(),
);
}
}
class AAAngebote extends StatelessWidget {
AAAngebote({Key key}) : super(key: key);
int allJobs = 2;
#override
Widget build(BuildContext context) {
return new MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Flutter App with MYSQL',
home: new MyHomePage(),
);
}
}
Future<dynamic> senddata() async {
int allJobs = (_key1.currentWidget as Muensterboerse).allJobs;
print(allJobs);
final response = await http.post(
"https://www.Bumsbirne.php", body: {
"status": allJobs,
});
var datauser = json.decode(response.body);
String jsonsDataString = datauser.toString();
dynamic jsonData = jsonDecode(jsonsDataString);
print(jsonData);
return jsonData;
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
dynamic jsonData;
callSendData() async {
jsonData = await senddata();
setState(() {});
}
//lol
#override
void initState() {
callSendData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: jsonData == null
? Center(child: CircularProgressIndicator())
: ListView.builder(
padding: const EdgeInsets.all(16.0),
itemCount: jsonData == null ? 0 : jsonData.length,
itemBuilder: (context, index) {
return ListTile(
leading: CircleAvatar(
backgroundImage: NetworkImage('https://kinsta.com/de/wpcontent/uploads/sites/5/2019/09/wordpress-loggst-url-1024x512.jpg'),
radius: 27,
),
title: Text(
jsonData[index]["titel"],
),
subtitle: Text(jsonData[index]["nam_ersteller"]),
trailing: Text(
'25 Km',
style: TextStyle(color: Colors.grey,
fontSize: 12,
decoration: TextDecoration.none,
fontFamily: 'Roboto',),
),
onTap: () {
Navigator.push(context,
new MaterialPageRoute(builder: (context) => DetailPage()));
},
);
// return _buildRow(data[index]);
}));
}
}
class DetailPage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Der Job'),
),
);
}
}
You can copy paste run full code below
Step 1: You can use GlobalKey and pass to Muensterboerse(key: _key1)
Step 2: In senddata(), do (_key1.currentWidget as Muensterboerse).allJobs;
code snippet
GlobalKey _key1 = GlobalKey();
...
class Muensterboerse extends StatelessWidget {
Muensterboerse({Key key}) : super(key: key);
...
Future<dynamic> senddata() async {
int allJobs = (_key1.currentWidget as Muensterboerse).allJobs;
print(allJobs);
...
Muensterboerse(key: _key1),
output of senddata()
I/flutter (22480): 1
full code
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
GlobalKey _key1 = GlobalKey();
class Muensterboerse extends StatelessWidget {
Muensterboerse({Key key}) : super(key: key);
int allJobs = 1;
#override
Widget build(BuildContext context) {
return Column(
children: [
Text("$allJobs"),
],
);
}
}
Future<dynamic> senddata() async {
int allJobs = (_key1.currentWidget as Muensterboerse).allJobs;
print(allJobs);
/*final response = await http.post(
"https://www.quyre.de/2/Muensterboerse.N.php", body: {
"status": allJobs
});*/
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() async{
await senddata();
setState(() {
_counter++;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Muensterboerse(key: _key1),
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}