I have a provider that sets a value for pin, but i cannot access its value from another screen, what i'm doing wrong? I have tried many ways to solve it but i cant make it work.
The widget where i set the pin value:
class PinDemo extends StatelessWidget {
const PinDemo({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (context) => PinValue(),
child: PinputExample(),
);
}
}
class PinputExample extends StatefulWidget {
const PinputExample({Key? key}) : super(key: key);
@override
State<PinputExample> createState() => _PinputExampleState();
}
class _PinputExampleState extends State<PinputExample> {
final pinController = TextEditingController();
final focusNode = FocusNode();
final formKey = GlobalKey<FormState>();
@override
void dispose() {
pinController.dispose();
focusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<PinValue>(
create: (_) => PinValue(),
child: Consumer<MyTheme>(builder: (context, myTheme, child) {
const focusedBorderColor = Color(0xFF9500c8);
const fillColor = Color.fromRGBO(243, 246, 249, 0);
var borderColor = myTheme.primaryColor;
return Form(
key: formKey,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Directionality(
textDirection: TextDirection.ltr,
child: Pinput(
controller: pinController,
focusNode: focusNode,
androidSmsAutofillMethod:
AndroidSmsAutofillMethod.smsUserConsentApi,
listenForMultipleSmsOnAndroid: true,
defaultPinTheme: defaultPinTheme,
validator: (value) {
return value == '222222' ? null : 'Pin is incorrect';
},
onCompleted: (pin) {
debugPrint('onCompleted: $pin');
Provider.of<PinValue>(context, listen: false).setPin(pin);
print(Provider.of<PinValue>(context, listen: false).pin);
//Where i set the value for pin. Here it prints normally
},
onChanged: (value) {
debugPrint('onChanged: $value');
},
cursor: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
margin: const EdgeInsets.only(bottom: 9),
width: 22,
height: 1,
color: focusedBorderColor,
),
],
),
errorPinTheme: defaultPinTheme.copyBorderWith(
border: Border.all(color: Colors.redAccent),
),
),
),
],
),
);
}));
}
}
The widget where i try to access the value of pin (but gets a empty string):
class TokenValidateScreen extends StatelessWidget {
const TokenValidateScreen({super.key});
@override
Widget build(BuildContext context) {
return Consumer<PinValue>(builder: (context, pinValue, child) {
return Scaffold(
body: Container(
child: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const SizedBox(
height: 40,
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const PinputExample(),
const SizedBox(height: 80),
ReusableButton(
text: "Validate",
onPressed: () {
print(pinValue.pin);
//Where i try to print the value and get the empty string
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) => TakePhotoScreen(),
),
);
},
),
const SizedBox(
height: 25,
),
Text("Reenviar token", style: CustomTextStyle.h2()),
Text(pinValue.pin, style: CustomTextStyle.h2())
],
),
],
),
),
),
);
});
}
}
PinValue class
import 'package:flutter/material.dart';
class PinValue with ChangeNotifier {
String _pin = '';
String get pin => _pin;
void setPin(String pin) {
_pin = pin;
notifyListeners();
}
}
According to examples that i see i cannot find what is wrong, can someone help me?
You don't need to create provider on PinputExample
.
Replace
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<PinValue>(
create: (_) => PinValue(),
child: Consumer<MyTheme>(builder: (context, myTheme, child) {
With
@override
Widget build(BuildContext context) {
return Consumer<MyTheme>(builder: (context, myTheme, child) {
You may wrap the MaterialApp with Provider and then use all over the app, for this case, you also need to remove PinDemo
's provider's create
. Just use consumer widget.
ChangeNotifierProvider<PinValue>(
create: (_) => PinValue(),
child: PinDemo()
Or you can pass provider value using route.