I have a serious problem with my Riverpod. Specifically, I am using StateProvider in Riverpod package. But when I update state, the widget tree does not rebuild. I checked the new state whether is updated by printing out state to see, I see that they are actually updated.
I have some same situations but when I click hot restart/reload page/scroll up,down mouse to change size chrome window, the widget tree rebuild one time.
Please help me and explain everything the most detail and easy to understand. Thank you very much
new state print out but UI not update
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:math';
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class Data {
final String data;
Data({required this.data});
}
final helloWorldProvider = StateProvider<Data?>((ref) => Data(data: 'No data'));
class MyApp extends ConsumerStatefulWidget {
const MyApp({super.key});
#override
ConsumerState<MyApp> createState() => _MyAppState();
}
class _MyAppState extends ConsumerState<MyApp> {
#override
void initState() {
// TODO: implement initState4
print("Init state");
super.initState();
// getData();
}
// getData() async {
// // http.Response response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/todos/1'));
// // final title = jsonDecode(response.body)["title"];;
// // ref.read(helloWorldProvider.notifier).update((state) => title);
// SharedPreferences prefs = await SharedPreferences.getInstance();
// prefs.setString('valueTemp', 'newValue');
// String? valueTemp = prefs.getString('valueTemp');
// String value = valueTemp ?? '';
// Data data = Data(data: value);
// ref.read(helloWorldProvider.notifier).update((state) => data);
// print("Đã thực hiện xong");
// }
void _change() {
print("change");
final rawString = generateRandomString(5);
Data data = new Data(data: rawString);
ref.watch(helloWorldProvider.notifier).update((state) => data);
print(ref.read(helloWorldProvider.notifier).state?.data);
}
String generateRandomString(int len) {
var r = Random();
return String.fromCharCodes(List.generate(len, (index) => r.nextInt(33) + 89));
}
#override
Widget build(BuildContext context) {
print('Rebuild');
final data = ref.watch(helloWorldProvider.notifier).state;
final dataText = data?.data ?? 'No text';
print(dataText);
return MaterialApp(
title: 'Google Docs Clone',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Center(
child: Column(children: [
Text(dataText)
]
)
),
floatingActionButton: FloatingActionButton(
onPressed: _change,
tooltip: 'Change',
child: const Icon(Icons.add),
),
));
}
}
I don't want to use other pattern as Provider, Bloc, StateNotifierProvider, ChangeNotifierProvider... I only want to run StateProvider successfully. I have refered to many articles and stackoverflows answer but I did't found any useful helps to my case.
final data = ref.watch(helloWorldProvider.notifier).state;
is watching the notifier, which rarely changes. You want to watch the state change, as in:
final data = ref.watch(helloWorldProvider);
Fixed, Tested your code.
I recommend this article Flutter Riverpod 2.0: The Ultimate Guide to Advanced Riverpod 😀
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'dart:math';
void main() {
runApp(const ProviderScope(child: MyApp()));
}
class Data {
final String data;
Data({required this.data});
}
final helloWorldProvider = StateProvider<Data?>((ref) => Data(data: 'No data'));
class MyApp extends ConsumerStatefulWidget {
const MyApp({super.key});
#override
ConsumerState<MyApp> createState() => _MyAppState();
}
class _MyAppState extends ConsumerState<MyApp> {
#override
void initState() {
// TODO: implement initState4
print("Init state");
super.initState();
// getData();
}
// getData() async {
// // http.Response response = await http.get(Uri.parse('https://jsonplaceholder.typicode.com/todos/1'));
// // final title = jsonDecode(response.body)["title"];;
// // ref.read(helloWorldProvider.notifier).update((state) => title);
// SharedPreferences prefs = await SharedPreferences.getInstance();
// prefs.setString('valueTemp', 'newValue');
// String? valueTemp = prefs.getString('valueTemp');
// String value = valueTemp ?? '';
// Data data = Data(data: value);
// ref.read(helloWorldProvider.notifier).update((state) => data);
// print("Đã thực hiện xong");
// }
void _change() {
print("change");
final rawString = generateRandomString(5);
Data data = Data(data: rawString);
ref.read(helloWorldProvider.notifier).update((state) => data);
print(ref.read(helloWorldProvider.notifier).state?.data);
}
String generateRandomString(int len) {
var r = Random();
return String.fromCharCodes(
List.generate(len, (index) => r.nextInt(33) + 89));
}
#override
Widget build(BuildContext context) {
print('Rebuild');
final data = ref.watch(helloWorldProvider)?.data;
final dataText = data ?? 'No text';
print(dataText);
return MaterialApp(
title: 'Google Docs Clone',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
body: Center(
child: Column(children: [Text(dataText)]),
),
floatingActionButton: FloatingActionButton(
onPressed: _change,
tooltip: 'Change',
child: const Icon(Icons.add),
),
),
);
}
}
Related
I am learning how to use the SharedPreferences library in Flutter.
I created this code and I would like the counter and counter2 variables once I close and reopen the app to remain as the last save.
However, when I reopen the app the counter and counter2 values return to 0.
Can anyone explain to me where I am going wrong?
Thank you.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'data.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
#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> {
int counter = 0;
int counter2 = 0;
increment() {
setState(() {
counter += 1;
counter2 += 2;
});
}
loadData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
String? json = prefs.getString('UserData');
print('loaded json: $json');
if (json == null) {
print('NO DATA (null)');
} else {
Map<String, dynamic> map = jsonDecode(json);
print('map $map');
final data = Data.fromJson(map);
print('Data ${data.counter}, ${data.counter2}');
}
});
}
saveData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final _data = Data(counter: counter, counter2: counter2);
String json = jsonEncode(_data);
print('saved json: $json');
prefs.setString('UserData', json);
}
clearData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.clear();
print('data cleared');
}
/// dichiarare l' initState()
#override
void initState() {
super.initState();
loadData();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'You have pushed the button this many times:',
),
Text(
'c: $counter, c2: $counter2',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
increment();
saveData();
},
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class Data {
int counter = 0;
int counter2 = 0;
Data({required this.counter, required this.counter2});
Map<String, dynamic> toJson() {
return {
'counter': counter,
'counter2': counter2,
};
}
Data.fromJson(Map<String, dynamic> json) {
counter = json['counter'];
counter2 = json['counter2'];
}
}
I agree with the other answer, the best is to use a FutureBuilder. But you can make your current code work with simply adding two lines at the end of loadData:
loadData() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
String? json = prefs.getString('UserData');
print('loaded json: $json');
if (json == null) {
print('NO DATA (null)');
} else {
Map<String, dynamic> map = jsonDecode(json);
print('map $map');
final data = Data.fromJson(map);
print('Data ${data.counter}, ${data.counter2}');
// add these lines
counter = data.counter;
counter2 = data.counter2;
}
});
}
What happens (as the other answer says) is that your widget is first built without knowing the values from SharedPreferences. After a little time this first build is done, the loadData future completes, and with setState the widget is rebuilt.
In a real application you'd like to avoid unnecessary builds, so you'd rather display a progress indicator while async data is being loaded, check FutureBuilder.
A short answer is that when you call loadData(); inside initState the function is performed asynchronously relative to the rest of the widget, so your Scaffold is built before the data is available. This is why you are seeing the data in from your print but not in the app.
One way to address it is to us a https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
I want to use a variable, which i want to fill with firebase data.
In the Firebase section it fills it up with the correct data and print it correctly to log, but after that in the Scaffold its looks like it using the data in the starting declaration.
But why? It's one variable with two data? So at the end of the code in the Text('$masik') i want to use the firebase data, not the starting string.
What am i doing wrong?
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String masik = '';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase',
home: AddData(),
);
}
}
class AddData extends StatelessWidget {
#override
Widget build(BuildContext context) {
String doksi = 'valami más';
var ezlett;
String masik = 'minden';
String sajt = '';
final Stream<QuerySnapshot> collectionStream = FirebaseFirestore.instance.collection('zenek').snapshots();
FirebaseFirestore.instance
.collection('zenek')
.doc(doksi)
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
String ezegyszoveg = documentSnapshot.data().toString();
print('Document exists on the database $ezegyszoveg');
ezlett = ezegyszoveg.substring(9, ezegyszoveg.indexOf(','));
print(ezlett);
masik = ezegyszoveg.substring(ezegyszoveg.indexOf('text: ')+6, ezegyszoveg.indexOf('}'));
print(masik);
}
});
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: const Text("próba"),
),
body:Row(
children: [
Text('$masik'),
],
)
);
}
}
Something like this example will work to update the UI when there is new data has been updated
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String masik = '';
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Firebase',
home: AddData(),
);
}
}
class AddData extends StatefulWidget {
#override
State<AddData> createState() => _AddDataState();
}
class _AddDataState extends State<AddData> {
String doksi = 'valami más';
var ezlett;
String masik = 'minden';
String sajt = '';
#override
void initState() {
super.initState();
updateTheUi();
}
void updateTheUi() {
final Stream<QuerySnapshot> collectionStream =
FirebaseFirestore.instance.collection('zenek').snapshots();
FirebaseFirestore.instance
.collection('zenek')
.doc(doksi)
.get()
.then((DocumentSnapshot documentSnapshot) {
if (documentSnapshot.exists) {
String ezegyszoveg = documentSnapshot.data().toString();
ezlett = ezegyszoveg.substring(9, ezegyszoveg.indexOf(','));
masik = ezegyszoveg.substring(
ezegyszoveg.indexOf('text: ') + 6, ezegyszoveg.indexOf('}'));
setState(() {});
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.green,
title: const Text("próba"),
),
body: Row(
children: [
Text('$masik'),
],
));
}
}
hey u r doing a silly mistake u have to use setState when u update your variable :
setState(){
masik = ezegyszoveg.substring(ezegyszoveg.indexOf('text: ')+6,ezegyszoveg.indexOf('}'));
} // this line put in setState in your code
First I created the GetxController class
final languageController = GetStorage();
var myLocal = [];
void saveLocale(List list) {
languageController.write('savedLocale', list);
}
#override
void onInit() {
List<dynamic>? savedLocale = languageController.read('savedLocale');
if (savedLocale != null) {
myLocal = savedLocale;
}
super.onInit();
}
}
Then I initialized GetStorage in main.dart
final myLocal = LanguageController().myLocal;
void main() async {
print(myLocal);
await GetStorage.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
translations: LocaleString(),
locale: myLocal.isNotEmpty
? Locale(myLocal[0], myLocal[1])
: Locale('en', 'US'),
debugShowCheckedModeBanner: false,
home: HomeScreen(),
);
}
}
And then in the dialog after setting the locale I writes it in storage
Future<dynamic> myMaterialDialog(BuildContext context) {
final LanguageController languageController = Get.find();
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text(chooseLanguage.tr),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: () {
Get.back();
Get.updateLocale(Locale('en', 'US'));
languageController.saveLocale(['en', 'US']);
},
child: Text(englishLanguage.tr),
),
TextButton(
onPressed: () {
Get.back();
Get.updateLocale(Locale('ru', 'RU'));
languageController.saveLocale(['ru', 'RU']);
},
child: Text(russianLanguage.tr),
),
],
),
);
});
}
And it's not working, every time I restarted my app it's shows 1 what myLocale is empty
To check if saveLocale() method is working, I created printSavedLocale() method
void printSavedLocale() {
print(languageController.read('savedLocale'));
}
and put it to dialoge button after saveLocale() and it's printing my saved locale, but after restarting saved locale is null
use this static methods. put them anywhere in your project:
void setData(String key, dynamic value) => GetStorage().write(key, value);
int? getInt(String key) => GetStorage().read(key);
String? getString(String key) => GetStorage().read(key);
bool? getBool(String key) => GetStorage().read(key);
double? getDouble(String key) => GetStorage().read(key);
dynamic getData(String key) => GetStorage().read(key);
void clearData() async => GetStorage().erase();
I can solove this by reading from the storage directly from main.dart
final LanguageController languageController = Get.put(LanguageController());
final myLocal = LanguageController().readSavedLocale();
void main() async {
await GetStorage.init();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return GetMaterialApp(
translations: LocaleString(),
locale: myLocal.isNotEmpty
? Locale(myLocal[0], myLocal[1])
: Locale('en', 'US'),
debugShowCheckedModeBanner: false,
home: HomeScreen(),
);
}
}
And readSavedLocale() method is
List readSavedLocale() {
var savedLocale = languageController.read('savedLocale');
return savedLocale;
}
if you still needs this , I use my app differently but I just made it work he it my main file (minus what you don' need)
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await GetStorage.init();
await firebaseInitialization.then((value) {
Get.put(HomeController());
});
runApp(Start());
}
class Start extends StatelessWidget {
Start({
Key? key,
}) : super(key: key);
final storage = GetStorage();
#override
Widget build(BuildContext context) {
Get.put(HomeController());
print(storage.read('langCode'));
print(storage.read('countryCode'));
return GetMaterialApp(
translations: LocaleString(),
fallbackLocale: const Locale('en', 'US'),
locale: storage.read('langCode') != null
? Locale(storage.read('langCode'), storage.read('countryCode'))
: const Locale('ar', 'MA'),
title: 'title'.tr,
}));
}
}
i have a button on my drawer that switches between arabic and english, you can put it wherever you want, you just need to have the widget
class Page extends GetView<HomeController>
which gives you the value 'controller' to represent the controller responsible for the language.
and this is the button responsible for the switch:
SizedBox(
height: 70,
child: OutlinedButton(
child: ListTile(
title: Text(
'language'.tr,
style: Theme.of(context).textTheme.headline6,
textDirection: TextDirection.rtl,
),
leading: const Icon(Icons.language),
),
onPressed: () {
controller.switchLang();
},
)),
and here is my homeController which is responsible for the locale:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
class HomeController extends GetxController {
static HomeController instance = Get.find();
final storage = GetStorage();
var ar = const Locale('ar', 'MA');
var us = const Locale('en', 'US');
switchLang() {
if (Get.locale == us) {
Get.updateLocale(ar);
storage.write('langCode', 'ar');
storage.write('countryCode', 'MA');
} else {
Get.updateLocale(us);
storage.write('langCode', 'en');
storage.write('countryCode', 'US');
}
update();
}
}
in your case if you have multiple locales , just change my switchlang function to handle multiple locales, you can do that easily with a switch case
I tried for the first time using Stream builder with HTTP requests. it is not updating data.
find below my code. Thanks for helping me!
///////////////////////////////////////// ////////////////////////////////// /////////////// //////////////////// ///////////////////// //////////////////// ///////////////////////////
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner:false,
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({ Key? key }) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: StreamBuilder(
stream: listMarkers,
builder: (BuildContext context,AsyncSnapshot<List<Coordonnees>> snapshot){
switch (snapshot.connectionState){
case ConnectionState.none:
// TODO: Handle this case.
// break;
case ConnectionState.waiting:
// TODO: Handle this case.
// break;
case ConnectionState.active:
return Center(child:CircularProgressIndicator());
// break;
case ConnectionState.done:
List<Coordonnees>? mark=snapshot.data;
return Center(
child:Text('latitude: ${mark![0].latitude}',
style: TextStyle(
fontSize: 30,
)
),
);
// break;
}
},
),
);
}
List<Coordonnees> marqueurs=[];
Future<List<Coordonnees>> UpdateMarkers(String id) async{
Map data = {
'idligne': id,
};
final response = await http.post(
Uri.parse("https://www.sirius-iot.eu/Dev/ESI/qitari2021/sarah.php?lignegps"),
body: data);
Map<String,dynamic> map=json.decode(response.body);
List<dynamic> dataa = map['lignegps'];
marqueurs.clear();
for(var i in dataa)
{
Coordonnees crd=Coordonnees(double.parse(i['latitude']),double.parse(i['longitude']),double.parse(i['vitesse']));
marqueurs.add(crd);
}
return marqueurs;
}
Stream<List<Coordonnees>> get listMarkers async*{
String id='1';
yield await UpdateMarkers(id) ;
}
}
class Coordonnees{
double latitude;
double longitude;
double vitesse;
Coordonnees(this.latitude,this.longitude,this.vitesse);
}
You can try .asStream() instead of manually yielding data which is awaited.
void main() {
listMarkers.listen((coordinates) {
print(coordinates);
});
}
class Coordinates {
int x;
int y;
Coordinates(this.x, this.y);
}
Future<List<Coordinates>> updateMarkers(String id) async{
await Future.delayed(Duration(seconds: 2));
return [
Coordinates(1,2)
];
}
Stream<List<Coordinates>> get listMarkers => updateMarkers('1').asStream();
Notice how elegant Stream<List<Coordinates>> get listMarkers => updateMarkers('1').asStream(); is as compared to what you are doing. And hopefully it will solve your issue too.
My code is:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:testing/test.dart';
import 'package:quiver/time.dart';
import 'dimensions.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DateTime _currentdate = new DateTime.now();
Future<Null> _selectdate(BuildContext context, List date) async{
String sanitizeDateTime(DateTime dateTime) => "${dateTime.month}-${dateTime.day}";
final DateTime picked = await showDatePicker(
context: context,
initialDate: DateTime(_currentdate.year,_currentdate.month-1),
firstDate: DateTime(_currentdate.year,_currentdate.month-1),
lastDate: DateTime(_currentdate.year,_currentdate.month+2),
selectableDayPredicate: (DateTime val) //=> val.month == 8 ? false:true,
{
String santized = sanitizeDateTime(val);
return !date.contains(santized);
},
);
if(picked!=null&& picked!=_currentdate) {
setState(() {
_currentdate = picked;
});
}
}
List enabledata=[];
var res;
demo() async {
List availablity=[];
List daysinamonth=[];
List output=[];
print('hi');
res = await checkapt();
print(res);
for (var item in res.keys.toList()){
enablesdates.add(_currentdate.month.toString()+"-"+item);
}
}
#override
void initState() {
demo();
super.initState();
}
#override
Widget build(BuildContext context) {
Dimensions(context);
String dayonly = new DateFormat.d().format(_currentdate);
return Scaffold(
appBar: AppBar(
title: Text('Date: $dayonly'),
actions: <Widget>[
IconButton(
onPressed: () async {
await _selectdate(context,enabledata);
print('$dayonly');
print(res['$dayonly'];
for (var item in res['$dayonly']){
timings.addAll(item);
}
print(timings);
},
icon: Icon(Icons.calendar_today),
),
],
),
I'm trying to access the $dayonly as the selected date by user, but instead it is still showing the _currentdate in the print function. my json res data is in the form {16: {14: 1}, 26: {19: 1}, 04: {15: 1}, 12: {11: 1}} and i want the user to select a date and save the new selected date in $dayonly . i think the program executes before the setState works and gets the new selected date in $dateonly. For expample, currentdate is 8 and selected date is 12, still when i print the $dateonly or if i want to access my res value again using res['$dateonly'] it is showing 8. I want it to show the selected date 12.
I'm very new to flutter, What can i do to resolve the issue.
Check this out.
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:testing/test.dart';
import 'package:quiver/time.dart';
import 'dimensions.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
DateTime _currentdate = new DateTime.now();
Future<Null> _selectdate(BuildContext context, List date) async{
String sanitizeDateTime(DateTime dateTime) => "${dateTime.month}-${dateTime.day}";
final DateTime picked = await showDatePicker(
context: context,
initialDate: DateTime(_currentdate.year,_currentdate.month-1),
firstDate: DateTime(_currentdate.year,_currentdate.month-1),
lastDate: DateTime(_currentdate.year,_currentdate.month+2),
selectableDayPredicate: (DateTime val) //=> val.month == 8 ? false:true,
{
String santized = sanitizeDateTime(val);
return !date.contains(santized);
},
);
if(picked!=null&& picked!=_currentdate) {
setState(() {
_currentdate = picked;
});
}
}
List enabledata=[];
var res;
demo() async {
List availablity=[];
List daysinamonth=[];
List output=[];
print('hi');
res = await checkapt();
print(res);
for (var item in res.keys.toList()){
enablesdates.add(_currentdate.month.toString()+"-"+item);
}
}
#override
void initState() {
demo();
super.initState();
}
String dayonly = new DateFormat.d().format(_currentdate);
#override
Widget build(BuildContext context) {
Dimensions(context);
return Scaffold(
appBar: AppBar(
title: Text('Date: $dayonly'),
actions: <Widget>[
IconButton(
onPressed: () async {
await _selectdate(context,enabledata);
print('$dayonly');
print(res['$dayonly'];
for (var item in res['$dayonly']){
timings.addAll(item);
}
print(timings);
},
icon: Icon(Icons.calendar_today),
),
],
),