A directional tooltip for flutter projects

Overview

just_the_tooltip

just_the_tooltip gives you more flexibility over the Flutter standard Tooltip by allowing you to set arbitrary content. It also expands on their single axis layout algorithm to fit both vertically and horizontally. The tooltip can be positioned along any axis and will fall back to the opposite side if overflowed.

Breaking

  • Removed JustTheTooltip.entry named constructor in favor of dedicated widget JustTheTooltipEntry. This mirrors a change in the code that explicitly differentiates where and how tooltips are shown.

Getting Started

JustTheTooltip(
  child: Material(
    color: Colors.grey.shade800,
    shape: const CircleBorder(),
    elevation: 4.0,
    child: const Padding(
      padding: EdgeInsets.all(8.0),
      child: Icon(
        Icons.add,
        color: Colors.white,
      ),
    ),
  ),
  content: const Padding(
    padding: EdgeInsets.all(8.0),
    child: Text(
      'Bacon ipsum dolor amet kevin turducken brisket pastrami, salami ribeye spare ribs tri-tip sirloin shoulder venison shank burgdoggen chicken pork belly. Short loin filet mignon shoulder rump beef ribs meatball kevin.',
    ),
  ),
)

JustTheTooltip needs two arguments. The direct child widget and the content (of the tooltip). The child widget will be wrapped with a GestureDetector or MouseRegion that is responsible for showing and hiding the content. Further handling of the tooltip state can be managed explicitly through a controller:

If you'd like to create a controller to manage the state of the tooltip, you can do so by defining an instance of a JustTheController and pass it through to constructor.

final tooltipController = JustTheController();

child: JustTheTooltip(
  controller: tooltipController,
  // ...
)

void showTooltip() {
  controller.showTooltip();
}

The controller itself is a ValueNotifier that carries the open/close state of the tooltip. To listen to these changes, add a listener to your controller.

@override
void initState() {
  // Programatically display tooltip after two seconds
  Future.delayed(const Duration(seconds: 2), () {
    tooltipController.showTooltip(immediately: false);
  });

  tooltipController.addListener(() {
    // Prints the enum value of [TooltipStatus.isShowing] or [TooltipStatus.isHiding]
    print('controller: ${tooltipController.value}');
  });
}

Customization

  • Modal

You can further define how a Tooltip will show by defining the isModal property. A modal will only open through clicking on the child and close by clicking on the background area (referred to as the skrim here). A non-modal (the default) is a more traditional tooltip opens and closes on hovers.

Note, phone emulators do not implement mouse controls. To test hover states, use a browser.

The fallback used when no mouse region is present but isModal is false is to only open when long pressed.

  • Tail Builder

If you'd like a custom tail (the nub on the end dialog bubble) drawn on your tooltip, you can pass through your own tailBuilder. The JustTheInterface.defaultTailBuilder (default) shows how to simply draw and return a path for your custom tails:

Path defaultTailBuilder(Offset tip, Offset point2, Offset point3) {
  return Path()
    ..moveTo(tip.dx, tip.dy)
    ..lineTo(point2.dx, point2.dy)
    ..lineTo(point3.dx, point3.dy)
    ..close();
}

The library also provides a simple bezier curved tailbuilder JustTheInterface.defaultBezierTailBuilder.

  • ListViews

The tooltip should also work in lists and follow the target through scrolling. For even more consideration of the available space in ListViews, a ScrollController may be passed to the just_the_tooltip to give the layout algorithm a hint as to how much space is before and after the scroll axis. This allows tooltips that would otherwise overflow to use up space offscreen in one of the scroll directions.

  • Non-Overlay Tooltip

For use cases where the tooltip must be a part the widget tree rather than an overlay there is a JustTheTooltipEntry.

Scaffold(
  appBar: AppBar(title: const Text('It goes under me')),
  body: JustTheTooltipArea(
    builder: (context, tooltip, scrim) {
      return Stack(
        fit: StackFit.passthrough,
        children: [
          ListView.builder(
            itemCount: 30,
            itemBuilder: (context, index) {
              if (index == 15) {
                return JustTheTooltipEntry(
                  tailLength: 10.0,
                  preferredDirection: AxisDirection.down,
                  isModal: true,
                  margin: const EdgeInsets.all(20.0),
                  child: const Material(
                    color: Colors.blue,
                    shape: CircleBorder(),
                    elevation: 4.0,
                    child: Padding(
                      padding: EdgeInsets.all(8.0),
                      child: Icon(
                        Icons.touch_app,
                        color: Colors.white,
                      ),
                    ),
                  ),
                  content: Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Container(
                        height: 120,
                        color: Colors.blue,
                        width: double.infinity,
                      ),
                      const SizedBox(height: 8),
                      const Text(
                        'Quia ducimus eius magni voluptatibus ut veniam ducimus. Ullam ab qui voluptatibus quos est in. Maiores eos ab magni tempora praesentium libero. Voluptate architecto rerum vel sapiente ducimus aut cumque quibusdam. Consequatur illo et quos vel cupiditate quis dolores at.',
                      ),
                    ],
                  ),
                );
              }

              return ListTile(title: Text('Item $index'));
            },
          ),
          // In the case of no scrim showing, this will return an SizedBox.shrink
          scrim,
          // In the case of no scrim showing, this will return an SizedBox.shrink
          tooltip,
        ],
      );
    },
  ),
);

This will give you the positioned tooltip and scrim (an empty gesture detector that catches tap events and closes the tooltip) for you to enter into the tree however you like. By doing this, you can make tooltips that are visually "under" other parts of the UI such as the appbar in the above example.

API subject to change.

Contributing

Issues and PRs welcome. Unless otherwise specified, all contributions to this lib will be under MIT license.

Comments
  • Some problems with all the durations

    Some problems with all the durations

    I don't know exactly what's going on, but setting these durations is near impossible to get right.

    Most of the time the tooltip doesn't show up. It must be hiding the tooltip in timers that get fired at the wrong time.

    Very confusing to set this up.

    opened by sgehrman 13
  • Show the tooltip programatically

    Show the tooltip programatically

    Forcing the child onTap to show the tooltip is not cool. It might be the default behavior but we should be able to decide when we want to show the tooltip in the app. Think of onboarding scenarios.

    opened by aytunch 9
  • Null safety issue

    Null safety issue

    I'm getting this error while building my app:

    
    ERROR: ../../.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.11+2/lib/src/just_the_tooltip.dart:329:27: Warning: Operand of null-aware operation '!' has type 'RendererBinding' which excludes null.
    ERROR:  - 'RendererBinding' is from 'package:flutter/src/rendering/binding.dart' ('/opt/flutter/packages/flutter/lib/src/rendering/binding.dart').
    ERROR:           RendererBinding.instance!.mouseTracker.mouseIsConnected;
    ERROR:                           ^
    ERROR: ../../.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.11+2/lib/src/just_the_tooltip.dart:393:21: Warning: Operand of null-aware operation '!' has type 'RendererBinding' which excludes null.
    ERROR:  - 'RendererBinding' is from 'package:flutter/src/rendering/binding.dart' ('/opt/flutter/packages/flutter/lib/src/rendering/binding.dart').
    ERROR:     RendererBinding.instance!.mouseTracker
    ERROR:                     ^
    ERROR: ../../.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.11+2/lib/src/just_the_tooltip.dart:397:20: Warning: Operand of null-aware operation '!' has type 'GestureBinding' which excludes null.
    ERROR:  - 'GestureBinding' is from 'package:flutter/src/gestures/binding.dart' ('/opt/flutter/packages/flutter/lib/src/gestures/binding.dart').
    ERROR:     GestureBinding.instance!.pointerRouter.addGlobalRoute(_handlePointerEvent);
    ERROR:                    ^
    ERROR: ../../.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.11+2/lib/src/just_the_tooltip.dart:402:21: Warning: Operand of null-aware operation '?.' has type 'RendererBinding' which excludes null.
    ERROR:  - 'RendererBinding' is from 'package:flutter/src/rendering/binding.dart' ('/opt/flutter/packages/flutter/lib/src/rendering/binding.dart').
    ERROR:     RendererBinding.instance?.mouseTracker
    ERROR:                     ^
    ERROR: ../../.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.11+2/lib/src/just_the_tooltip.dart:404:20: Warning: Operand of null-aware operation '?.' has type 'GestureBinding' which excludes null.
    ERROR:  - 'GestureBinding' is from 'package:flutter/src/gestures/binding.dart' ('/opt/flutter/packages/flutter/lib/src/gestures/binding.dart').
    ERROR:     GestureBinding.instance?.pointerRouter
    ERROR:                    ^
    ERROR: ../../.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.11+2/lib/src/just_the_tooltip.dart:414:25: Warning: Operand of null-aware operation '!' has type 'RendererBinding' which excludes null.
    ERROR:  - 'RendererBinding' is from 'package:flutter/src/rendering/binding.dart' ('/opt/flutter/packages/flutter/lib/src/rendering/binding.dart').
    ERROR:         RendererBinding.instance!.mouseTracker.mouseIsConnected;
    ERROR:                         ^
    ERROR: ../../.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.11+2/lib/src/just_the_tooltip.dart:498:22: Warning: Operand of null-aware operation '?.' has type 'WidgetsBinding' which excludes null.
    ERROR:  - 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('/opt/flutter/packages/flutter/lib/src/widgets/binding.dart').
    ERROR:       WidgetsBinding.instance?.addPostFrameCallback((_) async {
    ERROR:                      ^
    ERROR: ../../.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.11+2/lib/src/just_the_tooltip_entry.dart:210:20: Warning: Operand of null-aware operation '?.' has type 'WidgetsBinding' which excludes null.
    ERROR:  - 'WidgetsBinding' is from 'package:flutter/src/widgets/binding.dart' ('/opt/flutter/packages/flutter/lib/src/widgets/binding.dart').
    ERROR:     WidgetsBinding.instance?.addPostFrameCallback((_) {
    ERROR:                    ^
    
    opened by spiralw 5
  •  Error: Type 'TooltipTriggerMode' not found.   final TooltipTriggerMode? triggerMode

    Error: Type 'TooltipTriggerMode' not found. final TooltipTriggerMode? triggerMode

    app is working in debug mode, but its throwing several errors when i try to build the APK. Bellow i will mention the errors which i got.

    `../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:80:9: Error: Type 'TooltipTriggerMode' not found. final TooltipTriggerMode? triggerMode;
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:288:16: Error: Type 'TooltipTriggerMode' not found. static const TooltipTriggerMode _defaultTriggerMode =
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:300:8: Error: Type 'TooltipTriggerMode' not found. late TooltipTriggerMode triggerMode;
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip_entry.dart:60:9: Error: Type 'TooltipTriggerMode' not found. final TooltipTriggerMode? triggerMode;
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/models/just_the_interface.dart:125:3: Error: Type 'TooltipTriggerMode' not found. TooltipTriggerMode? get triggerMode;
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:289:7: Error: Getter not found: 'TooltipTriggerMode'. TooltipTriggerMode.longPress;
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:80:9: Error: 'TooltipTriggerMode' isn't a type. final TooltipTriggerMode? triggerMode;
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:288:16: Error: 'TooltipTriggerMode' isn't a type. static const TooltipTriggerMode _defaultTriggerMode =
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:300:8: Error: 'TooltipTriggerMode' isn't a type. late TooltipTriggerMode triggerMode;
    ^^^^^^^^^^^^^^^^^^
    ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:559:26: Error: The getter 'TooltipTriggerMode' isn't defined for the class '_JustTheTooltipState'.

    • '_JustTheTooltipState' is from 'package:just_the_tooltip/src/just_the_tooltip.dart' ('../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'TooltipTriggerMode'. if (triggerMode == TooltipTriggerMode.longPress) {
      ^^^^^^^^^^^^^^^^^^
      ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:581:44: Error: The getter 'triggerMode' isn't defined for the class 'TooltipThemeData'.
    • 'TooltipThemeData' is from 'package:flutter/src/material/tooltip_theme.dart' ('../../src/flutter_2.2.3/packages/flutter/lib/src/material/tooltip_theme.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'triggerMode'. widget.triggerMode ?? tooltipTheme.triggerMode ?? _defaultTriggerMode; ^^^^^^^^^^^
      ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:583:22: Error: The getter 'enableFeedback' isn't defined for the class 'TooltipThemeData'.
    • 'TooltipThemeData' is from 'package:flutter/src/material/tooltip_theme.dart' ('../../src/flutter_2.2.3/packages/flutter/lib/src/material/tooltip_theme.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'enableFeedback'. tooltipTheme.enableFeedback ??
      ^^^^^^^^^^^^^^
      ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:590:29: Error: The getter 'TooltipTriggerMode' isn't defined for the class '_JustTheTooltipState'.
    • '_JustTheTooltipState' is from 'package:just_the_tooltip/src/just_the_tooltip.dart' ('../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'TooltipTriggerMode'. : (triggerMode == TooltipTriggerMode.longPress)
      ^^^^^^^^^^^^^^^^^^
      ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart:595:29: Error: The getter 'TooltipTriggerMode' isn't defined for the class '_JustTheTooltipState'.
    • '_JustTheTooltipState' is from 'package:just_the_tooltip/src/just_the_tooltip.dart' ('../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip.dart'). Try correcting the name to the name of an existing getter, or defining a getter or field named 'TooltipTriggerMode'. : (triggerMode == TooltipTriggerMode.tap)
      ^^^^^^^^^^^^^^^^^^
      ../../src/flutter_2.2.3/.pub-cache/hosted/pub.dartlang.org/just_the_tooltip-0.0.10/lib/src/just_the_tooltip_entry.dart:60:9: Error: 'TooltipTriggerMode' isn't a type. final TooltipTriggerMode? triggerMode;
      ^^^^^^^^^^^^^^^^^^

    FAILURE: Build failed with an exception.

    • Where:
      Script '/home/mindstack/src/flutter_2.2.3/packages/flutter_tools/gradle/flutter.gradle' line: 1035

    • What went wrong:
      Execution failed for task ':app:compileFlutterBuildRelease'.

    Process 'command '/home/mindstack/src/flutter_2.2.3/bin/flutter'' finished with non-zero exit value 1

    • Try:
      Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

    • Get more help at https://help.gradle.org
      `

    opened by abhipoojary 4
  • adding status notifier

    adding status notifier

    Hello, thanks for creating this lib, it's so powerful. When I use this lib, I realized the "controller.isShowing" doesn't work as expected. After some investigation, I found the controller.value would be changed multiple time for each user action. So I exposed this tooltip status. I also updated the example for your reference. Feel free to update these changes if there is better implementation. Thanks~

    opened by zmhbh 4
  • Avoid tooltip area gesture detection for manual trigger mode

    Avoid tooltip area gesture detection for manual trigger mode

    We use a tooltip only in the manual trigger mode, so we show it only by using controller.showTooltip(), but in some situations the tooltip is unintentionally shown by a tap gesture.

    Let's avoid wrapping it in the GestureDetector/MouseRegion when only the manual trigger mode is used.

    opened by Pavel-Sulimau 3
  • LateInitializationError: Field '_controller@1501137672' has already been  initialized

    LateInitializationError: Field '_controller@1501137672' has already been  initialized

    Hi, I have error when I try create a new justTheController Any ideas?

    StackTrace: #0      LateError._
    throwFieldAlreadyInitialized (dart:_internal-patch\/internal_patch.dart:211)\n#1      _JustTheToolt
    ipState._controller= (package:just_the_tooltip\/src\/just_the_tooltip.dart:150)\n#2      _JustTheTo
    oltipState.didUpdateWidget (package:just_the_tooltip\/src\/just_the_tooltip.dart:222)\n#3      Stat
    efulElement.update (package:flutter\/src\/widgets\/framework.dart:4855)\n#4      Element.updateChil
    d (package:flutter\/src\/widgets\/framework.dart:3412)\n#5      ComponentElement.performRebuild (pa
    ckage:flutter\/src\/widgets\/framework.dart:4690)\n#6      Element.rebuild (package:flutter\/src\/w
    idgets\/framework.dart:4355)\n#7      StatelessElement.update (package:flutter\/src\/widgets\/frame
    work.dart:4746)\n#8      Element.updateChild (package:flutter\/src\/widgets\/framework.dart:3412)\n
    #9      ComponentElement.performRebuild (package:flutter\/src\/widgets\/framework.dart:4690)\n#10
       StatefulElement.performRebuild (package:flutter\/src\/widgets\/framework.dart:4840)\n#11     Ele
    ment.rebuild (package:flutter\/src\/widgets\/framework.dart:4355)\n#12     StatefulElement.update (
    package:flutter\/src\/widgets\/framework.dart:4872)\n#13     Element.updateChild (package:flutter\/
    src\/widgets\/framework.dart:3412)\n#14     Element.inflateWidget (package:flutter\/src\/widgets\/f
    ramework.dart:3663)\n#15     Element.updateChild (package:flutter\/src\/widgets\/framework.dart:342
    5)\n#16     ComponentElement.performRebuild (package:flutter\/src\/widgets\/framework.dart:4690)\n#
    17     StatefulElement.performRebuild (package:flutter\/src\/widgets\/framework.dart:4840)\n#18
     Element.rebuild (package:flutter\/src\/widgets\/framework.dart:4355)\n#19     ComponentElement._fi
    rstBuild (package:flutter\/src\/widgets\/framework.dart:4643)\n#20     StatefulElement._firstBuild
    (package:flutter\/src\/widgets\/framework.dart:4831)\n#21     ComponentElement.mount (package:flutt
    er\/src\/widgets\/framework.dart:4638)\n#22     Element.inflateWidget (package:flutter\/src\/widget
    s\/framework.dart:3673)\n#23     Element.updateChild (package:flutter\/src\/widgets\/framework.dart
    :3425)\n#24     ComponentElement.performRebuild (package:flutter\/src\/widgets\/framework.dart:4690
    ...
    #201    BuildOwner.buildScope (package:flutter\/src\/widgets\/framework.dart:2620)\n#202    Widgets
    Binding.drawFrame (package:flutter\/src\/widgets\/binding.dart:882)\n#203    RendererBinding._handl
    ePersistentFrameCallback (package:flutter\/src\/rendering\/binding.dart:319)\n#204    SchedulerBind
    ing._invokeFrameCallback (package:flutter\/src\/scheduler\/binding.dart:1143)\n#205    SchedulerBin
    ding.handleDrawFrame (package:flutter\/src\/scheduler\/binding.dart:1080)\n#206    SchedulerBinding
    ._handleDrawFrame (package:flutter\/src\/scheduler\/binding.dart:996)\n#207    _rootRun (dart:async
    \/zone.dart:1428)\n#208    _CustomZone.run (dart:async\/zone.dart:1328)\n#209    _CustomZone.runGua
    rded (dart:async\/zone.dart:1236)\n#210    _invoke (dart:ui\/hooks.dart:166)\n#211    PlatformDispa
    tcher._drawFrame (dart:ui\/platform_dispatcher.dart:270)\n#212    _drawFrame (dart:ui\/hooks.dart:1
    29)\n \n\n Error message: LateInitializationError: Field '_controller@1501137672' has already been 
    initialized
    
    opened by AtixD 3
  • JustTheController doesn't reflect the correct tooltip status

    JustTheController doesn't reflect the correct tooltip status

    It's easy to reproduce, just add a listener to the JustTheController instance. And check 'isShowing' within the closure, like what I did in the PR.

    As I mentioned in the PR, JustTheController as a ValueNotifier, ideally, it should reflect the current status of tooltip, like open or close. I noticed you have implemented these functions: 'isShowing' and 'isHidden', however, it's broken, the value never changes.

    I also tried to fix it directly, but the value will be changed multiple times during each user action, that means, if I listen to JustTheController, the listener will be invoked multiple times for each user action. Potentially, this listener behavior would cause some unnecessary issues. That's why I end up with creating a new status notifier. Maybe you have better implementation. Please let me know if you have any questions.

    opened by zmhbh 3
  • tooltip in ListView item crash

    tooltip in ListView item crash

    I haven't investigated this yet. But I added a tooltip on some listview items and I'm getting this:

    [ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: RenderFlex children have non-zero flex but incoming width constraints are unbounded. When a row is in a parent that does not provide a finite width constraint, for example if it is in a horizontal scrollable, it will try to shrink-wrap its children along the horizontal axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the horizontal direction. These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child cannot simultaneously expand to fit its parent. Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible children (using Flexible rather than Expanded). This will allow the flexible children to size themselves to less than the infinite remaining space they would otherwise be forced to take, and then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum constraints provided by the parent. If this message did not help you determine the problem, consider using debugDumpRenderTree(): https://flutter.dev/debugging/#rendering-layer http://api.flutter.dev/flutter/rendering/debugDumpRenderTree.html The affected RenderFlex is: RenderFlex#88256 relayoutBoundary=up18(creator: Row ← Padding ← DefaultTextStyle ← Builder ← Semantics ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#2bfc5 ink renderer] ← NotificationListener ← CustomPaint ← _ShapeBorderPaint ← PhysicalShape ← ⋯, parentData: offset=Offset(10.0, 10.0) (can use size), constraints: BoxConstraints(w=849.8, 0.0<=h<=Infinity), size: Size(849.8, 60.0), direction: horizontal, mainAxisAlignment: start, mainAxisSize: max, crossAxisAlignment: center, textDirection: ltr, verticalDirection: down) The creator information is set to: Row ← Padding ← DefaultTextStyle ← Builder ← Semantics ← DefaultTextStyle ← AnimatedDefaultTextStyle ← _InkFeatures-[GlobalKey#2bfc5 ink renderer] ← NotificationListener ← CustomPaint ← _ShapeBorderPaint ← PhysicalShape ← ⋯ See also: https://flutter.dev/layout/ If none of the above helps enough to fix this problem, please don't hesitate to file a bug: https://github.com/flutter/flutter/issues/new?template=2_bug.md #0 RenderBox.debugCannotComputeDryLayout. #1 RenderBox.debugCannotComputeDryLayout #2 RenderFlex.computeDryLayout #3 RenderBox._computeDryLayout #4 RenderBox.getDryLayout. #5 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #6 RenderBox.getDryLayout #7 RenderPadding.computeDryLayout #8 RenderBox._computeDryLayout #9 RenderBox.getDryLayout. #10 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #11 RenderBox.getDryLayout #12 RenderProxyBoxMixin.computeDryLayout #13 RenderBox._computeDryLayout #14 RenderBox.getDryLayout. #15 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #16 RenderBox.getDryLayout #17 RenderProxyBoxMixin.computeDryLayout #18 RenderBox._computeDryLayout #19 RenderBox.getDryLayout. #20 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #21 RenderBox.getDryLayout #22 RenderProxyBoxMixin.computeDryLayout #23 RenderBox._computeDryLayout #24 RenderBox.getDryLayout. #25 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #26 RenderBox.getDryLayout #27 RenderProxyBoxMixin.computeDryLayout #28 RenderBox._computeDryLayout #29 RenderBox.getDryLayout. #30 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #31 RenderBox.getDryLayout #32 RenderPadding.computeDryLayout #33 RenderBox._computeDryLayout #34 RenderBox.getDryLayout. #35 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #36 RenderBox.getDryLayout #37 RenderProxyBoxMixin.computeDryLayout #38 RenderBox._computeDryLayout #39 RenderBox.getDryLayout. #40 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #41 RenderBox.getDryLayout #42 RenderProxyBoxMixin.computeDryLayout #43 RenderBox._computeDryLayout #44 RenderBox.getDryLayout. #45 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #46 RenderBox.getDryLayout #47 RenderProxyBoxMixin.computeDryLayout #48 RenderBox._computeDryLayout #49 RenderBox.getDryLayout. #50 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:314:23) #51 RenderBox.getDryLayout #52 _JustTheTooltipState._getTargetInformation #53 _JustTheTooltipState._createEntry #54 _JustTheTooltipState._createNewEntries #55 _JustTheTooltipState.ensureTooltipVisible #56 _JustTheTooltipState._showTooltip. #57 _JustTheTooltipState._showTooltip. #58 _rootRun (dart:async/zone.dart:1420:47) #59 _CustomZone.run (dart:async/zone.dart:1328:19) #60 _CustomZone.runGuarded (dart:async/zone.dart:1236:7) #61 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:1276:23) #62 _rootRun (dart:async/zone.dart:1428:13) #63 _CustomZone.run (dart:async/zone.dart:1328:19) #64 _CustomZone.bindCallback. (dart:async/zone.dart:1260:23) #65 Timer._createTimer. (dart:async-patch/timer_patch.dart:18:15) #66 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:395:19) #67 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:426:5) #68 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:187:12)

    opened by sgehrman 3
  • onShow, onHide callbacks

    onShow, onHide callbacks

    I am using a widget by tapping it i am showing a tooltip. but i also want to change the size, colour of the tooltip but unable to do because i am not getting any callback of show and close in which i can change the widget.It would be great if those call backs are added soon. Thank you.

    opened by Hassanch15 1
  • Making a button to show a tooltip when it's a non-modal closes the modal immediately

    Making a button to show a tooltip when it's a non-modal closes the modal immediately

    This is semi expected behavior as the tooltip adds a global listener for taps and will close the tooltip if there's any taps. However, I don't think it should happen the second the tooltip is created.

    The tap handler should should ignore all taps until hasEntry is true

    Edit

    It does wait until it has an entry. It still doesn't handle it correctly

    void _handlePointerEvent(PointerEvent event) {
        if (!delegate.hasEntry) return;
    
        if (event is PointerUpEvent || event is PointerCancelEvent) {
          _hideTooltip();
        } else if (event is PointerDownEvent) {
          _hideTooltip(immediately: true);
        }
      }
    
    enhancement 
    opened by Nolence 1
  • isModal does not work, if child is gestureDetector

    isModal does not work, if child is gestureDetector

    isModal wraps the child with a gestureDetector as far as I know, but if the child is already wrapped with a gesture detector, isModal will not work

    issue code

    JustTheTooltip( isModal: true, content: Text("Content") child: GestureDetector( onTap: () => {}, // if not provided on tap it will work. child: Text("child"), ) );

    opened by fai9al7dad 0
  • Add navigator as ancestor to Offset

    Add navigator as ancestor to Offset

    Add navigator.context.findRenderObject() as an ancestor to position the overlay offset. This is required to work correctly inside a RouterOutlet, the flutter overlay widgets implement this, for example DropdownButton.

    opened by ErickPariseVitorassi 0
  • Prevent the tooltip from closing on clicking on it

    Prevent the tooltip from closing on clicking on it

    Is this how it was intended, that the tooltip closes when you click on it?

    Can this be disabled somehow?

    I think such property values (that I have set) should prevent this.

    triggerMode: TooltipTriggerMode.manual,
    barrierDismissible: false,
    

    But it doesn't work that way.

    opened by yegor-pelykh 1
  • isModal:true makes the tooltip persistant (on previous page) when a GestureDetector of higher level pushes the navigator to a new route...

    isModal:true makes the tooltip persistant (on previous page) when a GestureDetector of higher level pushes the navigator to a new route...

    ...Not allowing the tooltip to show for any new item on the new route (as the previous one wasn't closed 'properly'. It also doesn't allow it to close on the new page as it technically doesn't exist on that page? Lets look at this example:

    import 'package:flutter/material.dart';
    import 'package:just_the_tooltip/just_the_tooltip.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Error App',
          debugShowCheckedModeBanner: false,
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: const MyHomePage(title: 'Error'),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      final String title;
    
      const MyHomePage({
        Key? key,
        required this.title,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(title),
          ),
          body: Center: (child: GestureDetector(
            onDoubleTap: () {
              Navigator.push<void>(
                context,
                MaterialPageRoute(builder: (context) {
                  FocusScope.of(context).unfocus();
                  return SecondPage();
                }),
              );
            },
            child: ToolTipBug(
              description: 'Hello',
            ),
          ),
         ),
       );
      }
    }
    
    class ToolTipBug extends StatelessWidget {
      final String description;
    
      const ToolTipBug({
        Key? key,
        required this.description,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return JustTheTooltip(
          isModal: true,
          triggerMode: TooltipTriggerMode.tap,
          content: Text(description),
          child: SizedBox(
            height: 100,
            child: Center(child: Text('Test')),
          ),
        );
      }
    }
    
    class SecondPage extends StatelessWidget {
      const SecondPage({
        Key? key,
      }) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
    
    
        return  Scaffold(
          appBar: AppBar(
            title: Text('Page 2'),
          ),
          body: Center: (
            child: ToolTipBug(
              description: 'hello 2',
            ),
          ),
       );
      }
    }
    
    
    

    Lets consider this simple example. When you open the tooltip and then double click on the MyHomePage Class, and you go to the SecondPage, you expect the modal of the previous page to be closed and that you will be able to open the second ToolTipBug Widget on SecondPage by cliking on it but this doesn't happen. The previous modal in the MyHomePage Class persists (but is not there) and nothing opens in the new page. This behaviour only happens when isModal is set to true.

    opened by CodesbyRobot 0
Owner
Nollie
sunlight is for chumps
Nollie
Flutter package: Assorted layout widgets that boldly go where no native Flutter widgets have gone before.

assorted_layout_widgets I will slowly but surely add interesting widgets, classes and methods to this package. Despite the package name, they are not

Marcelo Glasberg 122 Dec 22, 2022
Flutter Carousel Pro - A Flutter Carousel widget

Carousel Extended A Flutter Carousel widget. Usage As simple as using any flutter Widget. Based on Carousel Pro but extended to be able to navigate be

omid habibi 3 Dec 7, 2020
Flutter-useful-widgets - Flutter Useful Widgets

useful_widgets This package makes it easy to build apps by providing a list of simple and useful widgets. import 'package:useful_widgets/useful_widget

Ricardo Crescenti 6 Jun 20, 2022
Flutter Duration Button - Create auto-click button likes Netflix's Skip Intro button in Flutter

Flutter Duration Button - Create auto-click button likes Netflix's Skip Intro button in Flutter

Kim Seung Hwan 7 Dec 7, 2022
Various Flutter widgets that are developed by Google but not by the core Flutter team

Flutter widgets This repository contains the source code for various Flutter widgets that are developed by Google but not by the core Flutter team. Is

Google 1.1k Jan 7, 2023
🟥 A flutter widget that flashes when flutter fails to render a frame in a certain timeframe

?? A flutter widget that flashes when flutter fails to render a frame in a certain timeframe

Andrei Lesnitsky 32 Oct 8, 2022
A Flutter plugin that makes it easier to make floating/overlay windows for Android with pure Flutter

flutter_floatwing A Flutter plugin that makes it easier to make floating/overlay windows for Android with pure Flutter. Android only Features Pure Flu

Zoe 116 Dec 21, 2022
Flutter Application to test basic flutter understanding

Flutter Application to test basic flutter understanding Getting Started Before you start with the application have a look at what

null 0 Apr 16, 2022
Flutter UI Widgets Flutter Package

Flutter UI Widgets Flutter Package This package makes different Flutter UI widgets implementation easy for you. Flutter UI Widgets The list of widgets

Hassan Ur Rahman 0 May 6, 2022
React hooks for Flutter. Hooks are a new kind of object that manages a Widget life-cycles. They are used to increase code sharing between widgets and as a complete replacement for StatefulWidget.

English | Português Flutter Hooks A Flutter implementation of React hooks: https://medium.com/@dan_abramov/making-sense-of-react-hooks-fdbde8803889 Ho

Remi Rousselet 2.6k Dec 29, 2022
Simple form maker for Flutter Framework

Flutter FormBuilder - flutter_form_builder This package helps in creation of data collection forms in Flutter by removing the boilerplate needed to bu

Danvick Miller 1.2k Jan 3, 2023
A credit card widget for Flutter application.

A credit card widget for Flutter application.

Simform Solutions 281 Dec 27, 2022
Code generation for Flutter Padding widgets based on your constants

Code generation for Flutter Padding widgets based on your constants

Emanuele 14 Oct 20, 2022
A simple Flutter widget library that helps us to select days in a week.

A simple Flutter widget library that helps us to select days in a week.

Shan Shaji 4 Oct 9, 2022
Flutter debug helper widget with common and custom actions

Flutter debug helper widget with common and custom actions

Stanislav Ilin 43 Dec 7, 2022
A flutter plugin which provides Crop Widget for cropping images.

A flutter plugin which provides Crop Widget for cropping images.

Chooyan 97 Jan 5, 2023
Flutter Easy Getx Implementations .

People ask me how I manage state,dependency,routes etc when I work with flutter,Here is the Simple Brief About GetX which I used for Dummy Basic Ecommerce Concept based flutter app development .

Tasnuva Tabassum oshin 13 Oct 18, 2022
The Chicago widget set for Flutter

Chicago widget library The Chicago widget set is a retro 32-bit desktop design language for Flutter. It was discussed in the Building a desktop design

Todd Volkert 404 Dec 26, 2022
A draggable Flutter widget that makes implementing a Sliding up and fully-stretchable much easier.

Draggable Home A draggable Flutter widget that makes implementing a Sliding up and fully-stretchable much easier! Based on the Scaffold and Sliver. Us

Devs On Flutter 106 Dec 12, 2022