使用flutter_html包传递并更新HTML值时界面显示$name而非输入内容的问题求助
嘿,我来帮你拆解这个问题,你遇到的$name占位符不替换成实际输入值的问题,主要有两个核心原因,咱们一步步解决:
问题根源
- const字符串锁死了插值:你把
htmlData定义成了const常量,Dart里const字符串是编译期就固定死的,里面的$name会被当成纯文本,根本不会去读取你定义的name变量值。 - HTML内容没跟着State更新:就算去掉const,如果HTML字符串不依赖
name这个State变量,调用setState后也不会重新生成新的HTML内容,界面自然不会刷新。
解决办法
第一步:去掉const,用Dart字符串插值生成HTML
把const htmlData改成普通字符串,用Dart的插值语法$name替换占位符,另外注意HTML的value属性最好加引号,避免解析异常。
第二步:让HTML内容随State动态生成
把htmlData的定义放在build方法里,这样每次setState触发重新build时,都会根据最新的name值生成新的HTML字符串,flutter_html就能渲染出最新内容了。
修改后的完整代码
void main() { runApp(MaterialApp( debugShowCheckedModeBanner: false, home: MyApp(), )); } class MyApp extends StatefulWidget { const MyApp({Key key}) : super(key: key); @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { TextEditingController folderController = TextEditingController(); var name = 'xyz'; @override Widget build(BuildContext context) { // 👇 移除const,用字符串插值生成动态HTML final htmlData = """ <tr> <td width="28%" align="right" valign="middle" class="labelfont">$name: </td> <td width="65%" align="left" valign="middle"> <input type="text" name="NAME" class="signuptextfield" value="$name" autocomplete="off"/> </td> <td width="7%" align="left" valign="middle"> </td> </tr> """; return Scaffold( appBar: AppBar( title: Text('Test App'), ), body: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ IconButton( onPressed: () { setState(() { name = folderController.text; }); }, icon: Icon( Icons.play_arrow, color: Colors.red, size: 60, )), TextFormField( // 注意:这里的mediumTextBoldStyle和AppColors需要你确保已定义 style: mediumTextBoldStyle(textColor: AppColors.mainFontColor), decoration: InputDecoration( hintText: 'FolderName', hintStyle: hintTextStyle(textColor: AppColors.hintFontColor), enabledBorder: const UnderlineInputBorder( borderSide: BorderSide(color: AppColors.hintFontColor), ), focusedBorder: const UnderlineInputBorder( borderSide: BorderSide(color: AppColors.mainFontColor), ), ), autovalidateMode: AutovalidateMode.onUserInteraction, controller: folderController, onChanged: (value) {}, ), Html( data: htmlData, style: { "table": Style( color: Colors.red, textAlign: TextAlign.center, backgroundColor: Colors.black, padding: EdgeInsets.all(15), margin: EdgeInsets.all(10), ), }, ), ]),), ); } }
额外优化建议
如果你觉得每次build都生成HTML字符串有点冗余,可以把HTML内容改成一个getter方法,代码会更清晰:
String get htmlData => """ <tr> <td width="28%" align="right" valign="middle" class="labelfont">$name: </td> <td width="65%" align="left" valign="middle"> <input type="text" name="NAME" class="signuptextfield" value="$name" autocomplete="off"/> </td> <td width="7%" align="left" valign="middle"> </td> </tr> """;
然后在build里直接用data: htmlData即可。
这样修改后,点击播放按钮,输入的内容就会替换掉HTML里的$name占位符,界面也会跟着更新啦!
内容的提问来源于stack exchange,提问作者matti peterbull
相关产品推荐
相关产品推荐

