You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用flutter_html包传递并更新HTML值时界面显示$name而非输入内容的问题求助

嘿,我来帮你拆解这个问题,你遇到的$name占位符不替换成实际输入值的问题,主要有两个核心原因,咱们一步步解决:

问题根源

  1. const字符串锁死了插值:你把htmlData定义成了const常量,Dart里const字符串是编译期就固定死的,里面的$name会被当成纯文本,根本不会去读取你定义的name变量值。
  2. 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">&nbsp;</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">&nbsp;</td> 
</tr>
""";

然后在build里直接用data: htmlData即可。

这样修改后,点击播放按钮,输入的内容就会替换掉HTML里的$name占位符,界面也会跟着更新啦!

内容的提问来源于stack exchange,提问作者matti peterbull

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 18:07:40