I created a model class for Provider. Which will fit the function of getting data from SharedPreferences
Future getDataPerson() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
id = prefs.getInt('id') ?? 000;
name = prefs.getString('name') ?? "Фамилия Имя Отчество";
phone = prefs.getString('phone') ?? "3231313";
email = prefs.getString('email') ?? "";
accessToken = prefs.getString('accessToken') ?? "нет токенааа";
_login = prefs.getString('login') ?? "нет логинааа";
_password = prefs.getString('password') ?? "нет пароляяя";
notifyListeners();
}
That's how I implement my Provider
body: MultiProvider(
providers: [
ChangeNotifierProvider<ApiClient>(create: (_)=>ApiClient()),
ChangeNotifierProvider<FinalModel>(create: (_)=>FinalModel()),
],
child: FinalScreenState(),
),
In initState, I call this function.
@override
void initState() {
super.initState();
finalModel = Provider.of<FinalModel>(context,listen: false);
getDataPerson();
}
Future getDataPerson() async{
return await finalModel.getDataPerson();
}
And in the code I get these variables and paste them into Text
idController.text = finalModel.getId.toString();
return Padding(padding: EdgeInsets.only(top: 15, bottom: 10,right: 1,left: 1),
child:Center(
child: TextField(
controller: idController,
))
);
However, only the values that I wrote in the code are inserted into the text. In this line it is "3231313"
prefs.getString('phone') ?? "3231313";
I tried calling the get Data Person function in different places in the code. In the build method itself.
The data I want to insert I take from json immediately after the user logs in using the button and receives a response from the api
var statusOne =await apiClient.signIn(_loginEmail1.text, _passwordParol1.text);
Map<String, dynamic> map = jsonDecode(rawJson);
bool status = map['status'];
if (status == true) {
//Entry in SharedPreferences
setDataPerson();
//The screen on which the data is displayed
Navigator.pushReplacementNamed(context, 'final');}
method setDataPerson()
void setDataPerson() async {
final prefs = await SharedPreferences.getInstance();
var statusOne =
await apiClient.signIn(_loginEmail1.text, _passwordParol1.text);
var rawJson = AuthModel.fromJson(statusOne.data);
await prefs.setInt('id', rawJson.data!.performerId!);
await prefs.setString('name', rawJson.data!.fullName!);
await prefs.setString('phone', rawJson.data!.phone!);
await prefs.setString('accessToken', rawJson.data!.accessToken!);
}
Build method
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
IdWidget(),
NameWidget(),
PhoneWidget(),
EmailWidget(),
],
);
}
PhoneWidget
class PhoneWidget extends StatelessWidget {
Widget build(BuildContext context) {
var finalModel = Provider.of<FinalModel>(context,listen: true);
return Padding(padding: EdgeInsets.only(top: 10, bottom: 10,right:
1,left: 1),
child: Consumer<FinalModel>(
builder: (context, model, widget) {
finalModel.phoneController.text = model.phone;
return Center(
child: TextField(
controller: finalModel.phoneController,
enabled: false,
decoration: const InputDecoration(
labelText: "Телефон",
contentPadding: EdgeInsets.only(left: 10, top: 10, bottom: 10),
border: OutlineInputBorder(),
),
));
})
);
}
}
However, even if you do not receive this data from the network and just write a regular string, the data will not have time to be displayed on the screen.
It's worth noting here that when I restart the screen. And that is, I update the initState and build method. Then the data is updated and immediately displayed on the screen I am not considering inserting the listen:true parameter into provider, , because the getData Person function will be called too often.
CodePudding user response:
Wrap Consumer
widget to your Column
widget so registered listeners will be called.
Widget IdWidget() {
return Consumer<YourModelClass>(
builder: (context, model, widget) => Padding(
padding: EdgeInsets.only(top: 15, bottom: 10, right: 1, left: 1),
child: Center(
child: TextField(
controller: model.id,
))));
}