0Pricing
Flutter Mobile Development · Ders

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(context, listen: false).

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!

  • ChangeNotifier holds your application state.
  • ChangeNotifierProvider makes that state available.
  • context.watch() listens for state changes and rebuilds UI.
  • context.read() accesses state for actions without rebuilding.
  • Provider.of(listen: false) is an older alternative to read.
  • Consumer allows for fine-grained UI rebuilds.
  • MultiProvider helps 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

  1. setState ve InheritedWidget
  2. Provider Paketinin Temelleri
  3. Durum İçin Riverpod
  4. Akışlarla BLoC Kalıbı
← Flutter Mobile Development Sayfasına Dön