using Shared preferences with a change notifier - flutter

I'm trying to understand how to use shared preferences with a change notifier. I've created a basic app and I want to save a bool and a string from the change notifier using shared preferences.
here is my main.dart:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => GlobalSettings1()),
ChangeNotifierProvider(create: (_) => SectionSettings1()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
initialRoute: '/seventh',
routes: {
'/': (context) => Page01(),
'/first': (context) => Page02(),
'/second': (context) => Page03(),
});
}
}
and here is page01
class _Page01State extends State<Page01> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
context.read<GlobalSettings1>().ToggleSwitch();
},
child: Container(
height: 30,
width: 80,
color: context.watch<GlobalSettings1>().toggleSwitch01
? Colors.green
: Colors.red,
),
),
SizedBox(
height: 20,
),
InkWell(
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) => Material(
color: Colors.transparent,
child: Buttons(
onTap: (val) {
context.read<GlobalSettings1>().StringToSave(val);
Navigator.pop(context);
},
),
),
);
},
child: Container(
height: 30,
width: 80,
child: Center(
child: Text(
context.watch()<GlobalSettings1>().stringToSave,
),
),
)),
],
),
);
}
}
and finally, here is my change notifier:
class Buttons extends StatelessWidget {
const Buttons({Key? key, required this.onTap}) : super(key: key);
final ValueChanged? onTap;
#override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
if (onTap != null) {
onTap!('Choice01');
}
},
child: Container(
height: 30,
width: 80,
child: Text('Choice01'),
)),
SizedBox(
height: 30,
),
InkWell(
onTap: () {
if (onTap != null) {
onTap!('Choice02');
}
},
child: Container(
height: 30,
width: 80,
child: Text('Choice02'),
)),
],
);
}
}
class GlobalSettings1 with ChangeNotifier {
bool _toggleSwitch01 = true;
String _stringToSave = 'Choice01';
final SharedPreferences prefs;
GlobalSettings1({required this.prefs});
bool get toggleSwitch01 => _toggleSwitch01;
String get stringToSave => _stringToSave;
void ToggleSwitch() {
_toggleSwitch01 = !_toggleSwitch01;
_setPrefItems();
notifyListeners();
}
void StringToSave(val) {
_stringToSave = val;
_setPrefItems();
notifyListeners();
}
void _setPrefItems() {
prefs.setBool('toggleSwitch01', _toggleSwitch01);
prefs.setString('stringToSave', _stringToSave);
notifyListeners();
}
void _getPrefItems() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
_stringToSave = prefs.getString('stringToSave') ?? '';
_toggleSwitch01 = prefs.getBool('autoUpdateVariables') ?? true;
notifyListeners();
}
bool getToggleSwitch01() {
_getPrefItems();
return _toggleSwitch01;
}
String getStringToSave() {
_getPrefItems();
return _stringToSave;
}
}
As you can see, there is a bool that is toggled in Page01 and a String that is displayed from a value that is generated and passed through from the buttons widget.
After looking at other tutorials on this matter, I think i have the change notifier set up correctly but am unsure about how to set up the main.dart and Page01 so that when the bool and String are set, they stay like that when the app is rebooted.
i'm currently getting an error in main.dart:
ChangeNotifierProvider(create: (_) => GlobalSettings1()),
asking me to add required argument prefs but i'm unsure what the code should be to go in the brackets.
thanks so much and any help would be greatly appreciated.

You need pass an instance of SharedPreferences to your GlobalSettings1, also change GlobalSettings1 to this:
class GlobalSettings1 with ChangeNotifier {
bool _toggleSwitch01 = true;
String _stringToSave = 'Choice01';
final SharedPreferences prefs;
GlobalSettings1({required this.prefs});
bool get toggleSwitch01 => _toggleSwitch01;
String get stringToSave => _stringToSave;
void ToggleSwitch() {
_toggleSwitch01 = !_toggleSwitch01;
_setPrefItems();
notifyListeners();
}
void StringToSave(val) {
_stringToSave = val;
_setPrefItems();
notifyListeners();
}
void _setPrefItems() {
prefs.setBool('toggleSwitch01', _toggleSwitch01);
prefs.setString('stringToSave', _stringToSave);
notifyListeners();
}
void _getPrefItems() { // <=== change this
_stringToSave = prefs.getString('stringToSave') ?? '';
_toggleSwitch01 = prefs.getBool('autoUpdateVariables') ?? true;
notifyListeners();
}
bool getToggleSwitch01() {
_getPrefItems();
return _toggleSwitch01;
}
String getStringToSave() {
_getPrefItems();
return _stringToSave;
}
}
then change your main to this:
void main() {
SharedPreferences prefs = await SharedPreferences.getInstance();
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => GlobalSettings1(prefs: prefs)),
ChangeNotifierProvider(create: (_) => SectionSettings1()),
],
child: MyApp(),
),
);
}

Currently, you are passing an instance on constructor.
GlobalSettings1({required this.prefs});
While it is SharedPreferences you can do get instance with
class GlobalSettings1 with ChangeNotifier {
bool _toggleSwitch01 = true;
String _stringToSave = 'Choice01';
GlobalSettings1();
......
void _setPrefItems() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setBool('toggleSwitch01', _toggleSwitch01);
prefs.setString('stringToSave', _stringToSave);
notifyListeners();
}

Related

Widget is not rebuilding when notifyListeners is called

i am trying to create a login page so that when i am logged-in, the Navigationrail Widget lets me access all its destinations. When logged off i can only access two pages.
I am using Provider in login.dart to triger a widget rebuild in main.dart .
here is the code.
login.dart
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:httptest/depand/XmlLogin.dart';
import 'package:httptest/main.dart';
void login(String userName, String passWord) async {
Response response;
Dio dio = Dio();
dio.interceptors.add(InterceptorsWrapper(
onResponse: (response, handler) {
var token = getToken.Transcribe(response.data);
LoginProvider obj = LoginProvider();
obj.providestate(true);
print(token);
print("logged in");
handler.next(response);
},
));
try {
//Http Post method
} catch (e) {
print(e);
}
}
class LoginProvider extends ChangeNotifier {
bool loginstate = false;
void providestate(bool val) {
loginstate = val;
print("loginstate changed to $loginstate");
notifyListeners();
}
}
main.dart
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
#override
State<MyHomePage> createState() => MyHomePageState();
}
class MyHomePageState extends State<MyHomePage> {
var selectedIndex = 0;
List<Widget> pages = [Page0(), Page1(), Page2(), Placeholder()];
#override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
return Scaffold(
body: Row(
children: [
SafeArea(
child: ChangeNotifierProvider<LoginProvider>(
create: (context) => LoginProvider(),
child: Builder(
builder: (context) {
return Consumer<LoginProvider>(
builder: (context, provider, child) {
return NavigationRail(
extended: constraints.maxWidth >= 600,
minExtendedWidth: 200,
destinations: [
NavigationRailDestination(),
NavigationRailDestination(),
NavigationRailDestination(),
NavigationRailDestination()
],
selectedIndex: selectedIndex,
onDestinationSelected: (value) {
if (provider.loginstate) {
setState(() {
selectedIndex = value;
});
print("On");
} else {
if (value == 0 || value == 3) {
setState(() {
selectedIndex = value;
});
print("OFF");
}
}
},
);
});
},
),
)),
Expanded(
child: Scaffold(
body: IndexedStack(
index: selectedIndex,
children: pages,
),
),
),
],
),
);
});
}
}
the login goes through but i Still cant access pages 1 and 2.
it prints out 'loginstate changed to True' from login.dart.
To ensure access place a provider in a widget tree something like this:
void main() {
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => LoginProvider()),
...
],
child: const MyApp(),
),
);
}
Then in child widgets access it using either Consumer to listen changes or Provider.of when just calling a method.
Consumer<LoginProvider>(
builder: (context, provider, child) {
...
},
)
Provider.of<LoginProvider>(context, listen: false).login(userName, passWord);
See Simple app state management for the full example.

stop closing showDialogue itself after 15 seconds

I am trying to display an information dialog when starting an application. After closing, another window appears asking for permission. I call it all in the initState function. It works, but I noticed that this first info dialog also closes on its own when 15 seconds have elapsed. How do I fix this? So that while the dialog is not closed by the user, the application will not be loaded further?
class _MyAppState extends State<MyApp> {
final keyIsFirstLoaded = 'is_first_loaded';
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) async {
final context = MyApp.navKey.currentState.overlay.context;
await showDialogIfFirstLoaded(context);
await initPlatformState();
});
}
showDialogIfFirstLoaded(BuildContext context, prefs) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstLoaded = prefs.getBool(keyIsFirstLoaded);
if (isFirstLoaded == null) {
return showDialog(
context: context,
builder: (BuildContext context) {
// return object of type Dialog
return new AlertDialog(
// title: new Text("title"),
content: new Text("//"),
actions: <Widget>[
new FlatButton(
child: new Text(".."),
onPressed: () {
Navigator.of(context).pop();
prefs.setBool(keyIsFirstLoaded, false);
},
),
],
);
},
);
}
}
initPlatformState() async {
print('Initializing...');
await BackgroundLocator.initialize();
print('Initialization done');
final _isRunning = await BackgroundLocator.isRegisterLocationUpdate();
setState(() {
isRunning = _isRunning;
});
onStart();
print('Running ${isRunning.toString()}');
}
#override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: [
// ... app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
navigatorKey:MyApp.navKey,
navigatorObservers: [
FirebaseAnalyticsObserver(analytics: analytics),
],
debugShowCheckedModeBanner: false,
title: '',
theme: ThemeData(),
home: new SplashScreen(),}
class SplashScreen extends StatefulWidget {
#override
_SplashScreenState createState() => new _SplashScreenState();
}
class _SplashScreenState extends State<SplashScreen> with SingleTickerProviderStateMixin {
Timer _timer;
bool _visible = true;
startTime() async {
_timer = Timer(new Duration(seconds: 5), navigationPage);
}
void navigationPage() {
Navigator.of(context).pushReplacementNamed('/home');
}
#override
void initState() {
_timer = Timer(Duration(seconds: 4),
() => setState(
() {
_visible = !_visible;
},
),
);
startTime();
super.initState();
}
#override
void dispose() {
_timer.cancel();
super.dispose();
}
#override
Widget build(BuildContext context) {
return new Stack(
children: <Widget>[
Container(
width: double.infinity,
child: Image.asset('images/bg.jpg',
fit: BoxFit.cover,
height: 1200,
),
),
Container(
width: double.infinity,
height: 1200,
color: Color.fromRGBO(0, 0, 0, 0.8),
),
Container(
alignment: Alignment.center,
child: Row(
children: <Widget>[
Expanded(
flex: 2,
child: Container(
child: Text(''),
),
),
],
),
),
],
);
}
}
This code displays an Alert dialogue if the user is new and after the button click, it will direct him to another dialogue.
I have tested the code and it doesn't close after 15 seconds. I'm still not sure what you're trying to accomplish but I hope this helps.
Init State
#override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) async {
await dialog1(context);
//await initPlatformState();
});
super.initState();
}
Alert Dialog 1
dialog1(BuildContext context)async{
SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstLoaded = prefs.getBool("keyIsFirstLoaded")??true;
if (isFirstLoaded) {
showDialog(
barrierDismissible: false, //disables user from dismissing the dialog by clicking out of the dialog
context: context, builder: (ctx) {
return AlertDialog(
title: Text("dialog 1"), content: Text("Content"), actions: [
TextButton(
child: new Text(".."),
onPressed: () async{
Navigator.pop(ctx);
await dialog2(context);
prefs.setBool("keyIsFirstLoaded", false);
},
),],);
},);
}else{
//not first time
}
}
Alert Dialog 2
void dialog2(BuildContext context)async{
print("dialog 2");
showDialog(context: context, builder: (context) {
return AlertDialog(title: Text("Dialog 2"),content: Text("permissions"),actions: [
TextButton(
child: new Text("close"),
onPressed: () async{
Navigator.pop(context);
//await dialog1(context); //uncomment if you want to go back to dialoge 1
},
),],);
},);
}
You can return a value from Navigator in the first dialog
Navigator.of(context).pop(true);
prefs.setBool(keyIsFirstLoaded, false);
Once it receive true, then only call the second method.
var value = await showDialogIfFirstLoaded(context);
if(value == true) {
await initPlatformState();
}

Riverpod not changing state

I am trying to use Riverpod for Flutter stage management.
I have created a class called UsuarioProvider:
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:shared_preferences/shared_preferences.dart';
class UsuarioProvider extends StateNotifier<String> {
UsuarioProvider(): super("No user");
void cambiarUsuario (String nuevo){
state = nuevo;
cambiarEmailUsuarioSP(nuevo);
}
cambiarEmailUsuarioSP(String nuevo) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
state =nuevo;
prefs.setString("email", nuevo);
}
recibirEmailSP() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
String emailActual = prefs.getString("email");
}
}
On main.dart I have declared the use of the riverpod provider as follows:
//riverpod USUARIO
final usuarioProvider = StateNotifierProvider<UsuarioProvider>((ref) {
return UsuarioProvider();
});
void cambiarUsuario(String nueva) {
context.read(usuarioProvider).cambiarUsuario(nueva);
}
Now I need to change the state for UsuarioProvider as follows:
...
cambiarUsuario(parsed['user']['email'].toString());
...
The value for parsed['user']['email'].toString() = 'mimail#gmail.com'
but then, trying to get the state for it:
child: Consumer(builder: (_, ScopedReader watch, __) {
var value = watch(usuarioProvider.state);
print("%%%%%%%%%%%%%%%%%%EMail en Home:"+value.toString());
if (value == "No user") {
value = 'NoClinic'.tr().toString();
}
return Text(
value.toString(),
style: TextStyle(
fontSize: 12.0,
),
);
}),
I am always getting 'No user', not 'mimail#gmail.com'
What am I doing wrong?
the provider file :
import 'package:riverpod/riverpod.dart';
final usuarioProvider = StateNotifierProvider<UsuarioProvider>((ref) {
return UsuarioProvider();
});
class UsuarioProvider extends StateNotifier<String> {
UsuarioProvider() : super("No user");
void cambiarUsuario(String nuevo) {
state = nuevo;
cambiarEmailUsuarioSP(nuevo);
}
cambiarEmailUsuarioSP(String nuevo) async {
await Future.delayed(Duration(seconds: 1));
// this isn't necessary and it will case aditional rebuilt
state = nuevo;
}
}
The screen :
class MyConsumerScreen extends StatelessWidget {
const MyConsumerScreen({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Consumer(
builder: (context, watch, child) {
var value = watch(usuarioProvider.state);
if (value == "No user") {
value = 'NoClinic';
}
return Text(value);
},
),
SizedBox(height: 50),
ElevatedButton(
onPressed: () {
context.read(usuarioProvider).cambiarUsuario("It work !");
},
child: Text("test"),
)
],
),
),
);
}
}
make sure the to add the provider scope :
void main() => runApp(ProviderScope(child: MyApp()));

how to make string as global variable in flutter

I was create SharedPreferences to save user loading in logon page. Then data of user will be save in SharedPreferences and move to main page. But my problem now in main page I need use this variable in different places in main page. But I cant do that.
I need to make variable of logindata can use in each places in main page I try to use in drawer to make logout. No I get error as:
Undefined name 'logindata'.
this is my code:
void initial() async {
logindata = await SharedPreferences.getInstance();
setState(() {
username = logindata.getString('username');
return username;
});
}
my full code:
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'addnewtopics.dart';
import 'DetilesOfMainPage.dart';
import 'loginpage.dart';
class MyApp extends StatelessWidget {
final String email;
MyApp({Key key, #required this.email}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('JSON ListView')
),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: <Widget>[
DrawerHeader(
child: Text('Drawer Header'),
decoration: BoxDecoration(
color: Colors.blue,
),
),
ListTile(
title: Text('Item 1'),
onTap: () {
logindata.setBool('login', true);// here I need to use It ========================
Navigator.pushReplacement(context,
new MaterialPageRoute(builder: (context) => LoginUser()));
Navigator.pop(context);
},
),
ListTile(
title: Text('Item 2'),
onTap: () {
// Navigator.pop(context);
},
),
],
),
),
body: JsonImageList(),
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(context, MaterialPageRoute(builder: (context) => UploadImageDemo()
),);
},
child: Icon(Icons.add),
),
));
}
}
class Flowerdata {
int id;
String flowerName;
String flowerImageURL;
Flowerdata({
this.id,
this.flowerName,
this.flowerImageURL
});
factory Flowerdata.fromJson(Map<String, dynamic> json) {
return Flowerdata(
id: json['id'],
flowerName: json['nametopics'],
flowerImageURL: json['image']
);
}
}
class JsonImageList extends StatefulWidget {
JsonImageListWidget createState() => JsonImageListWidget();
}
class JsonImageListWidget extends State {
SharedPreferences logindata;
String username;
#override
void initState() {
// TODO: implement initState
super.initState();
initial();
}
void initial() async {
logindata = await SharedPreferences.getInstance();
setState(() {
username = logindata.getString('username');
return username;
});
}
final String apiURL = 'http://xxxxxxxxx/getFlowersList.php';
Future<List<Flowerdata>> fetchFlowers() async {
var response = await http.get(apiURL);
if (response.statusCode == 200) {
final items = json.decode(response.body).cast<Map<String, dynamic>>();
List<Flowerdata> listOfFruits = items.map<Flowerdata>((json) {
return Flowerdata.fromJson(json);
}).toList();
return listOfFruits;
}
else {
throw Exception('Failed to load data from Server.');
}
}
getItemAndNavigate(String item, BuildContext context){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(itemHolder : item)
)
);
}
#override
Widget build(BuildContext context) {
return FutureBuilder<List<Flowerdata>>(
future: fetchFlowers(),
builder: (context, snapshot) {
if (!snapshot.hasData) return Center(
child: CircularProgressIndicator()
);
return ListView(
children: snapshot.data
.map((data) => Column(children: <Widget>[
GestureDetector(
onTap: ()=>{
getItemAndNavigate(data.flowerName, context)
},
child: Row(
children: [
Container(
width: 200,
height: 100,
margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.0),
child:
Image.network(data.flowerImageURL,
width: 200, height: 100, fit: BoxFit.cover,))),
Flexible(child:
Text(data.flowerName,
style: TextStyle(fontSize: 18)))
]),),
Divider(color: Colors.black),
],))
.toList(),
);
},
);
}
}
Anyone know how can make that?
You need var keyword, in your case you can directly use
var logindata = await SharedPreferences.getInstance();
You do not need to make it global, because SharedPreferences.getInstance() is Singleton
Every time you use var logindata = await SharedPreferences.getInstance(); will get the same instance
Also there is no performance issue when you call getInstance(), because it's cached, you can see source code snippet below
class SharedPreferences {
SharedPreferences._(this._preferenceCache);
...
static Future<SharedPreferences> getInstance() async {
if (_completer == null) {
_completer = Completer<SharedPreferences>();
try {
final Map<String, Object> preferencesMap =
await _getSharedPreferencesMap();
_completer.complete(SharedPreferences._(preferencesMap));
} on Exception catch (e) {
// If there's an error, explicitly return the future with an error.
// then set the completer to null so we can retry.
_completer.completeError(e);
final Future<SharedPreferences> sharedPrefsFuture = _completer.future;
_completer = null;
return sharedPrefsFuture;
}
}
return _completer.future;
When you declare a String outside of class and does not contain _ before variable name like _localString it become global
String globalString = ""; //global, import can be seen
String _localString = ""; //local and can only be seen in this file, import can not seen
void main() async{
var logindata = await SharedPreferences.getInstance();
runApp(MyApp());
}
You simply need to put your variable outside of any class or method. An example is to create a file globals.dart then put all your globals in it and import the file when you need.
Example
// globals.dart
String globalString;
int globalInt;
bool globalBool;
// in any other file
import 'globals.dart' as globals;
globals.globalString = "Global String";

problem putting progressDialog.shide () in flutter

I am new to flutter and I am having the following problem.
I am trying to use the progressDialog in in a listview, I make the query to my database, I extract the list and pass it to the listview, I am trying to use the progressDialog so when I start loading the list it will run and tell the user to wait, and when I finish loading the list then the progressDialog is hidden, so far it works for me by bringing me the list and the progressDialog is executed saying to wait, but when I put the progressDialog.hide where the loading of the list ends I this is not accepting that line of code (progressDialog .hidde)
image:
enter image description here
import 'dart:convert';
import 'package:fluterproyecto1/Modulos/DetalleUser.dart';
import 'package:flutter/material.dart';
import 'package:progress_dialog/progress_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
String username2 = '';
String profesion = '';
String name = '';
class MemberPage extends StatefulWidget {
MemberPage({Key key}) : super(key: key);
#override
_MemberPageState createState() => _MemberPageState();
}
class _MemberPageState extends State<MemberPage> {
Map data;
List userData;
ProgressDialog progressDialog;
String name = '';
Future getData() async {
http.Response response =
await http.get("http://masciudad.com.co/flutter/getdata.php");
data = json.decode(response.body);
//setState(() {
//progressDialog.show();
userData = data["data"];
//progressDialog.hide();
//});
}
#override
void initState() {
super.initState();
getData();
}
#override
Widget build(BuildContext context) {
progressDialog = ProgressDialog(context, type: ProgressDialogType.Normal);
progressDialog.style(message: 'Por favor espere...');
progressDialog.show();
setState(() {
obtenerPreferencias();
});
return Scaffold(
appBar: AppBar(
title: Text("Bienvenido $username2"),
),
body: ListView.builder(
itemCount: userData == null ? 0 : userData.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
Image.asset(
"assets/128.jpg",
width: 30.0,
height: 30.0,
),
//CircleAvatar(
///cuando la imagen es de interntet
//backgroundImage: NetworkImage(
// "https://s3.amazonaws.com/uifaces/faces/twitter/follettkyle/128.jpg"),
//),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
"${userData[index]["username"]} - ${userData[index]["profesion"]}",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w700,
),
),
)
],
),
),
onTap: () => Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new DetalleUser(name: userData[index]["username"]))),
);
},
),
//Navigator.of(context).push(MaterialPageRoute(
// builder: (BuildContext context) => MyHomePage()));
//Navigator.pushReplacementNamed(context, "/MyHomePage");
);
}
Future obtenerPreferencias() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
setState(() {
username2 = preferences.get("username2") ?? "";
profesion = preferences.get("profesion") ?? "";
});
}
Future destruirPreferencias() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.clear();
}
}
You can copy paste run full code below
You can use addPostFrameCallback and put logical in another function getRelatedData()
code snippet
void getRelatedData() async {
progressDialog = ProgressDialog(context, type: ProgressDialogType.Normal);
progressDialog.style(message: 'Por favor espere...');
progressDialog.show();
await getData();
await obtenerPreferencias();
progressDialog.hide();
}
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
getRelatedData();
});
}
working demo
full code
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:progress_dialog/progress_dialog.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
String username2 = '';
String profesion = '';
String name = '';
class MemberPage extends StatefulWidget {
MemberPage({Key key}) : super(key: key);
#override
_MemberPageState createState() => _MemberPageState();
}
class _MemberPageState extends State<MemberPage> {
Map data;
List userData;
ProgressDialog progressDialog;
String name = '';
Future getData() async {
http.Response response =
await http.get("http://masciudad.com.co/flutter/getdata.php");
data = json.decode(response.body);
//setState(() {
//progressDialog.show();
userData = data["data"];
print("getData Done");
//progressDialog.hide();
//});
}
void getRelatedData() async {
progressDialog = ProgressDialog(context, type: ProgressDialogType.Normal);
progressDialog.style(message: 'Por favor espere...');
progressDialog.show();
await getData();
await obtenerPreferencias();
progressDialog.hide();
}
#override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
getRelatedData();
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Bienvenido $username2"),
),
body: ListView.builder(
itemCount: userData == null ? 0 : userData.length,
itemBuilder: (BuildContext context, int index) {
return InkWell(
child: Padding(
padding: const EdgeInsets.all(10.0),
child: Row(
children: <Widget>[
Image.network(
"https://picsum.photos/250?image=9",
width: 30.0,
height: 30.0,
),
//CircleAvatar(
///cuando la imagen es de interntet
//backgroundImage: NetworkImage(
// "https://s3.amazonaws.com/uifaces/faces/twitter/follettkyle/128.jpg"),
//),
Padding(
padding: const EdgeInsets.all(10.0),
child: Text(
"${userData[index]["username"]} - ${userData[index]["profesion"]}",
style: TextStyle(
fontSize: 20.0,
fontWeight: FontWeight.w700,
),
),
)
],
),
),
onTap: () {
/*Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new DetalleUser(name: userData[index]["username"])));*/
});
},
),
//Navigator.of(context).push(MaterialPageRoute(
// builder: (BuildContext context) => MyHomePage()));
//Navigator.pushReplacementNamed(context, "/MyHomePage");
);
}
Future obtenerPreferencias() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
setState(() {
username2 = preferences.get("username2") ?? "";
profesion = preferences.get("profesion") ?? "";
});
}
Future destruirPreferencias() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.clear();
}
}
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: MemberPage(),
);
}
}
Dear #Yeimer I would suggest read documentation carefully
https://pub.dev/packages/progress_dialog
Add the Package this
dependencies:
progress_dialog: ^1.2.4
1
Initialize your ProgressDialog object
final ProgressDialog prDialog = ProgressDialog(context);
//For normal dialog
prDialog = ProgressDialog(context,type: ProgressDialogType.Normal, isDismissible: true/false, showLogs: true/false);
2 Showing the progress dialog
await pr.show();
3
Dismissing the progress dialog
prDialog.hide().then((isHidden) {
print(isHidden);
});
// or simply
await prDialog.hide();