What is a Show Case and why do we implement it? This article will explore the Implement ShowCase package We will see how to implement it in a program. It will show a highlight of our app using the showcase view package in your flutter applications. An extraordinary application UI limits the friction between user and application usefulness. A method for decreasing that grating is to feature and showcase the parts of your application. This is useful when a user launches your application interestingly. With the assistance of the Showcase view and ShowCaseWidget widget, we can showcase the feature in the Flutter application. It is most important when the user enters the user app for the first time this Showcase view understands the user how to use this app. Now go to the coding part.
Step 1: First add the Showcase view package
Open your pubspec.yaml file and add showcaseview: ^2.0.0+1 package into our app
dependencies: showcaseview: ^2.0.0+1
Step 2: Open your main.dart file
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:showcaseview/showcaseview.dart'; import 'ShowCase/show_case.dart'; void main() { WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setEnabledSystemUIMode(SystemUiMode.immersiveSticky, overlays:[]).then( (_) => runApp(MyApp()), ); // runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( debugShowCheckedModeBanner: false, home: ShowCaseWidget( builder: Builder( builder: (_)=>ShowCasePage(), ), ) ); } }
Step 3: Create and open ShowCasePage.dart file
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; class ShowCasePage extends StatefulWidget { const ShowCasePage({Key? key}) : super(key: key); @override State<ShowCasePage> createState() => _ShowCasePageState(); } class _ShowCasePageState extends State<ShowCasePage> { @override void initState() { // TODO: implement initState super.initState(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color(0xFFE9E9E9), appBar: PreferredSize( preferredSize: const Size.fromHeight(130.0), child: AppBar( automaticallyImplyLeading: false, toolbarHeight: 60.0, flexibleSpace: Container( margin: EdgeInsets.only(top: 60, left: 20, right: 20), child: TextField( decoration: InputDecoration( border: InputBorder.none, filled: true, fillColor: Colors.white, labelText: 'Search friends..', labelStyle: TextStyle(color: Colors.grey, fontSize: 14), floatingLabelBehavior: FloatingLabelBehavior.never, enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), prefixIcon: Icon( Icons.search, color: Colors.black54, size: 16, ), ), keyboardType: TextInputType.text, textInputAction: TextInputAction.done, ), ), backgroundColor: Color(0xffEE5366), elevation: 0, title: Text( 'Find Friends', style: TextStyle( fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold, fontStyle: FontStyle.normal), ), centerTitle: true, leading: IconButton( onPressed: () {}, icon: Icon( Icons.menu, color: Colors.white, ), ), actions: [ IconButton(icon: Icon(Icons.notifications, color: Colors.white,), onPressed: () {},), IconButton(icon: Icon(Icons.person, color: Colors.white,), onPressed: () {},), ], ), ), floatingActionButton: FloatingActionButton( backgroundColor: Color(0xffEE5366), onPressed: () { }, child: Icon(Icons.add, color: Colors.white,), ), body: SingleChildScrollView( child: Column( children: <Widget>[ ListTile( title: Text('Naina'), subtitle: Text('I miss you 💔💔'), leading: CircleAvatar(backgroundImage: NetworkImage('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR8CEeCVSxAKNsx56oDjEce0g23Deg02wTnUh6toHKeROC_7DDnnvyBDlXeBoOBU0-Wbg8&usqp=CAU'), radius: 30,), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Aakash'), subtitle: Text('hii, how are you?'), leading: CircleAvatar( backgroundImage: NetworkImage('https://images.unsplash.com/photo-1570295999919-56ceb5ecca61?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bWFsZSUyMHByb2ZpbGV8ZW58MHx8MHx8&w=1000&q=80'), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Vaishali'), subtitle: Text('nice to meet you'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1311084168/photo/overjoyed-pretty-asian-woman-look-at-camera-with-sincere-laughter.jpg?s=612x612&w=0&k=20&c=akS4eKR3suhoP9cuk7_7ZVZrLuMMG0IgOQvQ5JiRmAg='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Divya'), subtitle: Text('I love you 💖💖💖'), leading: CircleAvatar( backgroundImage: NetworkImage('https://www.rd.com/wp-content/uploads/2017/09/01-shutterstock_476340928-Irina-Bg.jpg?fit=640,427'), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Sejal'), subtitle: Text('what are you doing..'), leading: CircleAvatar( backgroundImage: NetworkImage('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTlcEOxSIW6Gh2KlUB57JuLdQc7abhYGC0Nu1PcVFqKatiIwTSb3__-kGcH6BnkoY093NY&usqp=CAU'), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Vijay'), subtitle: Text('today meeting is good'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1309328823/photo/headshot-portrait-of-smiling-male-employee-in-office.jpg?b=1&s=170667a&w=0&k=20&c=MRMqc79PuLmQfxJ99fTfGqHL07EDHqHLWg0Tb4rPXQc='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Gorav'), subtitle: Text('can you send me your address'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1300972574/photo/millennial-male-team-leader-organize-virtual-workshop-with-employees-online.jpg?b=1&s=170667a&w=0&k=20&c=96pCQon1xF3_onEkkckNg4cC9SCbshMvx0CfKl2ZiYs='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Vishal'), subtitle: Text('today i am not coming'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/photos/young-handsome-man-with-beard-wearing-casual-sweater-standing-over-picture-id1212702108?b=1&k=20&m=1212702108&s=612x612&w=0&h=JWIsNF0hgwe_ALOV3-2vux7LSR6Nwm91ZtP322_uUPQ='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Jeck'), subtitle: Text('Tomorrow we meet?'), leading: CircleAvatar( backgroundImage: NetworkImage('https://t4.ftcdn.net/jpg/01/15/85/23/360_F_115852367_E6iIYA8OxHDmRhjw7kOq4uYe4t440f14.jpg'), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Sagar'), subtitle: Text('we loving it'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1335941248/photo/shot-of-a-handsome-young-man-standing-against-a-grey-background.jpg?b=1&s=170667a&w=0&k=20&c=Dl9uxPY_Xn159JiazEj0bknMkLxFdY7f4tK1GtOGmis='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Deepak'), subtitle: Text('hii, how are you?'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1372641621/photo/portrait-of-a-businessman-on-gray-background.jpg?s=612x612&w=0&k=20&c=G7RmU1vHuzqIscJDOVrUVRl_-yIOIl0ws3f4RRc8qHU='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ], ), ) ); } }
Output
Step 4: Create CoustomShowcaseWidget inside ShowCasePage file
class CoustomShowcaseWidget extends StatelessWidget{ final Widget child; final String title; final String description; final GlobalKey globalkey; CoustomShowcaseWidget(this.globalkey,this.title,this.description,this.child); @override Widget build(BuildContext context) => Showcase( key: globalkey, tooltipPadding: EdgeInsets.all(10), title: title, titleTextStyle: TextStyle(fontSize: 16,color: Colors.black,fontWeight: FontWeight.bold), description: description, descTextStyle: TextStyle(fontSize: 12,color: Colors.black), overlayColor: Colors.grey, overlayOpacity: 0.7, child: child, ); }
Crate a GlobalKey() and calling ShowCaseWidget initState() function because when the class is open then first open the ShowCaseWidget
class _ShowCasePageState extends State<ShowCasePage> { final keyOne = GlobalKey(); final keyTwo = GlobalKey(); final keyThree = GlobalKey(); final keyFour = GlobalKey(); @override void initState() { // TODO: implement initState super.initState(); WidgetsBinding.instance.addPostFrameCallback( (_) => ShowCaseWidget.of(context).startShowCase( [ keyOne, keyTwo, keyThree, keyFour, ] ) ); }
Step 5: Wrap with CoustomShowcaseWidget which is use for Showcase
CoustomShowcaseWidget( keyOne, 'Notification', 'all notification appear here', IconButton(icon: Icon(Icons.notifications, color: Colors.white,), onPressed: () {},), ),
Complete code is here
import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:showcaseview/showcaseview.dart'; class ShowCasePage extends StatefulWidget { const ShowCasePage({Key? key}) : super(key: key); @override State<ShowCasePage> createState() => _ShowCasePageState(); } class _ShowCasePageState extends State<ShowCasePage> { final keyOne = GlobalKey(); final keyTwo = GlobalKey(); final keyThree = GlobalKey(); final keyFour = GlobalKey(); @override void initState() { // TODO: implement initState super.initState(); WidgetsBinding.instance.addPostFrameCallback( (_) => ShowCaseWidget.of(context).startShowCase( [ keyOne, keyTwo, keyThree, keyFour, ] ) ); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color(0xFFE9E9E9), appBar: PreferredSize( preferredSize: const Size.fromHeight(130.0), child: AppBar( automaticallyImplyLeading: false, toolbarHeight: 60.0, flexibleSpace: Container( margin: EdgeInsets.only(top: 60, left: 20, right: 20), child: TextField( decoration: InputDecoration( border: InputBorder.none, filled: true, fillColor: Colors.white, labelText: 'Search friends..', labelStyle: TextStyle(color: Colors.grey, fontSize: 14), floatingLabelBehavior: FloatingLabelBehavior.never, enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), prefixIcon: Icon( Icons.search, color: Colors.black54, size: 16, ), ), keyboardType: TextInputType.text, textInputAction: TextInputAction.done, ), ), backgroundColor: Color(0xffEE5366), elevation: 0, title: Text( 'Find Friends', style: TextStyle( fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold, fontStyle: FontStyle.normal), ), centerTitle: true, leading: IconButton( onPressed: () {}, icon: Icon( Icons.menu, color: Colors.white, ), ), actions: [ CoustomShowcaseWidget( keyOne, 'Notification', 'all notification appear here', IconButton(icon: Icon(Icons.notifications, color: Colors.white,), onPressed: () {},), ), CoustomShowcaseWidget( keyTwo, 'Profile', 'your profile page is here', IconButton(icon: Icon(Icons.person, color: Colors.white,), onPressed: () {},), ), ], ), ), floatingActionButton: FloatingActionButton( backgroundColor: Color(0xffEE5366), onPressed: () { }, child: CoustomShowcaseWidget( keyFour, 'Add Users', 'add new users data by clickingthis button', Icon(Icons.add, color: Colors.white,), ), ), body: SingleChildScrollView( child: Column( children: <Widget>[ ListTile( title: Text('Naina'), subtitle: Text('I miss you 💔💔'), leading: CoustomShowcaseWidget( keyThree, 'Profile Pic', 'users profile pic apear here', CircleAvatar(backgroundImage: NetworkImage('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR8CEeCVSxAKNsx56oDjEce0g23Deg02wTnUh6toHKeROC_7DDnnvyBDlXeBoOBU0-Wbg8&usqp=CAU'), radius: 30,), ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Aakash'), subtitle: Text('hii, how are you?'), leading: CircleAvatar( backgroundImage: NetworkImage('https://images.unsplash.com/photo-1570295999919-56ceb5ecca61?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxzZWFyY2h8Mnx8bWFsZSUyMHByb2ZpbGV8ZW58MHx8MHx8&w=1000&q=80'), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Vaishali'), subtitle: Text('nice to meet you'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1311084168/photo/overjoyed-pretty-asian-woman-look-at-camera-with-sincere-laughter.jpg?s=612x612&w=0&k=20&c=akS4eKR3suhoP9cuk7_7ZVZrLuMMG0IgOQvQ5JiRmAg='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Divya'), subtitle: Text('I love you 💖💖💖'), leading: CircleAvatar( backgroundImage: NetworkImage('https://www.rd.com/wp-content/uploads/2017/09/01-shutterstock_476340928-Irina-Bg.jpg?fit=640,427'), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Sejal'), subtitle: Text('what are you doing..'), leading: CircleAvatar( backgroundImage: NetworkImage('https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTlcEOxSIW6Gh2KlUB57JuLdQc7abhYGC0Nu1PcVFqKatiIwTSb3__-kGcH6BnkoY093NY&usqp=CAU'), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.green,size: 10,), ), ListTile( title: Text('Vijay'), subtitle: Text('today meeting is good'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1309328823/photo/headshot-portrait-of-smiling-male-employee-in-office.jpg?b=1&s=170667a&w=0&k=20&c=MRMqc79PuLmQfxJ99fTfGqHL07EDHqHLWg0Tb4rPXQc='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Gorav'), subtitle: Text('can you send me your address'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1300972574/photo/millennial-male-team-leader-organize-virtual-workshop-with-employees-online.jpg?b=1&s=170667a&w=0&k=20&c=96pCQon1xF3_onEkkckNg4cC9SCbshMvx0CfKl2ZiYs='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Vishal'), subtitle: Text('today i am not coming'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/photos/young-handsome-man-with-beard-wearing-casual-sweater-standing-over-picture-id1212702108?b=1&k=20&m=1212702108&s=612x612&w=0&h=JWIsNF0hgwe_ALOV3-2vux7LSR6Nwm91ZtP322_uUPQ='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Jeck'), subtitle: Text('Tomorrow we meet?'), leading: CircleAvatar( backgroundImage: NetworkImage('https://t4.ftcdn.net/jpg/01/15/85/23/360_F_115852367_E6iIYA8OxHDmRhjw7kOq4uYe4t440f14.jpg'), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Sagar'), subtitle: Text('we loving it'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1335941248/photo/shot-of-a-handsome-young-man-standing-against-a-grey-background.jpg?b=1&s=170667a&w=0&k=20&c=Dl9uxPY_Xn159JiazEj0bknMkLxFdY7f4tK1GtOGmis='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ListTile( title: Text('Deepak'), subtitle: Text('hii, how are you?'), leading: CircleAvatar( backgroundImage: NetworkImage('https://media.istockphoto.com/id/1372641621/photo/portrait-of-a-businessman-on-gray-background.jpg?s=612x612&w=0&k=20&c=G7RmU1vHuzqIscJDOVrUVRl_-yIOIl0ws3f4RRc8qHU='), radius: 30, ), trailing: Icon(Icons.circle,color: Colors.grey,size: 10,), ), ], ), ) ); } } class CoustomShowcaseWidget extends StatelessWidget{ final Widget child; final String title; final String description; final GlobalKey globalkey; CoustomShowcaseWidget(this.globalkey,this.title,this.description,this.child); @override Widget build(BuildContext context) => Showcase( key: globalkey, tooltipPadding: EdgeInsets.all(10), title: title, titleTextStyle: TextStyle(fontSize: 16,color: Colors.black,fontWeight: FontWeight.bold), description: description, descTextStyle: TextStyle(fontSize: 12,color: Colors.black), overlayColor: Colors.grey, overlayOpacity: 0.7, child: child, ); }
Conclusion:
In the article, I have explained the Showcase basic and advanced structure in a flutter; you can change or modify this code according to your choice. This was a small introduction to Showcase On User Interaction and user experience when entering in your app from my side, and it’s working using Flutter.
I hope this blog will provide you with sufficient information on Trying the Implementing Showcase view in your flutter projects. Make a demo program for working Showcase using the showcaseview package in your flutter applications. So please try and enjoy it.
❤ ❤ Thanks for reading this article ❤❤
If I got something wrong? Let me know in the comments. I would love to improve.
Clap 👏 If this article helps you.
If you like my work then you also read this article also: How to Implementing Navigation Drawer Animation into Flutter, How to create a Scratch Card in flutter using a scratcher package, and How to implement Pattern lock screen into Flutter.