出于调试目的,我在构建方法中放置了一条打印语句,我注意到当点击 TextFormField 时,整个小部件正在重建多次。
键盘打开,然后立即关闭。
这是我的代码:
class LoginScreen extends StatelessWidget {
LoginScreen({super.key});
static Route<void> route() {
return MaterialPageRoute<void>(builder: (_) => LoginScreen());
}
final _emailController = TextEditingController();
final _passwordController = TextEditingController();
final _selectUrl = TextEditingController();
@override
Widget build(BuildContext context) {
if (!kReleaseMode) {
_emailController.text = '';
_passwordController.text = '';
_selectUrl.text = baseUrl;
}
return Scaffold(
body: Center(
child: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Align(
alignment: Alignment.center,
child: Padding(
padding: const EdgeInsets.fromLTRB(
20.0,
),
child: Image.asset(
'assets/images/logo.png',
color: isDarkMode(context)
? Theme.of(context).colorScheme.primary
: null,
),
),
),
TextFormField(
controller: _emailController,
decoration: const InputDecoration(
hintText: 'Enter your email',
),
),
TextFormField(
controller: _passwordController,
decoration: const InputDecoration(
hintText: 'Enter your password',
),
obscureText: true,
),
BlocConsumer<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
if (state is AuthenticationFailureState) {
_emailController.text = state.fields['email'] ?? '';
_passwordController.text = state.fields['password'] ?? '';
showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: const Text('Login failed'),
content: Text(
state.errorMessage,
textAlign: TextAlign.center,
),
icon: const Icon(
Icons.error,
color: Colors.red,
));
});
} else if (state is AuthenticationSuccessState) {
context
.read<CalendarDataBloc>()
.add(FetchCalendarEvents());
context.read<HomeBloc>().add(FetchCheckedInEvents());
Navigator.pushReplacementNamed(context, '/home');
}
},
builder: (context, state) {
return state is AuthenticationLoadingState &&
(state).isLoading
? const Center(
child: CircularProgressIndicator(),
)
: SizedBox(
child: FilledButton(
onPressed: () {
BlocProvider.of<AuthenticationBloc>(context)
.add(
LoginUser(
_emailController.text.trim(),
_passwordController.text.trim(),
),
);
},
child: const Text(
'Login',
style: TextStyle(
fontSize: 20,
),
),
),
);
},
),
],
),
),
),
),
);
}
}
检查 Bloc 状态更改如果您的 AuthenticationBloc 频繁发出新状态(例如 AuthenticationLoadingState),则可能会过于频繁地触发重建。