Provider — بسته مدیریت وضعیت برای Flutter، توسط Rémi Rousselet در سال 2019 به عنوان یک لایه بروی InheritedWidget ساخته شده است. Provider مسئله انتقال دادهها به پایین درخت ویجتها بدون props drilling را حل میکند: هر ویجتی از طریق context.read<T>() یا context.watch<T>() به وضعیت دسترسی پیدا میکند. بر اساس pub.dev، Provider محبوبترین مدیر وضعیت Flutter با بیش از 25 هزار لایک است.
نکات کلیدی
Provider — بستهای برای مدیریت وضعیت و وارد کردن وابستگیها در Flutter، ساخته شده بر روی InheritedWidget. Provider یک شیئ (وضعیت، سرویس، مخزن) را در درخت ویجتها در دسترس قرار میدهد و با تغییر دادهها به طور خودکار UI را بازسازی میکند. به عنوان مثال، شما میتوانید یک شیئ را در هر جایی بدون ارسال آن از طریق سازنده دسترسی پیدا کنید.
Provider — روش به صورت رسمی توصیه شده توسط Google برای مدیریت وضعیت در Flutter (Flutter Team، 2019-2023). این بسته بخشی از Flutter Ecosystem است و توسط تیم Flutter پشتیبانی میشود. در زمان انتشار، Provider به عنوان جایگزینی برای متغیرهای سراسری و InheritedWidget پیشنهاد شد. بر اساس Flutter Community Survey 2025، Provider در 72% برنامههای Flutter استفاده میشود.
ChangeNotifier — کلاس داخلی Flutter است که الگوی Listener را پیادهسازی میکند. ChangeNotifier از طریق فراخوانی notifyListeners() مشترکان را از تغییر مطلع میکند. در زمینه Provider، ChangeNotifier کلاس اصلی برای وضعیت است: کلاسی از ChangeNotifier مشتق میشود که با صدــــ و روشهایی که پس از تغییر دادهها notifyListeners() را فراخوان میکنند، ایجاد میکند.
class CounterProvider extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
void reset() {
_count = 0;
notifyListeners();
}
}قوانین notifyListeners: پس از تغییر کامل دادهها فراخوان شود — نه در وسط روش، بلکه در پایان. اگر روش چندین تغییر انجام میدهد، notifyListeners() را یک بار پس از تمامی تغییرات فراخوان کنید، نه پس از هر کدام.
جایگزینهای ChangeNotifier: ValueNotifier — برای یک مقدار تک (مناسب برای نوعهای ابتدایی)، StateNotifier — از بسته state_notifier (به ندرت به تنهایی استفاده میشود).
Consumer — ویجتی است که در ChangeNotifier مشترک میشود و با هر فراخوانی notifyListeners() بازسازی میشود. Consumer یک تابع builder با سه پارامتر میپذیرد: context، model، child. Child — ویجتی است که به مدل وابسته نیست و Consumer آن را بازسازی نمیکند. این یک بهینهسازی است: اگر درون Consumer یک ویجت استاتیک (آیکون، متن بدون داده) وجود داشته باشد، آن از طریق child ارسال میشود و مجدداً ایجاد نمیشود.
Consumer<CounterProvider>(
builder: (context, provider, child) => Column(
children: [
child!, // بازسازی نمیشود
Text('${provider.count}'),
ElevatedButton(
onPressed: () => provider.increment(),
child: Icon(Icons.add),
),
],
),
child: Text('شمارنده:'),
)context.watch — روش افزونه BuildContext برای مشترک شدن در Provider. مدل را برمیگرداند و ویجت فعلی را در تغییرات آن مشترک میکند. context.read — دسترسی بدون مشترک شدن (برای گیرندههای onPressed، initState و dispose). context.select — مشترک شدن در یک صدـ مشخص مدل بدون بازسازی در صورت تغییر سایر صدـها.
MultiProvider — ویجتی برای ثبت چند Provider بدون تودرتونگی. به جای درختی با 5 سطح Provider → Provider → Provider، MultiProvider یک لیست از providerها را میپذیرد. هر Provider بعدی میتواند از قبلیها از طریق سازنده استفاده کند. MultiProvider — روش استاندارد سازماندهی سطح ریشه برنامه است.
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => CartProvider()),
ChangeNotifierProvider(create: (_) => AuthProvider()),
ProxyProvider<AuthProvider, OrderProvider>(
update: (_, auth, __) => OrderProvider(auth.userId),
),
],
child: MaterialApp(home: HomePage()),
)ProxyProvider — Providerی که به Provider دیگری وابسته است. ProxyProvider مقادیر را از سایر providerها دریافت میکند و آنها را به شیئ خود ارسال میکند. به عنوان مثال، OrderProvider به AuthProvider وابسته است. ChangeNotifierProxyProvider — نسخه ProxyProvider برای ChangeNotifier.
StreamProvider و FutureProvider: StreamProvider در یک جریان (Firebase، WebSocket) مشترک میشود و Consumer را در هر رویداد جدید بهروز میکند. FutureProvider — برای مقداردهی اسینکرون: Future را اجرا میکند، بارگذاری را نشان میدهد، سپس نتیجه را به ویجتها ارسال میکند.
Provider آزمایش میشود با احاطه کردن ویجت در MultiProvider با مقادیر آزمایشی. برای آزمایش به API یا پایگاه داده واقعی نیاز نیست — Provider با یک شیئ مقلد جایگزین میشود. بسته provider از ProviderScope برای جداسازی آزمایشها استفاده میکند.
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Counter increments on button tap',
(tester) async {
await tester.pumpWidget(
ChangeNotifierProvider(
create: (_) => CounterProvider(),
child: CounterScreen(),
),
);
await tester.tap(find.byKey(Key('increment')));
await tester.pump();
expect(find.text('1'), findsOneWidget);
},
);
}MockProvider: برای آزمایش ویجتها با Provider وابسته به API، یک زیرکلاس مقلد ایجاد کنید یا از mockito / mocktail استفاده کنید.
کارایی Provider بر پایه InheritedWidget است: با تغییر Provider، تمامی ویجتهایی که از طریق context.watch یا Consumer مشترک شدهاند، بازسازی میشوند. برای جلوگیری از بازسازیهای ضروری، از context.select، Consumer با پارامتر child و const برای ویجتهای استاتیک استفاده کنید.
| روش | اشتراک | بازسازی | کاربرد |
|---|---|---|---|
| context.watch | مدل کامل | هر تغییری | ویجتهای ساده |
| Consumer | مدل کامل | هر تغییری | با بهینهسازی child |
| context.select | صدـ مشخص | تنها با تغییر صدـ | مدلهای پیچیده |
| context.read | ندارد | هرگز | گیرندههای رویداد |
محدودیتها: Provider از جداسازی منطق کسب و کار در سطح رویداد (مانند BLoC) پشتیبانی نمیکند. برای سناریوهای پیچیده، Provider از BLoC و Riverpod عقب میماند.
سوالات متداول
Provider — لایهای بر روی InheritedWidget برای وارد کردن وابستگیها با ChangeNotifier. BLoC — الگوی معماری با Event + Stream برای جداسازی منطق. Provider یادگیری آسانتری دارد، BLoC کد را ساختارمندتر میکند.
ChangeNotifierProvider — نوعی Provider برای نمونههای ChangeNotifier. شیئ را از طریق create ایجاد میکند، آن را در دسترس نسلها قرار میدهد و Consumer را با فراخوانی notifyListeners بازسازی میکند.
از context.select به جای context.watch استفاده کنید — ویجت تنها با تغییر صدـ انتخابی بازسازی میشود. ChangeNotifierهای بزرگ را به چند کوچک تقسیم کنید. از Consumer child برای بخشهای استاتیک استفاده کنید.
بله. Provider (بدون ChangeNotifier) — برای وارد کردن شیئهای تغییرناپذیر (مخزن، مشتری API، پیکربندی). ValueListenableProvider — برای ValueNotifier. StreamProvider — برای جریان. FutureProvider — برای Future. ProxyProvider — برای Providerهای وابسته به دیگری.
ProviderNotFoundException — استثنای زمان اجرایی که در صورت تلاش برای دستیابی به Providerی که بالاتر در درخت ویجتها اعلام نشده است، رخ میدهد. راهحل: Provider را بالاتر در درخت قرار دهید یا از MultiProvider در سطح MaterialApp استفاده کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.