A Tricky Solution for Implementing Inline-Image-In-Text Feature in Flutter.

Overview

RealRichText

A Tricky Solution for Implementing Inline-Image-In-Text Feature in Flutter.

Getting Started

According to the related Flutter Issues(#2022) , Inline-Image-In-Text is a long-time(2 years) missing feature since RichText(or the underlying Paragraph) does only support pure text. But we can solve this problem in a simple/tricky way:

  1. Regard the images as a particular blank TextSpan, convert image's width and height to textspan's letterSpacing and fontSize. the origin paragraph will do the layout operation and leave the desired image space for us.
  2. Override the paint function,calculate the right offset via the getOffsetForCaret() api to draw the image over the space.

For more details, please refer to the source code.

Usage

The only thing you have to do is converting your origin text to a TextSpan/ImageSpan List first.

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:real_rich_text/real_rich_text.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Center(
          child: RealRichText([
            TextSpan(
              text: "A Text Link",
              style: TextStyle(color: Colors.red, fontSize: 14),
              recognizer: TapGestureRecognizer()
                ..onTap = () {
                  debugPrint("Link Clicked.");
                },
            ),
            ImageSpan(
              AssetImage("packages/real_rich_text/images/emoji_9.png"),
              imageWidth: 24,
              imageHeight: 24,
            ),
            ImageSpan(AssetImage("packages/real_rich_text/images/emoji_10.png"),
                imageWidth: 24,
                imageHeight: 24,
                margin: EdgeInsets.symmetric(horizontal: 10)),
            TextSpan(
              text: "哈哈哈",
              style: TextStyle(color: Colors.yellow, fontSize: 14),
            ),
            TextSpan(
              text: "@Somebody",
              style: TextStyle(
                  color: Colors.black,
                  fontSize: 14,
                  fontWeight: FontWeight.bold),
              recognizer: TapGestureRecognizer()
                ..onTap = () {
                  debugPrint("Link Clicked");
                },
            ),
            TextSpan(
              text: " #RealRichText# ",
              style: TextStyle(color: Colors.blue, fontSize: 14),
              recognizer: TapGestureRecognizer()
                ..onTap = () {
                  debugPrint("Link Clicked");
                },
            ),
            TextSpan(
              text: "showing a bigger image",
              style: TextStyle(color: Colors.black, fontSize: 14),
            ),
            ImageSpan(AssetImage("packages/real_rich_text/images/emoji_10.png"),
                imageWidth: 24,
                imageHeight: 24,
                margin: EdgeInsets.symmetric(horizontal: 5)),
            TextSpan(
              text: "and seems working perfect……",
              style: TextStyle(color: Colors.black, fontSize: 14),
            ),
          ]),
        ),
      ),
    );
  }
}

Note

ImageSpan must set the width & height properties.

if your image's width or height is not specific, you can wrap two RealRichText in a StatefulWidget, one for showing placeholder image and the other for showing the actual image when it is ready.

Comments
  • flutter 1.7.8报错

    flutter 1.7.8报错

    void _handleImageChanged(ImageInfo imageInfo, bool synchronousCall) {
        image = imageInfo.image;
        _listener?.call(imageInfo, synchronousCall);
      }
    
    opened by shunFSKi 2
  • TextSpan -> fontsize bug?

    TextSpan -> fontsize bug?

    if the fontsize > 58, the text will disappear.

    import 'package:flutter/material.dart';
    import './plugin/rich_text.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: const Text('Plugin example app'),
            ),
            body: Center(
              child: RealRichText([
                TextSpan(
                  text: "😀",
                  style: TextStyle(color: Colors.red, fontSize: 60),
                ),
              ]),
            ),
          ),
        );
      }
    }
    
    
    opened by BeanWei 1
  • extract imagespan out of nested children to be displayable

    extract imagespan out of nested children to be displayable

    A valuable feature of textspan is it can be nested with children. However, this implementation of RealRichText only supports displaying the immediate children of the root textspan such that the nested imagespan will only show blank placeholders. Therefore, through this commit, a method is added to expand all nested children into the children list of the root textspan to make the children imagespan rendered correctly.

    opened by OnTheThirdDay 0
  • Method not found: 'ImageStreamListener'

    Method not found: 'ImageStreamListener'

    Error: Method not found: 'ImageStreamListener'. oldImageStream?.removeListener(ImageStreamListener(_handleImageChanged));

    real_rich_text: git: https://github.com/bytedance/RealRichText.git

    opened by ENUUI 0
  • Wrong ImageSpan position

    Wrong ImageSpan position

    image

    import 'package:flutter/gestures.dart';
    import 'package:flutter/material.dart';
    import 'package:real_rich_text/real_rich_text.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: const Text('Plugin example app'),
            ),
            body: Center(
              child: RealRichText([
                TextSpan(
                  text: "【7.9隔夜大消息】 1、 降息预期降低,美股三大股指周一集体收跌,道指跌0.43%;纳指跌0.78%;标普500指数跌0.48%。中概股普跌,诺亚财富跌20.41%; 2、 诺亚财富大跌逾20% ,旗下歌斐资产34亿元踩雷承兴国际控股; 3、 格力电器:认购新疆众和非公开发行股票, 将成第三大股东; 4、 上交所:上半年沪市公司披露各类并购重组交易470余单, 涉及金额达到3500亿元; 5、 北向资金昨日净卖出36.06亿 ,中国平安净卖出7.08亿; 6、 唐人神:6月生猪销售收入同比翻倍; 7、 31家券商合计净利润为472.3亿元,剔除前述4家券商后同比增幅为44%; 8、 铁矿石急涨不具可持续性, 监管层将加大调查和监管力度; 9、 年内公募基金分红508亿元 ,债基“挑大梁”分红占比高达75.7%; 10、国有五大行2018年度现金分红金额再创新高,合计高达3031.25亿元(含税),较2017年度增加136亿元。 每天早上7:10左右,新增一个【隔夜大消息】,大家在上班路上可以大概知道前一天发生的财经大事。 不同于【早评】的是,隔夜的一些主要消息,需要大家自己去消化,而我会选择其中更为重要的4-5条,放在【早评】里面特别解释。 新的一天开始了,大家早安吖😘😘😘",
                ),
                ImageSpan(
                  AssetImage("packages/real_rich_text/images/emoji_9.png"),
                  imageWidth: 24,
                  imageHeight: 24,
                )
              ], overflow: TextOverflow.ellipsis,
                maxLines: 3,),
            ),
          ),
        );
      }
    }
    
    opened by 2dxgujun 2
  • ImageSpan not update on Hot reload

    ImageSpan not update on Hot reload

    I figure out that when you trigger a Hot reload, _RichTextWrapper will invoke updateRenderObject and it will call RenderParagraph's text setter to set a new TextSpan which call TextSpan.compareTo to determine whether to accept the new TextSpan or drop it.

    Since our ImageSpan is inherited from TextSpan, and we should override the compareTo method to aware the changes of these properties in ImageSpan class.

    Here is my patch code, and it works.

    @override
    RenderComparison compareTo(covariant ImageSpan other) {
      RenderComparison comparison = super.compareTo(other);
      if (other.imageProvider != imageProvider ||
          other.imageWidth != imageWidth ||
          other.imageHeight != imageHeight ||
          other.margin != margin) {
        comparison = RenderComparison.layout;
      }
      return comparison;
    }
    
    opened by 2dxgujun 0
Owner
Bytedance Inc.
Bytedance Inc.
A Flutter package to parse text and make them into linkified text widget

?? Flutter Parsed text A Flutter package to parse text and extract parts using predefined types like url, phone and email and also supports Regex. Usa

Fayeed Pawaskar 213 Dec 27, 2022
Rich Text renderer that parses Contentful Rich Text JSON object and returns a renderable Flutter widget

Contentful Rich Text Renderer for Flutter Rich Text renderer that parses Contentful Rich Text field JSON output and produces a Flutter Widget tree tha

Kumanu 45 Nov 10, 2022
A masked text for Flutter.

flutter_masked_text Masked text input for flutter. Alert Hi guys! Unfortunately, I'm not developing mobile anymore. This repo will not receive updates

Ben-hur Santos Ott 264 Dec 21, 2022
Soft and gentle rich text editing for Flutter applications.

About Zefyr Soft and gentle rich text editing for Flutter applications. You are viewing early dev preview version of this package which is no longer a

Memspace 2.2k Jan 8, 2023
Flutter widget that automatically resizes text to fit perfectly within its bounds.

Flutter widget that automatically resizes text to fit perfectly within its bounds. Show some ❤️ and star the repo to support the project Resources: Do

Simon Leier 1.8k Jan 3, 2023
A simple Flutter package that makes turning a FAB into a text field easy.

flutter_text_field_fab A simple Flutter widget that makes turning a FAB into a text field easy.

Haefele Software 4 Jan 18, 2022
Soft and gentle rich text editing for Flutter applications

Soft and gentle rich text editing for Flutter applications. Zefyrka is a fork of Zefyr package with the following improvements: support Flutter 2.0 op

null 85 Dec 21, 2022
Arc Text Widget for Flutter

Flutter Arc Text Renders text along the arc. See demo. The story behind the plugin is here. Basic usage class MyApp extends StatelessWidget

Kirill Bubochkin 15 Oct 18, 2021
Text Editor in Flutter for Android and iOS to help free write WYSIWYG HTML code

Flutter Summernote Text Editor in Flutter for Android and iOS to help free write WYSIWYG HTML code based on Summernote 0.8.18 javascript wrapper. NOTI

Chandra Abdul Fattah 41 Sep 12, 2022
A customizable code text field supporting syntax highlighting

CodeField A customizable code text field supporting syntax highlighting Live demo A live demo showcasing a few language / themes combinaisons Showcase

Bertrand 162 Dec 23, 2022
Flutter textfield validation lets you validate different textform fields in your Flutter app

Flutter textfield validation lets you validate different textform fields in your Flutter app

World-Package 2 Sep 15, 2022
A markdown renderer for Flutter.

Flutter Markdown A markdown renderer for Flutter. It supports the original format, but no inline HTML. Overview The flutter_markdown package renders M

Flutter 828 Aug 12, 2021
A Flutter Package to render Mathematics, Physics and Chemistry Equations based on LaTeX

flutter_tex Contents About Demo Video Screenshots How to use? Android iOS Web Examples Quick Example TeXView Document TeXView Markdown TeXView Quiz Te

Shahzad Akram 219 Jan 5, 2023
flutter 中文排版,支持分页上下对齐 两端对齐 翻页动画

text_composition flutter 中文排版 分页 上下对齐 两端对齐 多栏布局 弃用richText,使用Canvas,精确定位绘图位置,消除字体对排版影响 视频与截图 demo https://github.com/mabDc/text_composition/releases/t

西红柿大芝麻 50 Nov 3, 2022
Flutter Tutorial - PDF Viewer - Asset, File, Network & Firebase

Flutter Tutorial - PDF Viewer - Asset, File, Network & Firebase Use the Flutter PDF Viewer to download PDF documents and display them within your Flut

Johannes Milke 36 Dec 9, 2022
Create an AutoComplete TextField to search JSON data based on suggestions in Flutter.

Flutter Tutorial - AutoComplete TextField & AutoComplete Search Create an AutoComplete TextField to search JSON data based on suggestions in Flutter.

Johannes Milke 32 Oct 23, 2022
Flutter phone number input

phone_form_field Flutter phone input integrated with flutter internationalization Features Totally cross platform, this is a dart only package / depen

cedvdb 38 Dec 31, 2022
A low code editor with the full power of flutter.

flutter_blossom ?? Low code editor with the full power of flutter. Think in flutter, watch your ideas come to life, plan ahead and let your creativity

Flutter Blossom 0 Dec 2, 2021
A Flutter package provides some implementations of TextInputFormatter that format input with pre-defined patterns

A Flutter package provides some implementations of TextInputFormatter that format input with pre-defined patterns

HungHD 192 Dec 31, 2022