Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WidgetSpan: exception was thrown when set TextOverflow and MaxLines #35869

Closed
zmtzawqlp opened this issue Jul 10, 2019 · 21 comments
Closed

WidgetSpan: exception was thrown when set TextOverflow and MaxLines #35869

zmtzawqlp opened this issue Jul 10, 2019 · 21 comments
Assignees
Labels
framework flutter/packages/flutter repository. See also f: labels.

Comments

@zmtzawqlp
Copy link
Contributor

zmtzawqlp commented Jul 10, 2019

Steps to Reproduce

reproduce with following codes:

import 'package:flutter/material.dart';

class TextDemo extends StatelessWidget {
  final String _attachContent =
      "[love]Extended text help you to build rich text quickly. any special text you will have with extended text.It's my pleasure to invite you to join \$FlutterCandies\$ if you want to improve flutter .[love] if you meet any problem, please let me konw @zmtzawqlp .[sun_glasses]";
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("quickly build special text"),
      ),
      body: Container(
          padding: EdgeInsets.all(20.0),
          child: Text.rich(
            TextSpan(children: <InlineSpan>[
              TextSpan(text: _attachContent),
              WidgetSpan(
                  child: Container(
                color: Colors.blue,
                width: 30.0,
                height: 30.0,
              ))
            ]),
            overflow: TextOverflow.ellipsis,
            maxLines: 1,
          )),
    );
  }
}

Logs

Launching lib\main.dart on MI 6 in debug mode...
Initializing gradle...
Resolving dependencies...
Running Gradle task 'assembleDebug'...
Built build\app\outputs\apk\debug\app-debug.apk.
Syncing files to device MI 6...
I/flutter ( 8425): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter ( 8425): The following RangeError was thrown during performLayout():
I/flutter ( 8425): RangeError (index): Invalid value: Valid value range is empty: 0
I/flutter ( 8425): 
I/flutter ( 8425): When the exception was thrown, this was the stack:
I/flutter ( 8425): #0      List.[] (dart:core-patch/array.dart:12:52)
I/flutter ( 8425): #1      RenderParagraph._setParentData (package:flutter/src/rendering/paragraph.dart:514:44)
I/flutter ( 8425): #2      RenderParagraph.performLayout (package:flutter/src/rendering/paragraph.dart:527:5)
I/flutter ( 8425): #3      RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #4      RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:805:17)
I/flutter ( 8425): #5      RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #6      _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #7      RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #8      _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #9      RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #10     RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:165:27)
I/flutter ( 8425): #11     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #12     RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:181:11)
I/flutter ( 8425): #13     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #14     RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:406:13)
I/flutter ( 8425): #15     RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1334:12)
I/flutter ( 8425): #16     RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1252:20)
I/flutter ( 8425): #17     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #18     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #19     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #20     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #21     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #22     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #23     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #24     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #25     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #26     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #27     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #28     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #29     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #30     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #31     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #32     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #33     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #34     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #35     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #36     RenderPadding.performLayout (package:flutter/src/rendering/shifted_box.dart:206:11)
I/flutter ( 8425): #37     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #38     MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:142:11)
I/flutter ( 8425): #39     _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:443:7)
I/flutter ( 8425): #40     MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:212:7)
I/flutter ( 8425): #41     RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:356:14)
I/flutter ( 8425): #42     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #43     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #44     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #45     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #46     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1214:11)
I/flutter ( 8425): #47     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #48     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #49     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #50     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #51     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #52     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #53     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #54     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #55     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #56     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #57     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #58     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #59     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #60     _RenderProxyBox&RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)
I/flutter ( 8425): #61     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #62     RenderOffstage.performLayout (package:flutter/src/rendering/proxy_box.dart:3074:14)
I/flutter ( 8425): #63     RenderObject.layout (package:flutter/src/rendering/object.dart:1619:7)
I/flutter ( 8425): #64     RenderStack.performLayout (package:flutter/src/rendering/stack.dart:510:15)
I/flutter ( 8425): #65     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1496:7)
I/flutter ( 8425): #66     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:765:18)
I/flutter ( 8425): #67     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:346:19)
I/flutter ( 8425): #68     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:701:13)
I/flutter ( 8425): #69     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:285:5)
I/flutter ( 8425): #70     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1016:15)
I/flutter ( 8425): #71     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:958:9)
I/flutter ( 8425): #72     _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:874:5)
I/flutter ( 8425): #76     _invoke (dart:ui/hooks.dart:236:10)
I/flutter ( 8425): #77     _drawFrame (dart:ui/hooks.dart:194:3)
I/flutter ( 8425): (elided 3 frames from package dart:async)
I/flutter ( 8425): 
I/flutter ( 8425): The following RenderObject was being processed when the exception was fired: RenderParagraph#c3240 relayoutBoundary=up6 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE:
I/flutter ( 8425):   creator: RichText ← Text ← Expanded ← Row ← RepaintBoundary ← IndexedSemantics ←
I/flutter ( 8425):     NotificationListener<KeepAliveNotification> ← KeepAlive ← AutomaticKeepAlive ← KeyedSubtree ←
I/flutter ( 8425):     SliverList ← MediaQuery ← ⋯
I/flutter ( 8425):   parentData: offset=Offset(0.0, 0.0); flex=1; fit=FlexFit.tight (can use size)
I/flutter ( 8425):   constraints: BoxConstraints(w=170.0, 0.0<=h<=Infinity)
I/flutter ( 8425):   semantic boundary
I/flutter ( 8425):   size: MISSING
I/flutter ( 8425):   textAlign: start
I/flutter ( 8425):   textDirection: ltr
I/flutter ( 8425):   softWrap: wrapping at box width
I/flutter ( 8425):   overflow: ellipsis
I/flutter ( 8425):   locale: en_US
I/flutter ( 8425):   maxLines: 10
I/flutter ( 8425): This RenderObject had the following descendants (showing up to depth 5):
I/flutter ( 8425):     text: TextSpan
I/flutter ( 8425):       TextSpan
I/flutter ( 8425):         TextSpan
I/flutter ( 8425):         WidgetSpan#27958
I/flutter ( 8425): ════════════════════════════════════════════════════════════════════════════════════════════════════
I/flutter ( 8425): Another exception was thrown: RenderBox was not laid out: RenderParagraph#c3240 relayoutBoundary=up6 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 8425): Another exception was thrown: RenderBox was not laid out: RenderFlex#a186c relayoutBoundary=up5 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 8425): Another exception was thrown: RenderBox was not laid out: RenderRepaintBoundary#ee3e5 relayoutBoundary=up4 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
I/flutter ( 8425): Another exception was thrown: 'package:flutter/src/rendering/sliver_multi_box_adaptor.dart': Failed assertion: line 549 pos 12: 'child.hasSize': is not true.
I/flutter ( 8425): Another exception was thrown: NoSuchMethodError: The getter 'scrollOffsetCorrection' was called on null.
I/flutter ( 8425): Another exception was thrown: NoSuchMethodError: The method 'debugAssertIsValid' was called on null.
I/flutter ( 8425): Another exception was thrown: NoSuchMethodError: The getter 'visible' was called on null.

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.7.8+hotfix.3, on Microsoft Windows [Version 10.0.17134.829], locale zh-CN)

[√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
[√] Android Studio (version 3.1)
[√] VS Code (version 1.36.0)
[√] Connected device (1 available)

I have done some changes in packages\flutter\lib\src\rendering\paragraph.dart, i think we should take care of over flow widgets .

please take a look attached paragraph.zip.
paragraph.zip

@zmtzawqlp
Copy link
Contributor Author

zmtzawqlp commented Jul 10, 2019

three places i found , need to be changed
1.void paint(PaintingContext context, Offset offset)
2.bool hitTestChildren(BoxHitTestResult result, { Offset position })
3. void _setParentData() {

and it seem that over flow widgets are also calling build method, any performance problems for them?

@saravananmnm
Copy link

you can use blow mentioned lines

ConstrainedBox(
constraints: BoxConstraints(
maxWidth: MediaQuery.of(context).size.width * 0.5),
child: Wrap(alignment: WrapAlignment.end, children: [
new Text(subTitle ?? null,
textScaleFactor: textSize ?? null,
overflow: TextOverflow.clip,
softWrap: true,
maxLines: 2,
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.black54)),
]),
),

@justinmc justinmc added a: typography Text rendering, possibly libtxt framework flutter/packages/flutter repository. See also f: labels. and removed a: typography Text rendering, possibly libtxt labels Jul 10, 2019
@justinmc
Copy link
Contributor

How do you get the crash to happen? I ran the code and scrolled around but didn't get any crash.

@zmtzawqlp
Copy link
Contributor Author

@justinmc sorry, it should make sure text is over flow, i have update the demo codes, please try it

@justinmc
Copy link
Contributor

Thanks, now I can definitely reproduce it! Running the given code immediately logs the error. So the problem has to do with ending an overflowing line with a WidgetSpan. Seems like it's probably a bug in Flutter that should be fixed.

@zmtzawqlp
Copy link
Contributor Author

@justinmc I have another problem about widgetspan

I'm working for add widgetspan support for https://github.com/fluttercandies/extended_text and
https://github.com/fluttercandies/extended_text_field

try to do selection with widgetspan, but _textPainter.getOffsetForCaret return Offset.zero when textspan has widgetspans, could you please report to flutter team about it?

i'm try to work with workaround to fix it, but i think it's something wrong with flutter engine.

thanks.

@justinmc
Copy link
Contributor

@chunhtai Have you run into the above problem with WidgetSpan in your selectable text work?

@chunhtai
Copy link
Contributor

The current plan for selectable text is to only allow textspan. I don't think this will affect my work

@justinmc
Copy link
Contributor

Flutter might not support caret position with WidgetSpan right now then. It might be something worth adding, though.

@zmtzawqlp
Copy link
Contributor Author

_textPainter.getBoxesForSelection is right for WidgetSpan, so I do a workaround for get caret position with selection boxs.
selectable text is helpful, just like we can select text in web. I'm looking forward to add this feature.
thanks.

@chunhtai
Copy link
Contributor

We need to sort out what does it mean to copy/paste a widget span, and it might require a detail discussion

@zmtzawqlp
Copy link
Contributor Author

zmtzawqlp commented Jul 18, 2019

as i see, widget will be like something "[love]" as an image.
love
we insert some image(emoji) like "[love]" with text field,and send to Server-side, and get text string from Server-side and show it in Text.

just like some Instant Messaging app.

@AlexV525
Copy link
Member

@chunhtai When it comes a emoticon which user want to insert into TextField, it will insert something like [Good] [Love] and the developer will replace a custom emoticon to it, which is the new WidgetSpan can do. This is not related to emoji or any character. See the screenshot for the scene I'm talking about.
image
In the past we use extended_text or extended_text_field to achieve this function, but if WidgetSpan can't be selected, what kind of method can we take to solve this problem?

@chunhtai chunhtai self-assigned this Aug 13, 2019
@chunhtai
Copy link
Contributor

@zmtzawqlp I agree that should the correct behavior in this use case. The discussion is more about how we expose the api to enable this and what is the default behavior should be like.

@AlexVincent525
There is not possible to achieve this with current api unless you build your own widget.
I created a feature request #38474, please upvote to bump up its priority.

@chunhtai
Copy link
Contributor

chunhtai commented Aug 15, 2019

Finished investigation, the crashing is caused by widgetspan being truncated in engine side due to ellipsis.
The logic in RenderParagraph tries to locate the place to insert widgetspan and couldn't find it.

The fix should be ignore the widgetspan if there is no location returns from engine. will put up a pr to fix this

@zmtzawqlp
Copy link
Contributor Author

@chunhtai ok,thanks,we should take care of them

@AlexV525
Copy link
Member

AlexV525 commented Dec 9, 2019

@chunhtai Is the pull request been included in 1.9.1+hotfix.6? Cause so far this issue still exist.

@chunhtai
Copy link
Contributor

chunhtai commented Dec 9, 2019

@AlexVincent525 This should be included. Can you share a reproducible example for the issue you are facing?

@AlexV525
Copy link
Member

@chunhtai The code below was 100% reproduce the issue under my environment.

Text.rich(
  TextSpan(
    children: List<InlineSpan>.generate(
      12,
      (int index) => WidgetSpan(
        child: Text(
          "Test WidgetSpan $index",
          style: TextStyle(fontSize: 16.0),
        ),
      ),
    ),
  ),
  maxLines: 2,
)

Error log:

════════ Exception caught by rendering library ═════════════════════════════════════════════════════
The following RangeError was thrown during performLayout():
RangeError (index): Invalid value: Not in range 0..7, inclusive: 8

User-created ancestor of the error-causing widget was: 
  Text file:///Users/alex/Documents/FlutterProjects/TestApp/lib/pages/splash_page.dart:99:16
When the exception was thrown, this was the stack: 
#0      List.[] (dart:core-patch/array.dart:13:52)
#1      RenderParagraph._setParentData (package:flutter/src/rendering/paragraph.dart:519:44)
#2      RenderParagraph.performLayout (package:flutter/src/rendering/paragraph.dart:532:5)
#3      RenderObject.layout (package:flutter/src/rendering/object.dart:1701:7)
#4      RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:105:13)

flutter doctor

[✓] Flutter (Channel stable, v1.9.1+hotfix.6, on Mac OS X 10.15.1 19B88, locale zh-Hans-CN)

@AlexV525
Copy link
Member

By reviewing the paragraph.dart with 1.9.1+hotfix.6's tag, the PR wasn't included. And I'm sorry to say that but you have missed one place needs to be updated. @chunhtai

————————LINE BREAKER————————

The hitTestChildren method should add childIndex and be like:
while (child != null && childIndex < _textPainter.inlinePlaceholderBoxes.length) {

And childIndex++; after:

————————LINE BREAKER————————

The code above should be:
while (child != null && childIndex < _textPainter.inlinePlaceholderBoxes.length) {

————————LINE BREAKER————————

The code above should be:
while (child != null && childIndex < _textPainter.inlinePlaceholderBoxes.length) {

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 25, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

No branches or pull requests

5 participants