Flutter开发BMI应用时result值无法在屏幕显示问题求助
Flutter BMI计算器result变量无法在屏幕显示的解决方案
问题现象
开发Flutter BMI计算器时,点击计算按钮后,result变量在setState中更新后无法在屏幕上显示对应内容,但通过print(result)能在终端正常输出计算结果或提示信息,逻辑计算流程正常。
问题原因
核心问题是**htController、wtController、result三个变量定义在build方法内部**:
- 每次调用
setState都会触发build方法重新执行,这三个变量会被重新初始化(比如result被重置为空字符串); - 终端打印的是
setState代码块中临时更新的result值,此时build还未重新执行,所以能看到正确值,但屏幕显示的是build重新执行后初始化的空值。
修复方案
将htController、wtController、result移到State类的成员变量位置,确保它们的生命周期与State对象一致,不会在每次build时被重置。同时,需要在dispose方法中释放TextEditingController资源,避免内存泄漏。
修复后的完整代码
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blueGrey, ), home: const MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key}); @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { // 移到State类作为成员变量 late TextEditingController htController; late TextEditingController wtController; String result = ""; @override void initState() { super.initState(); // 初始化控制器 htController = TextEditingController(); wtController = TextEditingController(); } @override void dispose() { // 释放控制器资源 htController.dispose(); wtController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( toolbarHeight: 150, elevation: 22, shadowColor: Colors.blueGrey, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( bottomRight: Radius.circular(40), bottomLeft: Radius.circular(40))), title: const Text( "BMI CALCULATOR", style: TextStyle( fontStyle: FontStyle.normal, fontWeight: FontWeight.w600, color: Colors.white), ), centerTitle: true, ), body: Center( child: SizedBox( width: 300, height: double.infinity, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( "BMI", style: TextStyle( fontSize: 30, fontWeight: FontWeight.bold, color: Colors.blueGrey), ), const Image( image: NetworkImage( 'https://play-lh.googleusercontent.com/dIrupb2X482l0AOv36KOG_sw1B91-r1SH76-ZZm9zgqmjd1NjbsUCQMLmEo1GpljQjg'), height: 100, width: 100, ), const SizedBox(height: 21), TextField( controller: htController, decoration: InputDecoration( hintText: ("Please enter your height in metre."), focusedBorder: OutlineInputBorder( borderSide: const BorderSide( color: Colors.orange, width: 2, ), borderRadius: BorderRadius.circular(9), ), prefixIcon: const Icon( Icons.height, color: Colors.deepOrange, ), ), keyboardType: TextInputType.number, ), const SizedBox( height: 15, ), TextField( controller: wtController, decoration: InputDecoration( hintText: ("Please enter your weight in kg."), focusedBorder: OutlineInputBorder( borderSide: const BorderSide( color: Colors.orange, width: 2, ), borderRadius: BorderRadius.circular(9), ), prefixIcon: const Icon( Icons.height, color: Colors.deepOrange, ), ), keyboardType: TextInputType.number, ), const SizedBox( height: 11, ), ElevatedButton( onPressed: () { var wt = wtController.text.toString(); var ht = htController.text.toString(); if (wt.isNotEmpty && ht.isNotEmpty) { // BMI Calculation var iwt = int.parse(wt); var iht = double.parse(ht); var bmi = iwt / (iht * iht); setState(() { result = "Your BMI is:-${bmi.toStringAsFixed(2)}"; }); } else { setState(() { result = "Please fill every entry first."; }); } }, child: const Text('Calculate'), ), Text( result, style: const TextStyle(fontSize: 30, fontWeight: FontWeight.w600), ), ], ), ), ), ); } }
额外优化:修复了空值判断(用isNotEmpty替代!= ""),并且将BMI结果保留两位小数(toStringAsFixed(2)),提升显示体验。
内容的提问来源于stack exchange,提问作者Sachin Kumar
相关产品推荐
相关产品推荐

