in

A Flutter widget for rendering HTML and CSS as Flutter widgets


Screenshot 1 Screenshot 2 Screenshot 3
Another Screenshot of flutter_html Yet another Screenshot of flutter_html

here.

For a full example, see here.

Below, you will find brief descriptions of the parameters theHtml widget accepts and some code snippets to help you use this package.

here.

here for the full list.

To use this API, set the key as the tag of the HTML element you wish to provide a custom implementation for, and set the value to be a Style with your customizations.

here.

the source code for details on how these are implemented.

When setting customImageRenders, the package will prioritize the custom renders first, while the default ones are used as a fallback.

Note: Order is very important when you set customImageRenders. The more specific your ImageSourceMatcher, the higher up in the customImageRender list it should be.

RenderContext, and the DOM element as dom.Element. This type is used to define the widget that should be rendered when used in conjunction with an ImageSourceMatcher.

A typical usage might look like this:

ImageRender base64ImageRender() => (context, attributes, element) {
      final decodedImage = base64.decode(attributes["src"] != null ?
          attributes["src"].split("base64,")[1].trim() : "about:blank");
      return Image.memory(
        decodedImage,
      );
    };

The above example should be used with the base64UriMatcher() in the examples for ImageSourceMatcher.

Just like functions for ImageSourceMatcher, you can declare your own variables in the function itself:

ImageRender networkImageRender({
  Map<String, String> headers,
  double width,
  double height,
  Widget Function(String) altWidget,
}) =>
    (context, attributes, element) {
      return Image.network(
        attributes["src"] ?? "about:blank",
        headers: headers,
        width: width,
        height: height,
        frameBuilder: (ctx, child, frame, _) {
          if (frame == null) {
            return altWidget.call(attributes["alt"]) ??
                Text(attributes["alt"] ?? "",
                    style: context.style.generateTextStyle());
          }
          return child;
        },
      );
    };

Implementing these variables allows you to customize every last detail of how the widget is rendered.

Example Usages – customImageRender:

customImageRender can be used in two different ways:

  1. Overriding a default render:
Widget html = Html(
  data: """
  <img alt="Flutter" src="https://flutter.dev/assets/flutter-lockup-1caf6476beed76adec3c477586da54de6b552b2f42108ec5bc68dc63bae2df75.png" /><br />
  <img alt="Google" src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png" /><br />
  """,
  customImageRenders: {
    networkSourceMatcher(domains: ["flutter.dev"]):
        (context, attributes, element) {
      return FlutterLogo(size: 36);
    },
    networkSourceMatcher(): networkImageRender(
      headers: {"Custom-Header": "some-value"},
      altWidget: (alt) => Text(alt ?? ""),
      loadingWidget: () => Text("Loading..."),
    ),
            (attr, _) => attr["src"] != null && attr["src"]!.startsWith("/wiki"):
    networkImageRender(
            mapUrl: (url) => "https://upload.wikimedia.org" + url),
  },
);

Above, there are three custom networkSourceMatchers, which will be applied – in order – before the default implementations.

When an image with URL flutter.dev is detected, rather than displaying the image, the render will display the flutter logo. If the image is any other image, it keeps the default widget, but just sets the headers and the alt text in case that image happens to be broken. The final render handles relative paths by rewriting them, specifically prefixing them with a base url. Note that the customizations of the previous custom renders do not apply. For example, the headers that the second render would apply are not applied in this third render.

  1. Creating your own renders:
ImageSourceMatcher classAndIdMatcher({String classToMatch, String idToMatch}) => (attributes, element) =>
    attributes["class"] != null && attributes["id"] != null &&
    (attributes["class"]!.contains(classToMatch) ||
    attributes["id"]!.contains(idToMatch));

ImageRender classAndIdRender({String classToMatch, String idToMatch}) => (context, attributes, element) {
  if (attributes["class"] != null && attributes["class"]!.contains(classToMatch)) {
    return Image.asset(attributes["src"] ?? "about:blank");
  } else {
    return Image.network(
      attributes["src"] ?? "about:blank",
      semanticLabel: attributes["longdesc"] ?? "",
      width: attributes["width"],
      height: attributes["height"],
      color: context.style.color,
      frameBuilder: (ctx, child, frame, _) {
          if (frame == null) {
            return Text(attributes["alt"] ?? "", style: context.style.generateTextStyle());
          }
          return child;
        },
    ); 
  }
};

Widget html = Html(
  data: """
  <img alt="alt text" class="class1-class2" src="https://flutterawesome.com/a-flutter-widget-for-rendering-html-and-css-as-flutter-widgets/assets/flutter.png" /><br />
  <img alt="alt text 2" id='imageId' src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_92x30dp.png" /><br />
  """,
  customImageRenders: {
    classAndIdMatcher(classToMatch: "class1", idToMatch: "imageId"): classAndIdRender(classToMatch: "class1", idToMatch: "imageId")
  },
);

The above example has a matcher that checks for either a class or an id, and then returns two different widgets based on whether a class was matched or an id was matched.

The sky is the limit when using the custom image renders. You can make it as granular as you want, or as all-encompassing as you want, and you have full control of everything. Plus you get the package’s style parsing to use in your custom widgets, so your code looks neat and readable!

  1. flutter_svg package)
  2. Otherwise, just render an Image.network.

If the rendering of any of the above fails, the package will fall back to rendering the alt text of the image, if any.

Currently the package only considers the width, height, src, and alt text while rendering an image.

Note that there currently is no support for SVGs either in base64 format or asset format.

webview_flutter plugin.

When rendering iframes, the package considers the width, height, and sandbox attributes.

Sandbox controls the JavaScript mode of the webview – a value of null or allow-scripts will set javascriptMode: JavascriptMode.unrestricted, otherwise it will set javascriptMode: JavascriptMode.disabled.

You can set the navigationDelegate of the webview with the navigationDelegateForIframe property – see here for more details.

chewie_audio plugin.

The package considers the attributes controls, loop, src, autoplay, width, and muted when rendering the audio widget.

chewie plugin.

The package considers the attributes controls, loop, src, autoplay, poster, width, height, and muted when rendering the video widget.

flutter_svg plugin.

When rendering SVGs, the package takes the SVG data within the <svg> tag and passes it to flutter_svg. The width and height attributes are considered while rendering, if given.

flutter_math plugin.

When rendering MathML, the package takes the MathML data within the <math> tag and tries to parse it to Tex. Then, it will pass the parsed string to flutter_math.

Because this package is parsing MathML to Tex, it may not support some functionalities. The current list of supported tags can be found above, but some of these only have partial support at the moment.

If the parsing errors, you can use the onMathError API to catch the error and potentially fix it on your end – you can analyze the error and the parsed string, and finally return a new instance of Math.tex() with the corrected Tex string.

If you’d like to see more MathML features, feel free to create a PR or file a feature request!

flutter_math plugin.

Use a custom tag inside your HTML (an example could be <tex>), and place your raw Tex string inside.

Then, use the customRender parameter to add the widget to render Tex. It could look like this:

Widget htmlWidget = Html(
  data: r"""<tex>ihbarfrac{partial}{partial t}Psi(vec x,t) = -frac{hbar}{2m}nabla^2Psi(vec x,t)+ V(vec x)Psi(vec x,t)</tex>""",
  customRender: {
    "tex": (_, __, ___, element) => Math.tex(
      element.text,
      onErrorFallback: (FlutterMathException e) {
        //return your error widget here e.g.
        return Text(e.message);
      },
    ),
  }
);

flutter_layout_grid plugin.

When rendering table elements, the package tries to calculate the best fit for each element and size its cell accordingly. Rowspans and colspans are considered in this process, so cells that span across multiple rows and columns are rendered as expected. Heights are determined intrinsically to maintain an optimal aspect ratio for the cell.

Contribution Guide

Coming soon!

Meanwhile, PRs are always welcome

GitHub

View Github


Broadband Plans to Mitigate 4G Network Connectivity Issues Effect

SBI PO Prelims Result 2021 Out, Cut Off & Score Card