I uploaded 3 pages of related code here. My problem is this: I press the Pick Country
button and select a country, but I can't display my screen the phoneCode
parameter of the country I selected.
I'm working with flutter_riverpod package and my class type is ConsumerWidget. So,I can't use the setState() command for this class.
I added a debugPrint to my void pickCountry()
function. In this way, when I press the Pick Country button, I can see that the relevant value changes in the Debug Console section.
My problem is that this value does not change on the screen.
final phoneControllerProvider =
StateProvider<TextEditingController>((ref) => TextEditingController());
final countryProvider = StateProvider<Country?>((ref) => null);
class CountryCodeAndTextField extends ConsumerWidget {
const CountryCodeAndTextField({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final phoneController = ref.watch(phoneControllerProvider.notifier);
final Country? country = ref.watch(countryProvider.notifier).state;
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
if (country != null)
Text(
'+${country.phoneCode}', // The part that needs to be updated according to the country I have selected.
style: const TextStyle(color: Colors.white),
)
else
const Text(
'00',
style: TextStyle(color: Colors.white),
),
SizedBox(
width: ScreenSize.getWidth(context) * 0.6,
child: TextField(
controller: phoneController.state,
decoration: const InputDecoration(
hintText: 'Enter your phone number',
hintStyle: TextStyle(color: Colors.grey),
),
),
),
],
);
}
}
class LoginPage extends ConsumerWidget {
const LoginPage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
Country? currentCountry = ref.read(countryProvider.notifier).state;
void pickCountry() {
showCountryPicker(
context: context,
onSelect: (Country selectedCountry) {
currentCountry = selectedCountry;
},
);
debugPrint('selected phone code: ${currentCountry?.phoneCode}');
}
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text(
'Enter your phone number',
style: TextStyle(
color: Colors.white,
),
),
),
body: Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text(
'Chattor will need to verify your phone number',
style: TextStyle(color: Colors.grey),
),
TextButton(
onPressed: pickCountry,
child: const Text(
'Pick Country',
style: TextStyle(color: Colors.amber),
),
),
const CountryCodeAndTextField(),
SizedBox(height: ScreenSize.getHeight(context) * 0.63),
SizedBox(
width: ScreenSize.getWidth(context) * 0.30,
height: ScreenSize.getHeight(context) * 0.07,
child: const NextButtonWidget(),
),
],
),
);
}
}
I think I need to use StateNotifierProvider instead of StateProvider to trigger the build method and change the screen in the flutter_riverpod package.
class CountryNotifier extends StateNotifier<Country?> {
CountryNotifier() : super(null);
void setCountry(Country newCountry) {
state = newCountry;
}
}
final countryProvider = StateNotifierProvider<CountryNotifier, Country?>((ref) {
return CountryNotifier();
});
void pickCountry() {
showCountryPicker(
context: context,
onSelect: (Country selectedCountry) {
ref.read(countryProvider.notifier).setCountry(selectedCountry);
},
);
}
After making these adjustments, my problem was solved.