SimformSolutionsPvtLtd / flutter_showcaseview

Flutter plugin that allows you to showcase your features on flutter application. 👌🔝🎉
https://pub.dev/packages/showcaseview
MIT License
1.53k stars 445 forks source link

Create showcase for widget with dynamic size #153

Closed erperejildo closed 8 months ago

erperejildo commented 3 years ago

I've got a Grid inside a Flexible. How could I apply a showcase for it?

meetjanani-simformsolutions commented 3 years ago

@erperejildo could you please share more info like how you are using currently & what type of issues are facing.

erperejildo commented 3 years ago

This is my widget:

Flexible(
          child: GridView.count(
            childAspectRatio:
                Provider.of<MyRents>(context).viewMode == 'detailed' ? 3 : 1,
            padding: const EdgeInsets.symmetric(horizontal: 2.5, vertical: 2.5),
            crossAxisCount: Provider.of<MyRents>(context).viewMode == 'detailed'
                ? deviceWidth > 700
                    ? 2
                    : 1
                : deviceWidth > 700
                    ? (deviceWidth * 0.006).round()
                    : 3,
            mainAxisSpacing: 0.0,
            crossAxisSpacing: 0.0,
            children: <Widget>[
              ...widget.portfolio["rents"].map(
                (rent) {
                  index++;
                  return RentCard(index, rent);
                },
              ),
              Visibility(
                visible: !authService.disabledPortfolio(context),
                child: NewRent(),
              ),
            ],
          ),
        ),

And this is the UI (you can see i inside the white area, the 3 cards): Screenshot_1634060083

So if I wrap the above widget with this:

Showcase(
        overlayPadding: EdgeInsets.all(5),
        key: one,
        disposeOnTap: true,
        onTargetClick: () => print("CLICK"),
        title: 'Create an account',
        description:
        'You can now create your account and start adding your properties',
        contentPadding: EdgeInsets.all(16.0),
        showcaseBackgroundColor: Theme.of(context).primaryColor,
        textColor: Colors.white,
        child: ...

I get these errors:

Performing hot reload...
Syncing files to device Android SDK built for x86...
I/flutter (19010): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (19010): The following assertion was thrown while applying parent data.:
I/flutter (19010): Incorrect use of ParentDataWidget.
I/flutter (19010): The ParentDataWidget Flexible(flex: 1) wants to apply ParentData of type FlexParentData to a
I/flutter (19010): RenderObject, which has been set up to accept ParentData of incompatible type BoxParentData.
I/flutter (19010): Usually, this means that the Flexible widget has the wrong ancestor RenderObjectWidget. Typically,
I/flutter (19010): Flexible widgets are placed directly inside Flex widgets.
I/flutter (19010): The offending Flexible is currently placed inside a LayoutBuilder widget.
I/flutter (19010): The ownership chain for the RenderObject that received the incompatible parent data was:
I/flutter (19010):   RepaintBoundary ← NotificationListener<ScrollNotification> ← GlowingOverscrollIndicator ←
I/flutter (19010): Scrollable ← PrimaryScrollController ← GridView ← Flexible ← OverlayBuilder ← LayoutBuilder ←
I/flutter (19010): AnchoredOverlay ← ⋯
I/flutter (19010): 
I/flutter (19010): When the exception was thrown, this was the stack:
I/flutter (19010): #0      RenderObjectElement._updateParentData.<anonymous closure> (package:flutter/src/widgets/framework.dart:5835:11)
I/flutter (19010): #1      RenderObjectElement._updateParentData (package:flutter/src/widgets/framework.dart:5851:6)
I/flutter (19010): #2      RenderObjectElement.attachRenderObject (package:flutter/src/widgets/framework.dart:5873:7)
I/flutter (19010): #3      RenderObjectElement.mount (package:flutter/src/widgets/framework.dart:5544:5)
I/flutter (19010): #4      SingleChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6194:11)
I/flutter (19010): ...     Normal element mounting (49 frames)
I/flutter (19010): #53     Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14)
I/flutter (19010): #54     Element.updateChild (package:flutter/src/widgets/framework.dart:3425:18)
I/flutter (19010): #55     _LayoutBuilderElement._layout.layoutCallback (package:flutter/src/widgets/layout_builder.dart:137:18)
I/flutter (19010): #56     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2573:19)
I/flutter (19010): #57     _LayoutBuilderElement._layout (package:flutter/src/widgets/layout_builder.dart:154:12)
I/flutter (19010): #58     RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:1968:59)
I/flutter (19010): #59     PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:916:15)
I/flutter (19010): #60     RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:1968:14)
I/flutter (19010): #61     RenderConstrainedLayoutBuilder.rebuildIfNecessary (package:flutter/src/widgets/layout_builder.dart:228:7)
I/flutter (19010): #62     _RenderLayoutBuilder.performLayout (package:flutter/src/widgets/layout_builder.dart:363:5)
I/flutter (19010): #63     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
I/flutter (19010): #64     ChildLayoutHelper.layoutChild (package:flutter/src/rendering/layout_helper.dart:56:11)
I/flutter (19010): #65     RenderFlex._computeSizes (package:flutter/src/rendering/flex.dart:829:43)
I/flutter (19010): #66     RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:931:32)
I/flutter (19010): #67     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
I/flutter (19010): #68     RenderPositionedBox.performLayout (package:flutter/src/rendering/shifted_box.dart:437:14)
I/flutter (19010): #69     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
I/flutter (19010): #70     RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:277:14)
I/flutter (19010): #71     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
I/flutter (19010): #72     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
I/flutter (19010): #73     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
I/flutter (19010): #74     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:116:14)
I/flutter (19010): #75     RenderObject.layout (package:flutter/src/rendering/object.dart:1858:7)
I/flutter (19010): #76     RenderSliverFixedExtentBoxAdaptor.performLayout (package:flutter/src/rendering/sliver_fixed_extent_list.dart:240:19)

it continues

But basically I think the error is related to the non fixed height element

meetjanani commented 3 years ago

@erperejildo yes, seems like its related to nonfixed height/width, Showcase Widget requires its Child widget of fix/calculable sized of widget, could you please try by removing Flexible Widget & if required then add shrinkWrap: true property inside GridView.Count() widget

erperejildo commented 3 years ago

still same error. Any possibility of passing height/width and position to the Showcase?

d9media commented 2 years ago

hey @erperejildo I wrapped up my child widget within the row in a sizedbox but Flutter is throwing Incorrect use of ParentDataWidget errors. So annoying! Did you end up solving this somehow?

erperejildo commented 2 years ago

hey @erperejildo I wrapped up my child widget within the row in a sizedbox but Flutter is throwing Incorrect use of ParentDataWidget errors. So annoying! Did you end up solving this somehow?

nope. I gave up

d9media commented 2 years ago

Oh no! Sorry to hear that!

I ended up solving it by passing my own ShowcaseOptions object to the flexible widget. If that is present in the widget, I show it above the container. Works.

class ShowcaseOptions {
  final GlobalKey globalKey;
  final String key;
  final String title;
  final String description;

  ShowcaseOptions(
      {required this.globalKey,
      required this.key, // <-- I was gonna use this for globalstorage but didnt end up use it currently
      required this.title,
      required this.description});
}

class ShowcaseSteps {
  final GlobalKey mainMenu = GlobalKey();
  final GlobalKey locationChip = GlobalKey();
  final GlobalKey timecardWork = GlobalKey();
  final GlobalKey timecardBreak = GlobalKey();
  final GlobalKey timeButtons = GlobalKey();
  final GlobalKey weeklyNavigation = GlobalKey();
  final GlobalKey weeklyPending = GlobalKey();
  final GlobalKey weeklyEditEntry = GlobalKey();
}

In the flexible widget:

TimeCard(
      title: "",
      showcaseOptions: ShowcaseOptions(
             description: "showcase desc",
             title: "showcase title",
             globalKey: _showcaseSteps.timecardWork,
             key: "timecard_work"),
     // other properties
         ),

and inside the flexible widget (timecard):

@override
  Widget build(BuildContext context) {
    final Widget innerContent = Container(
      height: compactHeight ? 150 : 200,
      // and other content
    );

    return Expanded(
      child: showcaseOptions == null
          ? innerContent
          : Showcase(
              key: showcaseOptions!.globalKey,
              description: showcaseOptions!.description,
              title: showcaseOptions!.title,
              child: innerContent),
    );

I agree fixed size parameters might be easier though

aditya-css commented 9 months ago

Hi @erperejildo, Seems like you have wrapped Showcase over the Flexible and Grid.count widget. The error is specifically saying that only: "Incorrect use of ParentDataWidget"...... "Typically, Flexible widgets are placed directly inside Flex widgets". Please have the Flexible widget as parent of Showcase instead and your issue would be resolved.