具有 IntrinsicHeight 的 Flutter Html

问题描述 投票:0回答:1

当我使用html时,我遇到了由IntrinsicHeight引起的问题。但是,如果我使用文本,它运行得很好。 html 表示它需要特定的高度(不能是动态的)。然而,我需要动态高度。

这是我的代码:

Widget getContent() {
    final textTheme = Theme.of(context).textTheme;
    return Container(
      child: ListView.separated(
        shrinkWrap: true,
        physics: NeverScrollableScrollPhysics(),
        itemBuilder: (context, index) {
          final item = dataReview[index];
          final comment = item['comment'];
          return Container(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Container(
                  padding: EdgeInsets.symmetric(vertical: 12.0),
                  child: Text(
                    item['name'],
                    style: textTheme.titleLarge?.copyWith(
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
                Text(
                  item['date'],
                  style: textTheme.bodyMedium?.copyWith(
                    color: Colors.grey,
                    fontWeight: FontWeight.bold,
                  ),
                ),
                SizedBox(height: 6.0),
                Row(
                  children: [
                    for (int i = 5; i > 0; i--) ...[
                      Container(
                        padding: EdgeInsets.symmetric(vertical: 2.0),
                        child: SvgPicture.asset(
                          iconStarSolid,
                          colorFilter: ColorFilter.mode(
                            i <= 5 - item['rating']
                                ? Colors.black12
                                : Colors.amber,
                            BlendMode.srcIn,
                          ),
                        ),
                      ),
                    ],
                  ],
                ),
                Container(
                  padding: EdgeInsets.symmetric(vertical: 6.0),
                  child: VisibilityWidget(
                    visible: item['review'] != null,
                    child: Container(
                      padding: EdgeInsets.only(bottom: 8.0),
                      child: Html(
                        data: '<html><head></head><body><p>"Very very bad."</p></body></html>',
                        style: {
                          'body': Style(
                            margin: Margins.zero,
                            lineHeight: LineHeight.number(1.3),
                          ),
                        },
                        shrinkWrap: true,
                      ),
                    ),
                  ),
                ),
                Visibility(
                  visible: comment != null,
                  replacement: Container(),
                  child: Container(
                    padding: EdgeInsets.only(bottom: 16.0),
                    child: ContainerShadow(
                      color: primaryColor.withOpacity(0.1),
                      paddingVertical: 16.0,
                      paddingHorizontal: 16.0,
                      child: IntrinsicHeight(
                        child: Row(
                          children: [
                            Container(
                              child: VerticalDivider(
                                color: primaryColor.withOpacity(0.2),
                                width: 1.0,
                                thickness: 2.0,
                              ),
                            ),
                            SizedBox(width: 16.0),
                            Expanded(
                              child: Column(
                                crossAxisAlignment: CrossAxisAlignment.start,
                                children: [
                                  Row(
                                    children: [
                                      Container(
                                        height: 35.0,
                                        child: FittedBox(
                                          child: CircleAvatar(
                                            backgroundImage: AssetImage(
                                              iconCharger,
                                            ),
                                          ),
                                        ),
                                      ),
                                      Container(
                                        padding: EdgeInsets.symmetric(
                                          horizontal: 12.0,
                                        ),
                                        child: Text(
                                          'Admin',
                                          style: textTheme.titleLarge?.copyWith(
                                            color: primaryColor,
                                            fontWeight: FontWeight.bold,
                                          ),
                                        ),
                                      )
                                    ],
                                  ),
                                  SizedBox(height: 8.0),
                                  Text(
                                    comment != null ? comment['date'] : '',
                                    style: textTheme.bodyMedium?.copyWith(
                                      color: Colors.grey,
                                      fontWeight: FontWeight.bold,
                                    ),
                                  ),
                                  SizedBox(height: 12.0),
                                  Container(
                                    child: child: Html(
                                      data: '<html><head><title>Page Title</title></head><body><h1>My First Heading</h1><p>My first paragraph.</p></body></html>',
                                      style: {
                                        'h5': Style(
                                          margin: Margins.zero,
                                          lineHeight: LineHeight.number(1.3),
                                        ),
                                      },
                                      shrinkWrap: true,
                                    ),                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          );
        },
        separatorBuilder: (context, index) {
          return Divider(
            height: 5.0,
            thickness: 1.5,
            color: Colors.black12,
          );
        },
        itemCount: dataReview.length,
      ),
    );
  }

return VisibilityWidget(
      visible: !loading,
      replacement: Padding(
        padding: EdgeInsets.symmetric(vertical: 70.0),
        child: AnimateLoadingWidget(),
      ),
      child: VisibilityWidget(
        visible: isShowRatingRecap,
        replacement: Container(
          child: EmptyWidget(
            image: placeholderWarning,
            description: 'Empty.',
          ),
        ),
        child: SingleChildScrollView(
          padding: EdgeInsets.all(16.0),
          child: Column(
            children: [
              getHeader(),
              getContent(),
            ],
          ),
        ),
      ),
    );

预期结果: 单击此处查看我的预期结果的图像

当我使用 IntrinsicHeight 时如何获得 html 的动态高度? 或者也许还有其他选择来实现我的目标(绘制垂直线并同时使用 html)?

android ios flutter mobile flutter-html
1个回答
0
投票

我为此构建了一个小部件,使用 InAppWebView 动态计算 HTML 的高度:

https://pub.dev/packages/flutter_inappwebview

您基本上将 html 内容包装在 div 中,并将观察者放入脚本标记中,如下所示:

<html lang="en">
    <meta name="viewport" content="width=device-width user-scalable=no zoom=1.1">
    <body>
    <div><div class="htmlWrapper container" id="_flutter_target_do_not_delete">${state.htmlContent}</div></div>
      <script>
        function outputsize() {
          console.log(document.getElementById("_flutter_target_do_not_delete").offsetHeight);
            window.postMessage('flutterTargetHeight', document.getElementById("_flutter_target_do_not_delete").offsetHeight);
        }
        new ResizeObserver(outputsize).observe(_flutter_target_do_not_delete)
        outputsize()
    </script>""";
在这种情况下,state.htmlContent 是我想要显示的 html(因此只有正文中的内容)。根据您的情况,您可以删除父标签(html、meta 等),以便您拥有有效的 html。

我的 InAppWebView 小部件如下所示:

InAppWebViewSettings( verticalScrollBarEnabled: false, transparentBackground: true, javaScriptEnabled: true, disableHorizontalScroll: false, supportZoom: false), onConsoleMessage: (controller, consoleMessage) { double? height = double.tryParse(consoleMessage.message); if (height != null) { context.read<FlexibleWebviewBloc>().add( FlexibleWebviewEventAdjustHeight( height: height + FlexibleWebview.additionalHeight)); } }, ),
将 javaScriptEnabled 设置为 true,在 onConsoleMessage 消息中您可以获取小部件的高度。由于我使用 Bloc 进行状态管理,我用计算出的高度触发了一个事件:

double? height = double.tryParse(consoleMessage.message); if (height != null) { context.read<FlexibleWebviewBloc>().add( FlexibleWebviewEventAdjustHeight( height: height + FlexibleWebview.additionalHeight)); }
我还必须在计算中添加一些额外的高度(在我的例子中设置为 28)。

© www.soinside.com 2019 - 2024. All rights reserved.