| کانال توسعه‌دهندگان فلاتر |
1.95K subscribers
34 photos
1 video
16 links
⭕️ کانال توسعه‌دهندگان فلاتر دولوپیکس

💠 دولوپیکس | جامعه توسعه‌دهندگان ایرانی

💎 @Developix
🚀 Developix.ir

📌 پشتیبانی و تبلیغات:
@DevelopixSupport
Download Telegram
یک قطعه کد Dart مربوط به Flutter زیر را ببین:

سؤال:
خروجی نهایی اجرای این کد چیست؟
(به فاصله‌ها و خط‌های جدید در خروجی دقت کن)

راهنما: این کد از event loop، microtask و scheduleMicrotask در Dart استفاده می‌کند.

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
❤4
به این کد دقت کنید:

در نسخهٔ اول، برای هر build یک StreamSubscription جدید ساخته می‌شود و در dispose فقط آخرین مقدار نگه‌داری‌شده لغو می‌شود؛ این کار هم باعث Memory Leak می‌شود هم ممکن است چندین بار listener روی یک Stream داشته باشید و منجر به باگ‌های عجیب در UI شود.

در نسخهٔ دوم با انتقال listen به initState و نگه‌داری subscription در یک فیلد، از ساخت subscriptionهای تکراری جلوگیری شده و چرخهٔ حیات ویجت با Stream به‌درستی مدیریت می‌شود.

سؤال: در چنین سناریوهایی چرا استفاده از initState برای اتصال به Stream و آزاد کردن آن در dispose نسبت به ساخت subscription در متد build هم از نظر کارایی و هم از نظر پایداری برنامه انتخاب بهتری است؟

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
❤3
📱 سوال برای Flutter Devها

خروجی اجرای کد زیر در Dart چیست؟

به ترتیب خط‌ها و دقیقا همان چیزی که در console چاپ می‌شود را بنویسید.

نکته: به رفتار Future، حلقه‌ها و then دقت کنید؛ ترتیب اجرا ساده نیست 🙂

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
👎1
جدا کردن لایه UI از لایه منطق با Provider در Flutter 🧠👉📱

یکی از مهم‌ترین اصول Clean Architecture این است که UI و منطق (Business Logic) را قاطی هم نکنیم. تو Flutter خیلی وقت‌ها تمام منطق، فراخوانی API و state داخل همون فایل Widget اصلی می‌مونه و به‌مرور تبدیل می‌شود به یک God Widget که نگهداری‌اش سخت است 😅

یک راه‌حل ساده و استاندارد در Flutter استفاده از ChangeNotifier + Provider است. ایده اصلی:

• Widget فقط UI را رندر کند 🎨
• کلاس جداگانه state را مدیریت کند و منطق را در خود نگه دارد 🧩

۱. ساخت ViewModel (لایه منطق)
class CounterViewModel extends ChangeNotifier {
int _count = 0;

int get count => _count;

void increment() {
_count++;
notifyListeners();
}
}


اینجا هیچ خبری از BuildContext یا Widget نیست؛ فقط منطق و state. همین جداسازی ساده تست‌نویسی و نگهداری را خیلی راحت‌تر می‌کند ✅

۲. ثبت Provider در ریشه اپ
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => CounterViewModel(),
child: MaterialApp(
home: CounterPage(),
),
);
}
}


الان هر Widget زیرمجموعه می‌تواند به‌صورت امن و تمیز به CounterViewModel دسترسی داشته باشد.

۳. UI تمیز و سبک
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final viewModel = context.watch<CounterViewModel>();

return Scaffold(
appBar: AppBar(title: const Text('Counter')),
body: Center(
child: Text(
'Count: ${viewModel.count}',
style: const TextStyle(fontSize: 32),
),
),
floatingActionButton: FloatingActionButton(
onPressed: viewModel.increment,
child: const Icon(Icons.add),
),
);
}
}


توجه کنید که این Widget:
• هیچ state داخلی با setState() ندارد
• فقط از ViewModel می‌خواند و متدهای آن را صدا می‌زند

نکات مهم برای Clean Code با Provider ✨
• منطق async مثل call به API را در ViewModel قرار دهید، نه داخل Widget.
• هر صفحه شلوغ را به چند ViewModel کوچک‌تر و تخصصی تقسیم کنید.
• از context.select<T, R>() برای listen کردن به بخشی از state استفاده کنید تا rebuildها کم شود.

مستندات رسمی Provider و الگوهای پیشنهادی Flutter را می‌توان اینجا دید:
flutter.dev – State management

این جداسازی ساده، قدم بزرگی به سمت معماری تمیز، تست‌پذیر و مقیاس‌پذیر در پروژه‌های Flutter است. از همین امروز در یکی از صفحات شلوغ پروژه‌ات پیاده‌اش کنید و احساس سبکی کد را ببینید 🚀

🔖 #Flutter #فلاتر #Flutter #Clean_Code #Provider #State_Management #Architecture #Dart

👤 Developix

💎 Channel: @DevelopixFlutter
❤6🔥1
🔍 در کد زیر یک Memory Leak و استفاده‌ی اشتباه از Timer در یک StatefulWidget وجود دارد که می‌تواند باعث کرش یا رفتار غیرقابل‌پیش‌بینی در اپ شود. به‌طوری که بعد از ترک صفحه، تایمر همچنان در حال اجرا می‌ماند و به setState روی یک State تخریب‌شده صدا می‌زند.

چه چیزی باید در این کد اصلاح شود تا هم Memory Leak برطرف شود و هم مدیریت Timer به‌درستی انجام شود؟

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
👍6👎2
در نمونه‌کد بالا در نسخهٔ اشتباه، برای هر rebuild ویجت، یک Stream جدید ساخته می‌شود و listen روی آن ثبت می‌گردد که هم باعث Memory Leak می‌شود و هم روی کارایی اسکرول و رندر لیست تأثیر منفی می‌گذارد. در نسخهٔ بهینه با نگه‌داشتن Stream در State و استفاده از StreamBuilder تنها یک بار استریم ساخته شده و مدیریت subscription و cancel به صورت امن انجام می‌شود. این روش هم کد را تمیزتر می‌کند و هم در لیست‌های بزرگ، فشار روی GC و Scheduler را کاهش می‌دهد.

🔹 پرسش: اگر بخواهید در یک صفحهٔ پیچیده با چندین Stream مختلف، این الگو را به شکل تمیزتر و قابل تست‌تر پیاده‌سازی کنید، ترجیح می‌دهید از چه معماری یا State Managementای (مثل Bloc، Riverpod، Cubit و غیره) استفاده کنید و چرا؟

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
Forwarded from ابر ویراک
ویراک کلود | تجربه‌ی ابری بدون محدودیت ☁️🚀

🎁 ۲۰٪ شارژ هدیه روی اولین واریزی

مزیت‌هایی که واقعاً فرق می‌سازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راه‌اندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷

💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپ‌ها، تیم‌های فنی، تا سازمان‌های بزرگ

همین الان شروع کن و با حداکثر منابع، سریع‌تر رشد کن 👇🏻

📞 تماس سریع: 02191555530
🔗 https://virakcloud.com
❤1
‏اصل Single Responsibility توی ویجت‌های Flutter 🧩

یکی از راحت‌ترین راه‌ها برای تمیز و قابل‌نگهداری موندن کد Flutter اینه که واقعاً به Single Responsibility Principle (SRP) پایبند بمونیم.

طبق SRP هر کلاس باید فقط یک دلیل برای تغییر داشته باشه. توی Flutter یعنی هر ویجت بهتره فقط روی یک نقش مشخص تمرکز کنه: نمایش، منطق، یا مدیریت state؛ نه همۀ این‌ها با هم. 😄

وقتی یه صفحه همه‌چیزو قاطی خودش نگه می‌داره:
- تست‌نویسی سخت می‌شه
- ریفکتور خطرناک‌تر می‌شه
- کامپایل hot-reload کندتر حس می‌شه

نمونه‌ی یه ویجت خلاف SRP 👇
class ProfilePage extends StatefulWidget {
const ProfilePage({super.key});

@override
State<ProfilePage> createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
bool _loading = false;
String? _name;

Future<void> _loadProfile() async {
setState(() => _loading = true);
await Future.delayed(const Duration(seconds: 1));
setState(() {
_name = 'Ali';
_loading = false;
});
}

@override
void initState() {
super.initState();
_loadProfile();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Profile')),
body: Center(
child: _loading
? const CircularProgressIndicator()
: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(_name ?? 'Unknown'),
ElevatedButton(
onPressed: _loadProfile,
child: const Text('Reload'),
),
],
),
),
);
}
}


اینجا یک کلاس هم:
- API call شبیه‌سازی می‌کنه
- state رو نگه می‌داره
- UI کامل صفحه رو می‌سازه

حالا همون ایده رو با احترام به SRP تکه‌تکه می‌کنیم 👇

۱) جدا کردن منطق لود پروفایل
class ProfileController extends ChangeNotifier {
bool loading = false;
String? name;

Future<void> loadProfile() async {
loading = true;
notifyListeners();

await Future.delayed(const Duration(seconds: 1));

name = 'Ali';
loading = false;
notifyListeners();
}
}


۲) ویجت فقط مسئول نمایش
class ProfilePage extends StatelessWidget {
final ProfileController controller;

const ProfilePage({super.key, required this.controller});

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Profile')),
body: Center(
child: AnimatedBuilder(
animation: controller,
builder: (context, _) {
if (controller.loading) {
return const CircularProgressIndicator();
}
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(controller.name ?? 'Unknown'),
ElevatedButton(
onPressed: controller.loadProfile,
child: const Text('Reload'),
),
],
);
},
),
),
);
}
}


حالا:
- ProfileController فقط منطق و state رو مدیریت می‌کنه
- ProfilePage فقط رندر و تعامل UI رو انجام می‌ده

این الگو با Provider، Riverpod یا BLoC خیلی تمیزتر هم می‌شه و راحت‌تر تست واحد برای منطق می‌نویسیم.

برای مطالعه‌ی بیشتر می‌شه به معماری‌ها و راهنماهای رسمی Flutter سر زد:
State Management - flutter.dev

کم‌کم هر ویجت چاق رو به چند کلاس کوچک با یک وظیفۀ مشخص تبدیل کن و اجازه بده پروژه‌ات در طول زمان بدون ترس از ریفکتور رشد کنه 🚀

🔖 #Flutter #فلاتر #Flutter #Clean_Code #SRP #Architecture #State_Management #Dart

👤 Developix

💎 Channel: @DevelopixFlutter
🔥3
خروجی اجرای این کد Dart در Flutter چیست؟

در نظر بگیرید این کد در تابع main یک اپ Flutter اجرا می‌شود و ترتیب اجرا بین microtask queue و event queue اهمیت دارد.

خروجی نهایی (متن کامل چاپ‌شده روی کنسول با در نظر گرفتن ترتیب خطوط) چیست؟

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
📌 دسترسی به ۴ سرویس مهم حوزه برنامه‌نویسی روی اینترنت ملی مجدداً برقرار شد:

🔹 Vercel
https://vercel.com/

🔹 Next.js
https://nextjs.org/

🔹 SourceForge
https://sourceforge.net/

🔹 Let's Encrypt
https://letsencrypt.org/
این سرویس‌ها از ابزارهای مهم در توسعه، انتشار و امنیت پروژه‌ها محسوب می‌شوند.

🔖 #Flutter #فلاتر

👤 Alireza

💎 Channel: @DevelopixFlutter
در کد زیر سعی شده ترتیب اجرای کد هنگام صدا زدن runApp و استفاده از scheduleMicrotask و Future.microtask بررسی شود.

خروجی نهایی این برنامه (به‌ترتیب خطوط چاپ‌شده در کنسول) چه خواهد بود؟

پاسخ را دقیقا مطابق خروجی کنسول بنویسید، هر خط در یک سطر جدا.

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
در کد اشتباه بالا، هر بار که لیست اسکرول یا بازسازی می‌شود، متد _heavyComputation مستقیماً داخل build صدا زده می‌شود و عملاً هر بار محاسبات سنگین دوباره انجام می‌گیرد که باعث لگ، مصرف CPU بالا و افت فریم در لیست‌های بزرگ می‌شود.

در نسخه‌ی اصلاح‌شده، نتیجه‌ی محاسبه‌ی سنگین را یک بار در initState به کمک memoization و Future محاسبه کرده و با FutureBuilder فقط همان نتیجه‌ی کش‌شده را استفاده می‌کنیم؛ در نتیجه تعداد اجرای محاسبات سنگین به شدت کم می‌شود و عملکرد اسکرول در <ListView.builder> بهبود چشمگیری پیدا می‌کند.

به‌جای اجرای مستقیم محاسبات پرهزینه در متد build، از تکنیک‌هایی مانند memoization، FutureBuilder و جابه‌جا کردن منطق سنگین به initState استفاده کنید تا هم مصرف منابع کمتر شود و هم تجربه‌ی کاربری در لیست‌های پیچیده بهتر شود.

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
❤2🔥1
در نمونه‌کد بالا در نسخهٔ اول، برای هر بار ساختن ویجت، یک TextEditingController جدید داخل متد build ساخته می‌شود و هیچ‌وقت dispose نمی‌شود؛ این کار هم باعث Memory Leak می‌شود و هم روی پرفورمنس فرم‌های بزرگ اثر منفی دارد. در نسخهٔ دوم، کنترلر به‌صورت فیلد در State نگه‌داری شده، فقط یک‌بار در initState ساخته و در متد dispose آزاد می‌شود. شما در فرم‌های پیچیده و ویجت‌های stateful مشابه، کدام الگو را به‌عنوان روش استاندارد مدیریت Controller‌ها و منابع قابل dispose در Flutter استفاده می‌کنید تا هم از Memory Leak جلوگیری شود و هم مصرف مموری و زمان رندر کنترل شود؟

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
❤4
Forwarded from Developix Support
This media is not supported in your browser
VIEW IN TELEGRAM
🏆آفرهای جام جهانی ۲۰۲۶ هاست‌ایران فعال شد!

با کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافیک آماده کن:

🔥 ۲۵٪ تخفیف روی پلن‌های ۳ ماهه هاست اشتراکی ایران
⚡ ۵۰٪ تخفیف روی پلن‌های یک‌ماهه سرویس ابری در دیتاسنترهای تهران، مشهد و اهواز

🧠 مشاوره رایگان زیرساخت توسط کارشناسان هاست‌ایران
فرصت استفاده از تخفیف‌ها و ثبت فرم مشاوره محدود است.

📌 برای کپی کدهای تخفیف و ثبت‌نام در فرم مشاوره، روی لینک زیر کلیک کنید:

📌صفحه فرم مشاوره
📌تلگرام هاست‌ایران
📌بله هاست‌ایران


#هاست_ایران #سرور_ابری_هاست_ایران #هاست_اشتراکی #دیتاسنتر #مشاوره_زیرساخت #جام_جهانی2026
💠 نسخه جدید کتابخانه Dio منتشر شده است

🔸 ارتقا از نسخه 5.9.2 به 5.10.0

🔖 #dio, #flutter, #release

💎 @DevelopixFlutter
👍4❤1
در نمونه‌کد بالا در نسخهٔ اول داخل StreamBuilder برای هر رویداد استریم از setState() استفاده شده؛ در حالی‌که خود ویجت StreamBuilder با هر تغییر در stream ری‌بیلد می‌شود و نیازی به مدیریت دستی state نیست. این کار می‌تواند باعث ری‌بیلدهای اضافی، پیچیدگی بیشتر و بروز باگ در سناریوهای پیچیده‌تر شود. در نسخهٔ دوم با تکیه بر snapshot و حذف setState()، هم کد تمیزتر شده و هم رفتار UI قابل پیش‌بینی‌تر و کاراتر می‌شود. در چنین مواقعی ترجیح می‌دهید state را چطور مدیریت کنید؟

🔖 #Flutter #فلاتر

👤 Developix

💎 Channel: @DevelopixFlutter
❤2👍2