Provider Paketinin Temelleri
Uygulamanız genelinde basit ve ölçeklenebilir durum yönetimi için popüler bir Flutter çözümü olan Provider paketini kullanmayı öğrenin.
Provider Paketinin Temelleri, CoddyKit'te ücretsiz bir Flutter Mobile Development dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Flutter Mobile Development öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Flutter Mobile Development kursu toplamda 4 dersten oluşur.
Bu dersin bazı bölümleri henüz çevrilmemiş olup İngilizce olarak gösterilmektedir.
What is Provider?
The Provider package is a popular and simple solution for state management in Flutter. It's built on top of Flutter's own InheritedWidget, making it efficient and easy to understand.
It helps you share data and state across your widget tree without complex callbacks or prop drilling.
The Data Holder: ChangeNotifier
At the heart of Provider is the ChangeNotifier class. You extend this class for any object that holds state you want to share.
When your state changes, you call notifyListeners() to tell all listening widgets to rebuild.
import 'package:flutter/material.dart';
// 1. Extend ChangeNotifier
class MyCounter extends ChangeNotifier {
int _count = 0; // Private state variable
// Getter to access the count
int get count => _count;
// Method to modify state and notify listeners
void increment() {
_count++;
notifyListeners(); // Important! Triggers UI updates
}
}Making State Available
To make your ChangeNotifier instance available to widgets, you use a ChangeNotifierProvider. You wrap a part of your widget tree (usually your whole app) with it.
The create callback provides an instance of your state object.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
// Our state class from before
class MyCounter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
void main() {
runApp(
// Wrap the app with ChangeNotifierProvider
ChangeNotifierProvider(
create: (context) => MyCounter(), // Create an instance
child: MyApp(), // The widget tree that can access MyCounter
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Provider Setup')),
body: Center(
child: Text(
'MyCounter is now provided!',
style: TextStyle(fontSize: 24),
),
),
),
);
}
}Listening for UI Rebuilds
The most common way for a widget to listen to state changes and rebuild its UI is using context.watch. This method makes the widget dependent on the provided state.
When notifyListeners() is called, any widget using watch will rebuild.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyCounter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => MyCounter(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// 1. Use context.watch<MyCounter>() to get the current state
// This widget will rebuild when MyCounter changes.
final counter = context.watch<MyCounter>();
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Watch for Changes')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Count: ${counter.count}', // Display the count
style: TextStyle(fontSize: 32),
),
SizedBox(height: 20),
// Button to increment (action will be added next)
ElevatedButton(
onPressed: () {
// How to trigger increment? See next scene!
},
child: Text('Increment (Not yet connected)'),
),
],
),
),
),
);
}
}Actions without Rebuilds
Sometimes you need to access state methods (like increment()) but don't want the widget to rebuild. For this, use context.read.
It provides a one-time access to the state object and does not establish a listening relationship.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyCounter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => MyCounter(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter = context.watch<MyCounter>(); // Listen for UI updates
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Read for Actions')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Count: ${counter.count}',
style: TextStyle(fontSize: 32),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// 1. Use context.read<MyCounter>() to get the instance
// 2. Call the increment method
context.read<MyCounter>().increment();
},
child: Text('Increment Counter'),
),
],
),
),
),
);
}
}Alternative for One-Time Access
Before context.read, the common way to access state without listening was Provider.of.
It works exactly like context.read, but read is often preferred for its conciseness. Both are suitable for event handlers like onPressed.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyCounter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => MyCounter(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counter = context.watch<MyCounter>(); // UI listens
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Provider.of(listen: false)')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Count: ${counter.count}',
style: TextStyle(fontSize: 32),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
// Use Provider.of with listen: false for one-time access
Provider.of<MyCounter>(context, listen: false).increment();
},
child: Text('Increment Counter (using Provider.of)'),
),
],
),
),
),
);
}
}Fine-Grained Rebuilds with Consumer
The Consumer widget is another way to listen to state changes. Unlike context.watch(), which rebuilds the entire widget, Consumer only rebuilds its direct child (the builder function).
This can be useful for performance if only a small part of a large widget needs to react to state changes.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyCounter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => MyCounter(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Consumer Widget')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'This text does NOT rebuild.',
style: TextStyle(fontSize: 20, color: Colors.grey),
),
SizedBox(height: 20),
// Only the Text widget inside Consumer rebuilds
Consumer<MyCounter>(
builder: (context, counter, child) {
print('Consumer rebuilt!'); // See this in console
return Text(
'Count: ${counter.count}',
style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold),
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<MyCounter>().increment();
},
child: Icon(Icons.add),
),
),
);
}
}Providing Multiple States
For apps with multiple independent state objects, wrapping your app with many ChangeNotifierProviders can get messy. MultiProvider simplifies this.
It takes a list of providers, making your widget tree cleaner and easier to manage.
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class MyCounter extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
class MyThemeSettings extends ChangeNotifier {
bool _isDark = false;
bool get isDark => _isDark;
void toggleTheme() {
_isDark = !_isDark;
notifyListeners();
}
}
void main() {
runApp(
MultiProvider( // Use MultiProvider for multiple states
providers: [
ChangeNotifierProvider(create: (context) => MyCounter()),
ChangeNotifierProvider(create: (context) => MyThemeSettings()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Access both states using watch
final counter = context.watch<MyCounter>();
final theme = context.watch<MyThemeSettings>();
return MaterialApp(
theme: theme.isDark ? ThemeData.dark() : ThemeData.light(),
home: Scaffold(
appBar: AppBar(title: Text('MultiProvider Demo')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Count: ${counter.count}', style: TextStyle(fontSize: 28)),
SizedBox(height: 20),
Text('Dark Mode: ${theme.isDark ? "On" : "Off"}', style: TextStyle(fontSize: 28)),
SizedBox(height: 30),
ElevatedButton(
onPressed: () => context.read<MyThemeSettings>().toggleTheme(),
child: Text('Toggle Theme'),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => context.read<MyCounter>().increment(),
child: Icon(Icons.add),
),
),
);
}
}Provider Quick Check
Which of the following is the primary purpose of context.read in the Provider package?
Provider Basics Recap
You've learned the essentials of the Provider package!
ChangeNotifierholds your application state.ChangeNotifierProvidermakes that state available.context.watchlistens for state changes and rebuilds UI.() context.readaccesses state for actions without rebuilding.() Provider.of(listen: false)is an older alternative toread.Consumerallows for fine-grained UI rebuilds.MultiProviderhelps manage multiple state objects cleanly.
Provider is a powerful and flexible tool for managing state in your Flutter apps!
Sıkça Sorulan Sorular
“Provider Paketinin Temelleri” dersi ücretsiz mi?
Evet — “Provider Paketinin Temelleri” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Flutter Mobile Development kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Flutter Mobile Development kursu toplamda 4 dersten oluşur.
“Provider Paketinin Temelleri” dersinde ne öğreneceğim?
Uygulamanız genelinde basit ve ölçeklenebilir durum yönetimi için popüler bir Flutter çözümü olan Provider paketini kullanmayı öğrenin. Flutter Mobile Development ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Flutter Mobile Development öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Flutter Mobile Development, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.
“Provider Paketinin Temelleri” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Flutter Mobile Development dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Flutter Mobile Development dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- setState ve InheritedWidget
- Provider Paketinin Temelleri
- Durum İçin Riverpod
- Akışlarla BLoC Kalıbı