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 446 forks source link

Exception: Please provide ShowCaseView context #123

Closed bossbeagle1509 closed 3 years ago

bossbeagle1509 commented 3 years ago

When I try to begin the showcase I get an error saying Exception: Please provide ShowCaseView context.

Here's my code for the page:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:showcaseview/showcaseview.dart';

class Guide extends StatefulWidget {
  const Guide({Key? key}) : super(key: key);

  @override
  _GuideState createState() => _GuideState();
}

class _GuideState extends State<Guide> {
  final GlobalKey _one = GlobalKey();
  final GlobalKey _two = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          IconButton(
            onPressed: () {
              ShowCaseWidget.of(context)!.startShowCase(
                [
                  _one,
                  _two,
                ],
              );
            },
            icon: const Icon(
              CupertinoIcons.power,
            ),
          )
        ],
      ),
      body: ShowCaseWidget(
        builder: Builder(
          builder: (context) => Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              // crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Showcase(
                  key: _one,
                  description: 'This shows you what day today is.',
                  child: const Text(
                    'Today is Wensten :)',
                  ),
                ),

                // for some space
                const SizedBox(
                  height: 40,
                ),

                Showcase(
                  key: _two,
                  description: 'This shows you what the weather is.',
                  child: const Text(
                    'And it may rain :(',
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

This issue has been mentioned by several others, but no one has taken the time to respond. A successful package need not depend on class leading features, but rather on an active community and responsive repo owners.

Please do respond, even if not to point out whatever mistake I'm making.

Thanks, Pranav

BirjuVachhani commented 3 years ago

Hey, It seems that ShowcaseWidget is not the root of your tree and you're trying to access it in IconButton.

bossbeagle1509 commented 3 years ago

Hey @BirjuVachhani ! Thank you so much for reverting !

I need the showcase to to trigger via a button, not on a page bein initialised, hence the button's onPressed is being used.

This is is simply one of the pages in a sample app I built to try the package. What do you mean by it is not the root of my tree ? Where do you suggest I place the required widget ?

BirjuVachhani commented 3 years ago

@bossbeagle1509 What I mean is to put ShowCaseWidget above the Scaffold and use builder's context to do ShowCaseWidget.of(context).

bossbeagle1509 commented 3 years ago

Ok, I changed it to this:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:showcaseview/showcaseview.dart';

class Guide extends StatefulWidget {
  const Guide({Key? key}) : super(key: key);

  @override
  _GuideState createState() => _GuideState();
}

class _GuideState extends State<Guide> {
  final GlobalKey _one = GlobalKey();
  final GlobalKey _two = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return ShowCaseWidget(
      builder: Builder(
        builder: (context) => Scaffold(
          appBar: AppBar(
            actions: [
              IconButton(
                onPressed: () {
                  ShowCaseWidget.of(context)!.startShowCase(
                    [
                      _one,
                      _two,
                    ],
                  );
                },
                icon: const Icon(
                  CupertinoIcons.power,
                ),
              )
            ],
          ),
          body: ShowCaseWidget(
            builder: Builder(
              builder: (context) => Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Showcase(
                      key: _one,
                      title: 'blah blah',
                      description: 'This shows you what day today is.',
                      child: const Text(
                        'Today is Wensten :)',
                      ),
                    ),

                    // for some space
                    const SizedBox(
                      height: 40,
                    ),

                    Showcase(

                      key: _two,
                      description: 'This shows you what the weather is.',
                      title: 'blah blah',
                      child: const Text(
                        'And it may rain :(',
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

But now I get no error and it still doesn't work :(

bossbeagle1509 commented 3 years ago

Ok so I managed to get it to work by moving the button down to be within the Column,

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:showcaseview/showcaseview.dart';

class Guide extends StatefulWidget {
  const Guide({Key? key}) : super(key: key);

  @override
  _GuideState createState() => _GuideState();
}

class _GuideState extends State<Guide> {
  final GlobalKey _one = GlobalKey();
  final GlobalKey _two = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return ShowCaseWidget(
      builder: Builder(
        builder: (context) => Scaffold(
          // appBar: AppBar(
          //   actions: [
          //     IconButton(
          //       onPressed: () {
          //         ShowCaseWidget.of(context)!.startShowCase(
          //           [
          //             _one,
          //             _two,
          //           ],
          //         );
          //       },
          //       icon: const Icon(
          //         CupertinoIcons.power,
          //       ),
          //     )
          //   ],
          // ),
          body: ShowCaseWidget(
            builder: Builder(
              builder: (context) => Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    // to trigger
                    IconButton(
                      onPressed: () {
                        ShowCaseWidget.of(context)!.startShowCase(
                          [
                            _one,
                            _two,
                          ],
                        );
                      },
                      icon: const Icon(
                        CupertinoIcons.power,
                      ),
                    ),

                    const SizedBox(
                      height: 100,
                    ),

                    // a showcase
                    Showcase(
                      key: _one,
                      title: 'blah blah',
                      description: 'This shows you what day today is.',
                      child: const Text(
                        'Today is Wensten :)',
                      ),
                    ),

                    // for some space
                    const SizedBox(
                      height: 40,
                    ),

                    // a showcase
                    Showcase(
                      key: _two,
                      description: 'This shows you what the weather is.',
                      title: 'blah blah',
                      child: const Text(
                        'And it may rain :(',
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

but is it not possible to have the button in the AppBar ?

BirjuVachhani commented 3 years ago

You are having 2 ShowcaseWidget. Remove the one in the body. I think it should work then. Avoid shadowing the context of Builder with the context of build method. Rename Builder's context to ctx and use it in ShowcaseWidget.of(ctx).

bossbeagle1509 commented 3 years ago

Fantabulous ! Works great now !

Thank you so much for your time and the suggestions ! I'm closing the issue now.