I have a ConsumerWidget
, which I'm using to watch the state of a provider. Anyways everything is working, besides my TextEditingControllers
. Whenever I type something into the text field and click the done button on the phone keyboard, the textfields goes empty again. I think this is due to the state of that widget. So my question is how do I use the TextEditingController
inside the ConsumerWidget
, which has no createState
method?
Here is my code. Thanks in advance:
class MainPage extends ConsumerWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context, ref) {
// provider
final roomListData = ref.watch(roomDataProvider);
final roomService = RoomService();
final roomIDController = TextEditingController();
final roomPasswordController = TextEditingController();
// UI screen size
final size = MediaQuery.of(context).size;
double deviceWidth = size.width;
double deviceHeight = size.height;
return Scaffold(
backgroundColor: bluePrimary,
body: SingleChildScrollView(
child: roomListData.when(
data: (data) {
List<RoomModelResponse> roomList =
data.map((room) => room).toList();
return SafeArea(
child: Container(
padding:
const EdgeInsets.symmetric(horizontal: 36, vertical: 16),
child: Column(
//crossAxisAlignment: CrossAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
IconButton(
iconSize: deviceWidth * 0.09,
icon: const Icon(Icons.person_outline,
color: orangePrimary),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const DetailedProfilePage()));
},
),
IconButton(
icon: const Icon(
Icons.add,
color: orangePrimary,
),
iconSize: deviceWidth * 0.09,
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const CreateRoomScreen()),
);
},
)
],
),
SizedBox(height: deviceHeight * 0.04),
Align(
alignment: Alignment.centerLeft,
child: Text("Join room",
style: TextStyle(
fontFamily: 'Chalet',
fontSize: deviceWidth * 0.05,
color: whitePrimary,
fontWeight: FontWeight.w100,
)),
),
SizedBox(height: deviceHeight * 0.008),
// room ID textField
SizedBox(
width: MediaQuery.of(context).size.width * 0.85,
child: TextField(
controller: roomIDController,
decoration: InputDecoration(
filled: true,
fillColor: whitePrimary,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none),
hintText: 'Enter room ID to join it',
hintStyle: const TextStyle(
color: Color.fromARGB(255, 174, 173, 173))),
),
),
SizedBox(height: deviceHeight * 0.01),
// room password textField
SizedBox(
width: MediaQuery.of(context).size.width * 0.85,
child: TextField(
obscureText: true,
controller: roomPasswordController,
decoration: InputDecoration(
filled: true,
fillColor: whitePrimary,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: BorderSide.none),
hintText:
'Leave blank if the room has no password',
hintStyle: const TextStyle(
color: Color.fromARGB(255, 174, 173, 173))),
),
),
...
You can also use hooks (flutter_hooks
package) and use HookConsumerWidget
. Then your code will be even shorter. You will also need a package hooks_riverpod
:
class MainPage extends HookConsumerWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context, ref) {
final roomListData = ref.watch(roomDataProvider);
final roomIDController = useTextEditingController();
final roomPasswordController = useTextEditingController();
return Scaffold(...);
}
}
Hooks take care of the lifecycle of objects themselves, so you don't have to manually dispose of them via the dispose
method.
Links: