tutorial_coach_mark.dart
Fri Sep 06 2024 12:23:37 GMT+0000 (Coordinated Universal Time)
Saved by @mehran
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:ghalam_jadoee/pages/Addpage.dart'; import 'package:lottie/lottie.dart'; import 'package:tutorial_coach_mark/tutorial_coach_mark.dart'; import 'package:url_launcher/url_launcher.dart'; final Uri _url = Uri.parse('https://t.me/ir_samstudio'); final Uri _url2 = Uri.parse('info@samstudio.app'); void main() { runApp(const MaterialApp( home: About(), )); } class About extends StatefulWidget { const About({super.key}); @override State<About> createState() => _AboutState(); } TutorialCoachMark? tutorialCoachMark; List<TargetFocus> targets = []; GlobalKey Samkey = GlobalKey(); GlobalKey telkey = GlobalKey(); GlobalKey bazarkey = GlobalKey(); @override void initState() {} bool DarkMod = false; class _AboutState extends State<About> { @override void initState() { super.initState(); Future.delayed(const Duration(seconds: 1), () { _showtutorialCoachmark(); }); } void _showtutorialCoachmark() { _initTaget(); tutorialCoachMark = TutorialCoachMark( targets: targets, pulseEnable: false, colorShadow: Colors.black, hideSkip: true) ..show(context: context); } void _initTaget() { targets.addAll([ TargetFocus( identify: "Sam", keyTarget: Samkey, shape: ShapeLightFocus.RRect, contents: [ TargetContent( align: ContentAlign.top, builder: (context, controller) { return CoachmarkDesc( text: "نام تجاری شرکت که با الگو از مختصر اسامی اصلی اعضا تیم است", onNext: () { controller.next(); }, onSkip: () { controller.skip(); }, ); }, ), ], ), TargetFocus( identify: "tel_key", keyTarget: telkey, contents: [ TargetContent( align: ContentAlign.bottom, builder: (context, controller) { return CoachmarkDesc( text: "شما میتوانید با عضو شدن در شبگه های اجتماعی از اخرین تغییرات خبردار شوید", onNext: () { controller.next(); }, onSkip: () { controller.skip(); }, ); }, ), ], ), TargetFocus( identify: "bazar_key", keyTarget: bazarkey, shape: ShapeLightFocus.RRect, contents: [ TargetContent( align: ContentAlign.bottom, builder: (context, controller) { return CoachmarkDesc( text: "با ثبت نظر در بازار به توسعه برنامه کمک کنید", next: "شروع", onNext: () { controller.next(); }, onSkip: () { controller.skip(); }, ); }, ), ]) ]); } @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { double width = constraints.maxWidth; bool maxWidth = width > 360 ? true : false; print(width); return Scaffold( backgroundColor: DarkMod == false ? const Color.fromARGB(255, 240, 240, 240) : Colors.grey[850], body: Directionality( textDirection: TextDirection.rtl, child: Stack( children: [ Positioned( top: MediaQuery.of(context).size.height * 0.2, left: 0, right: 0, child: Lottie.asset( 'assets/images/welcome1.json', width: MediaQuery.of(context).size.width * 0.3, height: MediaQuery.of(context).size.height * 0.3, fit: BoxFit.fill, ), ), Positioned( top: 0, left: 0, right: 0, child: ClipPath( clipper: WaveClipper(), child: Container( height: MediaQuery.of(context).size.height * 0.16, color: const Color.fromRGBO(112, 27, 248, 1), alignment: Alignment.center, child: const Text( 'درباره ما', style: TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, fontFamily: 'Iranian_Sans'), ), ), ), ), Positioned( top: MediaQuery.of(context).size.height * 0.5, left: 0, right: 0, child: Container( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Center( child: Text( key: Samkey, 'SAM Studio', style: TextStyle( fontSize: maxWidth ? 22 : 12, fontWeight: FontWeight.bold, fontFamily: 'Iranian_Sans', color: DarkMod == false ? Colors.grey[850] : Colors.white, ), ), ), const SizedBox(height: 35), Padding( padding: const EdgeInsets.only(right: 20), key: telkey, child: Text( 'راههای ارتباطی:', style: TextStyle( fontSize: maxWidth ? 16 : 10, fontWeight: FontWeight.bold, fontFamily: 'Iranian_Sans', color: DarkMod == false ? Colors.grey[850] : Colors.white, ), ), ), const SizedBox(height: 10), Container( width: MediaQuery.of(context).size.width, child: Padding( padding: EdgeInsets.all( maxWidth ? 18 : 0, ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.center, children: [ FittedBox( fit: BoxFit.contain, child: ElevatedButton( onPressed: () { _launchUrl(); }, child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.telegram, color: const Color.fromRGBO( 112, 27, 248, 1), size: maxWidth ? 18 : 9, ), SizedBox( width: maxWidth ? 8 : 1, ), Text( 'تلگرام', style: TextStyle( fontSize: maxWidth ? 16 : 9, color: const Color.fromRGBO( 112, 27, 248, 1), ), ), ], ), ), ), Padding( padding: const EdgeInsets.only(right: 10), child: FittedBox( fit: BoxFit.contain, child: ElevatedButton( onPressed: () { Clipboard.setData(const ClipboardData( text: 'info@samstudio.app')); ScaffoldMessenger.of(context) .showSnackBar(const SnackBar( content: Text( 'ایمیل برای شما کپی شد', textDirection: TextDirection.rtl))); }, child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( size: maxWidth ? 18 : 9, Icons.email, color: const Color.fromRGBO( 112, 27, 248, 1), ), SizedBox( width: maxWidth ? 8 : 1, ), Text( 'ایمیل', style: TextStyle( fontSize: maxWidth ? 16 : 9, color: const Color.fromRGBO( 112, 27, 248, 1), ), ), ], ), ), ), ), Padding( padding: const EdgeInsets.only(right: 10), child: FittedBox( fit: BoxFit.contain, child: ElevatedButton( onPressed: () { // _launchURL('https://eitaa.com/your_eitaa_handle'); }, child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon( size: maxWidth ? 18 : 9, Icons.message, color: const Color.fromRGBO( 112, 27, 248, 1), ), SizedBox( width: maxWidth ? 8 : 1, ), Text( 'ایتا', style: TextStyle( fontSize: maxWidth ? 16 : 9, color: const Color.fromRGBO( 112, 27, 248, 1), ), ), ], ), ), ), ), ], ), ), ), SizedBox( height: maxWidth ? 30 : 10, ), Center( key: bazarkey, child: ElevatedButton( onPressed: () { // _launchURL('https://cafebazaar.ir/app/your_app_id'); }, style: ElevatedButton.styleFrom( minimumSize: const Size(double.infinity, 50), backgroundColor: const Color.fromRGBO(112, 27, 248, 1), ), child: const Text( 'ثبت نظر در کافه بازار', style: TextStyle( fontSize: 20, color: Colors.white, fontWeight: FontWeight.bold, fontFamily: 'Iranian_Sans'), ), ), ), ], ), ), ), ], ), ), ); }); } Future<void> _launchUrl() async { if (!await launchUrl(_url)) { throw Exception('Could not launch $_url'); } } } class WaveClipper extends CustomClipper<Path> { @override Path getClip(Size size) { var path = Path(); path.lineTo(0, size.height - 50); path.quadraticBezierTo( size.width / 2, size.height, size.width, size.height - 50, ); path.lineTo(size.width, 0); path.close(); return path; } @override bool shouldReclip(CustomClipper<Path> oldClipper) => true; } class CoachmarkDesc extends StatefulWidget { const CoachmarkDesc({ super.key, required this.text, this.skip = "رد کردن", this.next = "بعدی", this.onSkip, this.onNext, }); final String text; final String skip; final String next; final void Function()? onSkip; final void Function()? onNext; @override State<CoachmarkDesc> createState() => _CoachmarkDescState(); } class _CoachmarkDescState extends State<CoachmarkDesc> with SingleTickerProviderStateMixin { late AnimationController animationController; @override void initState() { animationController = AnimationController( vsync: this, lowerBound: 0, upperBound: 20, duration: const Duration(milliseconds: 800), )..repeat(reverse: true); super.initState(); } @override void dispose() { animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Directionality( textDirection: TextDirection.rtl, child: AnimatedBuilder( animation: animationController, builder: (context, child) { return Transform.translate( offset: Offset(0, animationController.value), child: child, ); }, child: Container( padding: const EdgeInsets.all(15), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( widget.text, style: Theme.of(context).textTheme.bodyMedium, ), const SizedBox(height: 16), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ TextButton( onPressed: widget.onSkip, child: Text(widget.skip), ), const SizedBox(width: 16), ElevatedButton( onPressed: widget.onNext, child: Text(widget.next), ), ], ), ], ), ), ), ); } }
Comments