ApexTeam | Pana | Faam | PizzaTon Founder
اجرای متد بعد از ساخت کامل ویجت در فلاتر
تا حالا شده دلتون بخواد دقیقاً بعد از اینکه متد build توی یک statefulWidget صدا زده شد، یک snackbar نشون بدین یا مثلا یه دیالوگ به محض نمایش اولین لایه از یک ویجت نشون بدین؟
وقتی خواستم یه اسنکبار (SnackBar) ساده رو توی initState درست کنم یه جورایی nullPointerException گرفتم :D
class HomeScreen extends StatefulWidget {
@override
HomeScreenState createState() => new HomeScreenState();
}
class HomeScreenState extends State<HomeScreen> {
GlobalKey<ScaffoldState> _key = new GlobalKey();
@override
void initState() {
super.initState();
// NOTE: Calling this function here would crash the app.
showHelloWorld();
}
@override
Widget build(BuildContext context) {
return new Scaffold(key: _key, body: Container(color: Colors.red));
}
void showHelloWorld() {
_key.currentState.showSnackBar(SnackBar(
content: Text("HelloWorld"),
));
}
}
اروری که میگیرفتم این بود که یعنی هنوز ویجت رو نساختم و تو میخوای به اون ویجت دسترسی پیدا کنی و یه متد از currentState اون ویجت صدا بزنی؟
و اما واسه اینکه از این حدسم مطمئن بشم (چرا واقعا؟ نمیدونم) رفتم و داخل initState بجای اینکه showHelloWorld رو یهویی صدا بزنم با یه تاخیر کمی مثلا 5 ثانیه صداش میزنم که مطمئن باشم ویجتم ساخته شده ولی خب مسلماً این روش جالبی نیست :)
// Add this after super.initState();
Future.delayed(Duration(seconds: 5)).then((v) => showHelloWorld());
به قول بهتاش "من دیگه رد دادم" و رفتم سراغ دکتر گوگل عزیز و نتایج جالب بود :
- بعد از super.initState بیایم و از WidgetsBinding به شکل زیر استفاده کنیم.
توی داکیومنت فلاتر از WidgetsBinding به عنوان چسب بین لایه ویجت ها و موتور فلاتر نام برده شده. (The glue between the widgets layer and the Flutter engine) - و یا همین تیکه کد رو در قالب یه mixin به ویجت stateful خودتون اضافه کنید.
// Add this after super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => showHelloWorld(context));
از متد addPostFrameCallback برای اضافه کردن یک FrameCallback به انتهای فریم درحال اجرا استفاده میشه به این معنی که به محض اینکه فریم مربوط به رندر اولین لایه از این ویجت تموم بشه متد مورد نظر شما قابل اجراست و میتونه به المنت های رندر شده دسترسی داشته باشه (تکنیکالی).
OR
// Use this Mixin with your StatefulWidget
mixin WidgetLoadMixin<T extends StatefulWidget> on State<T> {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) => (context));
}
void (BuildContext context);
}
حالا کافیه متد رو override کنید و به راحتی هر کاری که میخواین بعد از لود شدن کامل ویجت انجام بشه توش بنویسید.
*** یه dependency هم هست که همین کار (mixin بالا) رو براتون انجام میده به اسم after layout که میتونید ازش استفاده کنید اما کدهای بالا کارتون رو راه میندازه.
امیدوارم از خوندن این مطلب لذت برده باشید.
مهدی باقری
مطلبی دیگر از این انتشارات
Dart Extension (افزونه های دارت)
مطلبی دیگر از این انتشارات
فلاتر دسکتاپ (Flutter Desktop)
مطلبی دیگر در همین موضوع
جای ادوارد هاپر خالی