如何通过 useTextEditingController 使用 HookWidget
How to use HookWidget with useTextEditingController
我是 flutter 开发的新手,正在尝试了解 Riverpod。
我目前设法使以下登录表单与 StatefulWidget 一起使用。
基本上,如果两个字段都不为空,则按钮会启用,反之亦然。
这是它的当前代码。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Login Demo',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// ),
home: Scaffold(
body: Center(
child: SizedBox(
width: 400,
child: MyLoginPage2(),
),
),
),
);
}
}
class MyLoginPage extends StatefulWidget {
const MyLoginPage({Key? key}) : super(key: key);
@override
State<MyLoginPage> createState() => _MyLoginState();
}
class _MyLoginState extends State<MyLoginPage> {
final emailController = TextEditingController(text: '');
final passwordController = TextEditingController(text: '');
@override
void initState() {
super.initState();
emailController.addListener(() {
setState(() {});
});
passwordController.addListener(() {
setState(() {});
});
}
@override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: passwordController,
obscureText: true,
),
areFieldsEmpty()
? const ElevatedButton(
child: Text('Login disabled'),
onPressed: null,
)
: ElevatedButton(
child: const Text('Login enabled'),
onPressed: () => print("this is where login happens"),
)
],
);
}
bool areFieldsEmpty() {
return emailController.text.toString().isEmpty ||
passwordController.text.toString().isEmpty;
}
}
我不喜欢的是听众如何直接调用 setState
来触发小部件刷新。这是你如何完成这样的行为?
我阅读了很多关于 Riverpod 的文章,但我似乎不明白如何对从 HookWidget
而不是 StatefulWidget
继承的上述行为进行建模。具体来说,如何将监听器添加到文本编辑控制器。
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Login Demo',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// ),
home: Scaffold(
body: Center(
child: SizedBox(
width: 400,
child: MyLoginPage2(),
),
),
),
);
}
}
class MyLoginPage2 extends HookWidget {
final emailController = useTextEditingController(text: '');
final passwordController = useTextEditingController(text: '');
MyLoginPage2({Key? key}) : super(key: key);
// Pending questions
// 1. Where do I add the listeners to the controllers?
// 2. They are supposed to be auto dispose, right?
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: passwordController,
obscureText: true,
),
areFieldsEmpty()
? const ElevatedButton(
child: Text('Login disabled'),
onPressed: null,
)
: ElevatedButton(
child: const Text('Login enabled'),
onPressed: () => print("this is where login happens"),
)
],
);
}
bool areFieldsEmpty() {
return emailController.text.toString().isEmpty ||
passwordController.text.toString().isEmpty;
}
}
如有任何帮助或提示,我们将不胜感激。
要更新 HookWidget
上的更改,请使用 useEffect()。在创建自定义 hookWidget 之前,我们不必担心处置问题。
class MyLoginPage2 extends HookWidget {
const MyLoginPage2({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final emailController = useTextEditingController(text: '');
final passwordController = useTextEditingController(text: '');
final _areFieldsEmpty =
useState<bool>(true); // controll the button based on Text.isEmpty
bool areFieldsEmpty() {
return emailController.text.toString().isEmpty ||
passwordController.text.toString().isEmpty;
}
useEffect(() {
emailController.addListener(() {
_areFieldsEmpty.value = areFieldsEmpty();
});
passwordController.addListener(() {
_areFieldsEmpty.value = areFieldsEmpty();
});
}, [
emailController,
passwordController,
]);
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: passwordController,
obscureText: true,
),
_areFieldsEmpty.value
? const ElevatedButton(
child: Text('Login disabled'),
onPressed: null,
)
: ElevatedButton(
child: const Text('Login enabled'),
onPressed: () => print("this is where login happens"),
)
],
);
}
}
我是 flutter 开发的新手,正在尝试了解 Riverpod。
我目前设法使以下登录表单与 StatefulWidget 一起使用。 基本上,如果两个字段都不为空,则按钮会启用,反之亦然。
这是它的当前代码。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Login Demo',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// ),
home: Scaffold(
body: Center(
child: SizedBox(
width: 400,
child: MyLoginPage2(),
),
),
),
);
}
}
class MyLoginPage extends StatefulWidget {
const MyLoginPage({Key? key}) : super(key: key);
@override
State<MyLoginPage> createState() => _MyLoginState();
}
class _MyLoginState extends State<MyLoginPage> {
final emailController = TextEditingController(text: '');
final passwordController = TextEditingController(text: '');
@override
void initState() {
super.initState();
emailController.addListener(() {
setState(() {});
});
passwordController.addListener(() {
setState(() {});
});
}
@override
void dispose() {
emailController.dispose();
passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: passwordController,
obscureText: true,
),
areFieldsEmpty()
? const ElevatedButton(
child: Text('Login disabled'),
onPressed: null,
)
: ElevatedButton(
child: const Text('Login enabled'),
onPressed: () => print("this is where login happens"),
)
],
);
}
bool areFieldsEmpty() {
return emailController.text.toString().isEmpty ||
passwordController.text.toString().isEmpty;
}
}
我不喜欢的是听众如何直接调用 setState
来触发小部件刷新。这是你如何完成这样的行为?
我阅读了很多关于 Riverpod 的文章,但我似乎不明白如何对从 HookWidget
而不是 StatefulWidget
继承的上述行为进行建模。具体来说,如何将监听器添加到文本编辑控制器。
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Login Demo',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// ),
home: Scaffold(
body: Center(
child: SizedBox(
width: 400,
child: MyLoginPage2(),
),
),
),
);
}
}
class MyLoginPage2 extends HookWidget {
final emailController = useTextEditingController(text: '');
final passwordController = useTextEditingController(text: '');
MyLoginPage2({Key? key}) : super(key: key);
// Pending questions
// 1. Where do I add the listeners to the controllers?
// 2. They are supposed to be auto dispose, right?
@override
Widget build(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: passwordController,
obscureText: true,
),
areFieldsEmpty()
? const ElevatedButton(
child: Text('Login disabled'),
onPressed: null,
)
: ElevatedButton(
child: const Text('Login enabled'),
onPressed: () => print("this is where login happens"),
)
],
);
}
bool areFieldsEmpty() {
return emailController.text.toString().isEmpty ||
passwordController.text.toString().isEmpty;
}
}
如有任何帮助或提示,我们将不胜感激。
要更新 HookWidget
上的更改,请使用 useEffect()。在创建自定义 hookWidget 之前,我们不必担心处置问题。
class MyLoginPage2 extends HookWidget {
const MyLoginPage2({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final emailController = useTextEditingController(text: '');
final passwordController = useTextEditingController(text: '');
final _areFieldsEmpty =
useState<bool>(true); // controll the button based on Text.isEmpty
bool areFieldsEmpty() {
return emailController.text.toString().isEmpty ||
passwordController.text.toString().isEmpty;
}
useEffect(() {
emailController.addListener(() {
_areFieldsEmpty.value = areFieldsEmpty();
});
passwordController.addListener(() {
_areFieldsEmpty.value = areFieldsEmpty();
});
}, [
emailController,
passwordController,
]);
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: emailController,
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: passwordController,
obscureText: true,
),
_areFieldsEmpty.value
? const ElevatedButton(
child: Text('Login disabled'),
onPressed: null,
)
: ElevatedButton(
child: const Text('Login enabled'),
onPressed: () => print("this is where login happens"),
)
],
);
}
}