DEV Community

Cover image for Flutter Provider Türleri 💫 🌌 ✨
Gülsen Keskin
Gülsen Keskin

Posted on • Updated on

Flutter Provider Türleri 💫 🌌 ✨

Not: Bu yazı Flutter Community tarafından paylaşılan makalenin Türkçe çevirisi niteliğini taşır. Orijinal içeriğe linkten ulaşabilirsiniz.

Flutter'da bir çok Provider türü vardır bunlardan bazıları:

• Provider
• ListenableProvider
• ChangeNotifierProvider
• ValueListenableProvider
• StreamProvider
• FutureProvider
• MultiProvider
• ProxyProvider
• ChangeNotifierProxyProvider

Bu yazıda provider türlerini ve bunlardan hangisinin ne zaman kullanılacağını öğreneceğiz.

Bunun için aşağıdaki yapıyı kullanacağız.

Image description

• "Do something" düğmesi, uygulama durumunu değiştiren herhangi bir uygulama olayını temsil eder.

• "Show something" Metin widget'ı, kullanıcı arayüzünün uygulama durumunu görüntülemesi gereken herhangi bir bölümünü temsil eder.

• Soldaki yeşil dikdörtgen ve sağdaki mavi dikdörtgen, widget ağacının iki farklı bölümünü temsil eder. Bir etkinliğin ve güncellediği kullanıcı arayüzünün uygulamanın herhangi bir bölümünde olabileceğini vurgulamak için kullanılmışlardır.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('My App')),
        body: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[

            Container(
              padding: const EdgeInsets.all(20),
              color: Colors.green[200],
              child: RaisedButton(
                child: Text('Do something'),
                onPressed: () {},
              ),
            ),

            Container(
              padding: const EdgeInsets.all(35),
              color: Colors.blue[200],
              child: Text('Show something'),
            ),

          ],
        ),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Provider paketini pubspec.yaml dosyanıza ekleyin:

dependencies:
  provider: ^6.0.2
Enter fullscreen mode Exit fullscreen mode

Bunu herhangi bir sayfada kullanmak için aşağıdaki şekilde import edebilirsiniz.

import 'package:provider/provider.dart';

Provider

Tahmin edebileceğiniz gibi, Provider, Provider widget türlerinin en temelidir.
Widget ağacında herhangi bir yere bir değer (genellikle bir data model object) sağlamak için kullanabilirsiniz.
Ancak, bu değer değiştiğinde widget ağacını güncellemenize yardımcı olmaz.

class MyModel { 
  String someValue = 'Hello';
  void doSomething() {
    someValue = 'Goodbye';
    print(someValue);
  }
}
Enter fullscreen mode Exit fullscreen mode
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<MyModel>( //                                <--- Provider
      create: (context) => MyModel(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: "Text('My App')),"
          body: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[

              Container(
                padding: const EdgeInsets.all(20),
                color: Colors.green[200],
                child: Consumer<MyModel>( //                    <--- Consumer
                  builder: (context, myModel, child) {
                    return RaisedButton(
                      child: Text('Do something'),
                      onPressed: (){
                        // We have access to the model.
                        myModel.doSomething();
                      },
                    );
                  },
                )
              ),

              Container(
                padding: const EdgeInsets.all(35),
                color: Colors.blue[200],
                child: Consumer<MyModel>( //                    <--- Consumer
                  builder: (context, myModel, child) {
                    return Text(myModel.someValue);
                  },
                ),
              ),

            ],
          ),
        ),
      ),
    );
  }
}

class MyModel { //                                               <--- MyModel
  String someValue = 'Hello';
  void doSomething() {
    someValue = 'Goodbye';
    print(someValue);
  }
}
Enter fullscreen mode Exit fullscreen mode

Bunu çalıştırdığınızda aşağıdaki sonucu alırsınız:

Image description

Kullanıcı arayüzü, modelden gelen "Hello" metniyle oluşturuldu.

“Do something” düğmesine basmak, model üzerinde bir olayın gerçekleşmesine neden olacaktır. Ancak, modelin verileri değiştirilmiş olsa bile, Provider widget aracı sağladığı değerlerdeki değişiklikleri dinlemediği için kullanıcı arayüzü yeniden oluşturulamadı.

ChangeNotifierProvider

Provider widget bileşeninden farklı olarak, ChangeNotifierProvider model nesnesindeki değişiklikleri dinler.
Değişiklik olduğunda, Consumer altındaki tüm widget'ları yeniden oluşturacaktır.

Kodda Provider'ı ChangeNotifierProvider olarak değiştirin.
Model sınıfının ChangeNotifier'ı kullanması (veya extend etmesi) gerekir. Bu sizin notifyListeners()'a erişmenizi sağlar ve notifyListeners()'ı her çağırdığınızda ChangeNotifierProvider bilgilendirilecek ve Consumer'lar widget'larını yeniden oluşturacaktır.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<MyModel>( //      <--- ChangeNotifierProvider
      create: (context) => MyModel(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text('My App')),
          body: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[

              Container(
                  padding: const EdgeInsets.all(20),
                  color: Colors.green[200],
                  child: Consumer<MyModel>( //                  <--- Consumer
                    builder: (context, myModel, child) {
                      return RaisedButton(
                        child: Text('Do something'),
                        onPressed: (){
                          myModel.doSomething();
                        },
                      );
                    },
                  )
              ),

              Container(
                padding: const EdgeInsets.all(35),
                color: Colors.blue[200],
                child: Consumer<MyModel>( //                    <--- Consumer
                  builder: (context, myModel, child) {
                    return Text(myModel.someValue);
                  },
                ),
              ),

            ],
          ),
        ),
      ),
    );
  }
}

class MyModel with ChangeNotifier { //                          <--- MyModel
  String someValue = 'Hello';

  void doSomething() {
    someValue = 'Goodbye';
    print(someValue);
    notifyListeners();
  }
}
Enter fullscreen mode Exit fullscreen mode

Şimdi “Do something” düğmesine bastığınızda, metin “Hello” dan “Goodbye” a dönüşür.

Image description

Çoğu uygulamada model sınıfınız kendi dosyasında olacak ve ChangeNotifier'ı kullanmak için flutter/foundation.dart dosyasını içe aktarmanız gerekecek. Bunun gerçekten hayranı değilim çünkü bu, iş mantığınızın artık framework'e bağımlı olduğu ve framework'ün bir ayrıntı olduğu anlamına gelir.

Consumer widget'ı, notifyListeners() çağrıldığında altındaki tüm pencere öğelerini yeniden oluşturur.
Butonun güncellenmesi gerekmez, bu nedenle bir Consumer kullanmak yerine Provider.of'u kullanabilir ve listen parametresini "false" olarak ayarlayabilirsiniz.
Bu şekilde, değişiklik olduğunda buton yeniden oluşturulmaz.

class MyButton extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final myModel = Provider.of<MyModel>(context, listen: false);
    return RaisedButton(
      child: Text('Do something'),
      onPressed: () {
        myModel.doSomething();
      },
    );
  }
}

Enter fullscreen mode Exit fullscreen mode

FutureProvider

FutureProvider, temel olarak FutureBuilder widget'ının etrafındaki bir sarmalayıcıdır.
Kullanıcı arayüzünde göstermesi için bazı initial dataları veriyorsunuz ve ayrıca provide etmek istediğiniz değerin bir Future'ını sağlıyorsunuz.
FutureProvider, Future'ın ne zaman tamamlandığını dinler ve ardından Consumerları widget'larını yeniden oluşturmaları için bilgilendirir.

Aşağıdaki kodda, kullanıcı arayüzüne bazı initial dataları vermek için boş bir model kullandım.
Ayrıca 3 saniye sonra yeni bir model döndürme işlevi ekledim.
FutureProvider'ın beklediği şey budur.

Temel Provider gibi, FutureProvider da modelin kendisindeki değişiklikleri dinlemez. Aşağıdaki kod 2 saniye sonra “Do something” butonunu yaparak modeli değiştirir. UI üzerinde herhangi bir etkisi yoktur.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureProvider<MyModel>( //                      <--- FutureProvider
      initialData: MyModel(someValue: 'default value'),
      create: (context) => someAsyncFunctionToGetMyModel(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text('My App')),
          body: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[

              Container(
                padding: const EdgeInsets.all(20),
                color: Colors.green[200],
                child: Consumer<MyModel>( //                    <--- Consumer
                  builder: (context, myModel, child) {
                    return RaisedButton(
                      child: Text('Do something'),
                      onPressed: (){
                        myModel.doSomething();
                      },
                    );
                  },
                )
              ),

              Container(
                padding: const EdgeInsets.all(35),
                color: Colors.blue[200],
                child: Consumer<MyModel>( //                    <--- Consumer
                  builder: (context, myModel, child) {
                    return Text(myModel.someValue);
                  },
                ),
              ),

            ],
          ),
        ),
      ),
    );

  }
}

Future<MyModel> someAsyncFunctionToGetMyModel() async { //  <--- async function
  await Future.delayed(Duration(seconds: 3));
  return MyModel(someValue: 'new data');
}

class MyModel { //                                               <--- MyModel
  MyModel({this.someValue});
  String someValue = 'Hello';
  Future<void> doSomething() async {
    await Future.delayed(Duration(seconds: 2));
    someValue = 'Goodbye';
    print(someValue);
  }
}
Enter fullscreen mode Exit fullscreen mode

Image description

FutureProvider, Consumer'a Future<MyModel> tamamlandıktan sonra yeniden oluşturmasını söyler.

Uygulamayı başlangıç değerleriyle yeniden oluşturmak için hot restart'a basın.

"Do something" butonuna basmanın, Future tamamlandıktan sonra bile kullanıcı arayüzünü güncellemediğini unutmayın.
Bu tür bir işlevsellik istiyorsanız, son bölümdeki ChangeNotifierProvider'ı kullanın.

FutureProvider için kullanım durumunuz, bir dosyadan veya ağdan bazı verileri okumak olabilir.Ancak bunu bir FutureBuilder ile de yapabilirsiniz.Uzman olmayan görüşüme göre, FutureProvider bir FutureBuilder'dan çok daha kullanışlı değil.Bir sağlayıcıya ihtiyacım olursa, muhtemelen bir ChangeNotifierProvider kullanırdım ve bir sağlayıcıya ihtiyacım yoksa, muhtemelen bir FutureBuilder kullanırdım.
Yine de bir yorum eklemek isterseniz bunu güncellemekten memnuniyet duyarım.

StreamProvider

StreamProvider, temel olarak StreamBuilder'ın etrafındaki bir sarıcıdır. Bir akış sağlarsınız ve ardından akışta bir olay olduğunda Consumer'lar yeniden oluşturulur. Kurulum, yukarıdaki FutureProvider'a çok benzer.

StreamProvider modelin kendisindeki değişiklikleri dinlemez.
Yalnızca akıştaki yeni eventleri dinler.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamProvider<MyModel>( //                       <--- StreamProvider
      initialData: MyModel(someValue: 'default value'),
      create: (context) => getStreamOfMyModel(),
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text('My App')),
          body: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[

              Container(
                padding: const EdgeInsets.all(20),
                color: Colors.green[200],
                child: Consumer<MyModel>( //                    <--- Consumer
                  builder: (context, myModel, child) {
                    return RaisedButton(
                      child: Text('Do something'),
                      onPressed: (){
                        myModel.doSomething();
                      },
                    );
                  },
                )
              ),

              Container(
                padding: const EdgeInsets.all(35),
                color: Colors.blue[200],
                child: Consumer<MyModel>( //                    <--- Consumer
                  builder: (context, myModel, child) {
                    return Text(myModel.someValue);
                  },
                ),
              ),

            ],
          ),
        ),
      ),
    );

  }
}

Stream<MyModel> getStreamOfMyModel() { //                        <--- Stream
  return Stream<MyModel>.periodic(Duration(seconds: 1),
          (x) => MyModel(someValue: '$x'))
      .take(10);
}

class MyModel { //                                               <--- MyModel
  MyModel({this.someValue});
  String someValue = 'Hello';
  void doSomething() {
    someValue = 'Goodbye';
    print(someValue);
  }
}
Enter fullscreen mode Exit fullscreen mode

Image description

StreamProvider, Consumer'a yeni bir stream eventi (akış olayı) olduğunda yeniden oluşturmasını söyler.

Uygulamayı başlangıç değerleriyle yeniden oluşturmak için hot restart a basın.

"Do something" düğmesine basmanın kullanıcı arayüzünü güncellemediğini unutmayın. Bu tür bir işlevsellik istiyorsanız, sadece ChangeNotifierProvider kullanın. Aslında, model nesnenizde bir akış olabilir ve sadece notifyListeners()'ı çağırabilirsiniz.
Bu durumda bir StreamProvider'a hiç ihtiyacınız olmaz.

ValueListenableProvider

ValueListenableProvider'ı immutable state model nesnesi ile kullanabilirsiniz ve değişmezliğin (immutability) bazı avantajları vardır.

class MyModel {
  ValueNotifier<String> someValue = ValueNotifier('Hello');
  void doSomething() {
    someValue.value = 'Goodbye';
  }
}
Enter fullscreen mode Exit fullscreen mode

ValueListenableProvider ile içindeki değişiklikleri dinleyebilirsiniz. Ancak, kullanıcı arayüzünden model üzerinde bir method çağırmak istiyorsanız, modeli de sağlamanız gerekir.
Bu nedenle, aşağıdaki kodda bir Provider'ın, MyModel'deki ValueNotifier'ı ValueListenableProvider'a veren bir Consumer'a MyModel sağladığını görebilirsiniz.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Provider<MyModel>(//                              <--- Provider
      create: (context) => MyModel(),
      child: Consumer<MyModel>( //                           <--- MyModel Consumer
          builder: (context, myModel, child) {
            return ValueListenableProvider<String>.value( // <--- ValueListenableProvider
              value: myModel.someValue,
              child: MaterialApp(
                home: Scaffold(
                  appBar: AppBar(title: Text('My App')),
                  body: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[

                      Container(
                          padding: const EdgeInsets.all(20),
                          color: Colors.green[200],
                          child: Consumer<MyModel>( //       <--- Consumer
                            builder: (context, myModel, child) {
                              return RaisedButton(
                                child: Text('Do something'),
                                onPressed: (){
                                  myModel.doSomething();
                                },
                              );
                            },
                          )
                      ),

                      Container(
                        padding: const EdgeInsets.all(35),
                        color: Colors.blue[200],
                        child: Consumer<String>(//           <--- String Consumer
                          builder: (context, myValue, child) {
                            return Text(myValue);
                          },
                        ),
                      ),

                    ],
                  ),
                ),
              ),
            );
          }),
    );
  }
}

class MyModel { //                                             <--- MyModel
  ValueNotifier<String> someValue = ValueNotifier('Hello'); // <--- ValueNotifier
  void doSomething() {
    someValue.value = 'Goodbye';
    print(someValue.value);
  }
}
Enter fullscreen mode Exit fullscreen mode

Image description

"Do something" butonuna basmak, ValueListenableProvider sayesinde "Hello"nun "Goodbye" olarak değişmesini sağlar.

Widget ağacının en üstünde bir Consumer yerine Provider.of<MyModel>(context, listen: false) kullanmak muhtemelen daha iyi olur. Aksi takdirde, her seferinde tüm ağacı yeniden inşa ederiz.

Provider<MyModel>, myModel'i hem ValueListenableProvider'a hem de "Do something" düğmesinin kapanmasına verir.

ListenableProvider

Bunu yalnızca kendi özel provider'ınızı oluşturmanız gerekiyorsa kullanırsınız.

MultiProvider

Şimdiye kadar ki örneklerimiz yalnızca bir model nesnesi kullandı.
İkinci tür bir model nesnesi sağlamanız gerekiyorsa, providerları iç içe yerleştirebilirsiniz (yukarıdaki ValueListenableProvider örneğinde yaptığım gibi). Ancak, iç içe kullanım dağınıktır. Bunu yapmanın daha düzgün bir yolu, bir MultiProvider kullanmaktır.

Aşağıdaki örnekte, iki ChangeNotifierProviders ile sağlanan iki farklı model vardır.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider( //                                     <--- MultiProvider
      providers: [
        ChangeNotifierProvider<MyModel>(create: (context) => MyModel()),
        ChangeNotifierProvider<AnotherModel>(create: (context) => AnotherModel()),
      ],
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text('My App')),
          body: Column(
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[

                  Container(
                      padding: const EdgeInsets.all(20),
                      color: Colors.green[200],
                      child: Consumer<MyModel>( //            <--- MyModel Consumer
                        builder: (context, myModel, child) {
                          return RaisedButton(
                            child: Text('Do something'),
                            onPressed: (){
                              // We have access to the model.
                              myModel.doSomething();
                            },
                          );
                        },
                      )
                  ),

                  Container(
                    padding: const EdgeInsets.all(35),
                    color: Colors.blue[200],
                    child: Consumer<MyModel>( //              <--- MyModel Consumer
                      builder: (context, myModel, child) {
                        return Text(myModel.someValue);
                      },
                    ),
                  ),

                ],
              ),

             // SizedBox(height: 5),

              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[

                  Container(
                      padding: const EdgeInsets.all(20),
                      color: Colors.red[200],
                      child: Consumer<AnotherModel>( //      <--- AnotherModel Consumer
                        builder: (context, myModel, child) {
                          return RaisedButton(
                            child: Text('Do something'),
                            onPressed: (){
                              myModel.doSomething();
                            },
                          );
                        },
                      )
                  ),

                  Container(
                    padding: const EdgeInsets.all(35),
                    color: Colors.yellow[200],
                    child: Consumer<AnotherModel>( //        <--- AnotherModel Consumer
                      builder: (context, anotherModel, child) {
                        return Text('${anotherModel.someValue}');
                      },
                    ),
                  ),

                ],
              ),
            ],
          ),
        ),
      ),
    );

  }
}

class MyModel with ChangeNotifier { //                        <--- MyModel
  String someValue = 'Hello';
  void doSomething() {
    someValue = 'Goodbye';
    print(someValue);
    notifyListeners();
  }
}

class AnotherModel with ChangeNotifier { //                   <--- AnotherModel
  int someValue = 0;
  void doSomething() {
    someValue = 5;
    print(someValue);
    notifyListeners();
  }
}
Enter fullscreen mode Exit fullscreen mode

Image description

İlk "Do something" düğmesine basmak, "Hello"yu "Goodbye" olarak değiştirecektir. İkinci “Do something” düğmesine basmak “0”ı “5” olarak değiştirecektir.

Bununla tek ChangeNotifierProvider arasında pek bir fark yoktur.
Farklı Consumer'ların doğru modeli alma yolu, gösterdikleri türe göredir. Yani, Consumer<MyModel>, MyModel'i alır ve Consumer<AnotherModel>, AnotherModel'i alır.

ProxyProvider

Ya sağlamak istediğiniz iki modeliniz varsa, ancak modellerden biri diğerine bağlıysa?
Bu durumda bir ProxyProvider kullanabilirsiniz.
Bir ProxyProvider değeri bir providerdan alır ve başka bir provider'a enjekte edilmesini sağlar.

Bir ProxyProvider kurma şekliniz ilk başta kafa karıştırıcı olabilir, bu yüzden bununla ilgili küçük bir açıklama eklememe izin verin.

MultiProvider(
  providers: [
    ChangeNotifierProvider<MyModel>(
      create: (context) => MyModel(),
    ),
    ProxyProvider<MyModel, AnotherModel>(
      update: (context, myModel, anotherModel) => AnotherModel(myModel),
    ),
  ],
Enter fullscreen mode Exit fullscreen mode

Temel ProxyProvider'ın iki türü vardır. Birinci tip, ikinci tipin bağlı olduğu şeydir. Yani, başka bir Provider tarafından zaten sağlanmış olan bir modeldir. Güncelleme kapanışında ikinci model tipine enjekte edilir. Üçüncü parametre (anotherModel) önceki yerleşik değeri saklar, ancak bunu burada kullanmıyoruz. Sadece myModel'i AnotherModel'in yapıcısına iletiyoruz.

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider( //                              <--- MultiProvider
      providers: [
        ChangeNotifierProvider<MyModel>( //               <--- ChangeNotifierProvider
          create: (context) => MyModel(),
        ),
        ProxyProvider<MyModel, AnotherModel>( //          <--- ProxyProvider
          update: (context, myModel, anotherModel) => AnotherModel(myModel),
        ),
      ],
      child: MaterialApp(
        home: Scaffold(
          appBar: AppBar(title: Text('My App')),
          body: Column(
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[

                  Container(
                      padding: const EdgeInsets.all(20),
                      color: Colors.green[200],
                      child: Consumer<MyModel>( //          <--- MyModel Consumer
                        builder: (context, myModel, child) {
                          return RaisedButton(
                            child: Text('Do something'),
                            onPressed: (){
                              myModel.doSomething('Goodbye');
                            },
                          );
                        },
                      )
                  ),

                  Container(
                    padding: const EdgeInsets.all(35),
                    color: Colors.blue[200],
                    child: Consumer<MyModel>( //            <--- MyModel Consumer
                      builder: (context, myModel, child) {
                        return Text(myModel.someValue);
                      },
                    ),
                  ),

                ],
              ),

              Container(
                  padding: const EdgeInsets.all(20),
                  color: Colors.red[200],
                  child: Consumer<AnotherModel>( //          <--- AnotherModel Consumer
                    builder: (context, anotherModel, child) {
                      return RaisedButton(
                        child: Text('Do something else'),
                        onPressed: (){
                          anotherModel.doSomethingElse();
                        },
                      );
                    },
                  )
              ),

            ],
          ),
        ),
      ),
    );

  }
}

class MyModel with ChangeNotifier { //                       <--- MyModel
  String someValue = 'Hello';
  void doSomething(String value) {
    someValue = value;
    print(someValue);
    notifyListeners();
  }
}

class AnotherModel { //                                      <--- AnotherModel
  MyModel _myModel;
  AnotherModel(this._myModel);
  void doSomethingElse() {
    _myModel.doSomething('See you later');
    print('doing something else');
  }
}
Enter fullscreen mode Exit fullscreen mode

Image description

Metin “Hello” ile başlar.

“Do something” düğmesine bastığınızda, MyModel metni “Goodbye” olarak değiştirir. MyModel dinleyicisini (ChangeNotifierProvider) bilgilendirir ve kullanıcı arayüzü yeni metinle yeniden oluşturulur.

"Do something else" düğmesine bastığınızda, AnotherModel MyModel'i (ProxyProvider tarafından enjekte edilmiştir) alır ve metnini "See you later" olarak değiştirir. MyModel dinleyicilerine değişiklikleri bildirdiği için, kullanıcı arayüzü tekrar güncellenir. AnotherModel'in değişen kendi verileri olsaydı, ProxyProvider değişiklikleri dinlemediğinden UI güncellenmezdi. Bunun için bir ChangeNotifierProxyProvider gerekir.

Provider builder ve value constructors

Bitirmeden önce, Provider'ı kullanmayı öğrenirken kafamı karıştıran bir şeyi daha açıklamak istiyorum.
Provider widget öğelerinin çoğu (tümü değilse de) iki tür constructor'a sahiptir. basic constructor, model nesnenizi oluşturduğunuz bir oluşturma işlevi alır. Bunu yukarıdaki örneklerin çoğunda yaptık.

Provider<MyModel>(
  create: (context) => MyModel(),
  child: ...
)
Enter fullscreen mode Exit fullscreen mode

MyModel Nesnenin create fonksiyonunda oluşturulduğunu görebilirsiniz .

Nesneniz zaten oluşturulduysa ve yalnızca ona bir referans sağlamak istiyorsanız, value adlı named (adlandırılmış) constructor'ı kullanabilirsiniz:

final myModel = MyModel();
...
Provider<MyModel>.value(
    value: myModel, 
    child: ...
)
Enter fullscreen mode Exit fullscreen mode

Burada MyModel daha önce oluşturuldu ve sadece referans olarak iletildi. Ağdan veri yüklemek için modelde bir yöntemi çağırabilmeniz için modelinizi initState() yönteminde başlatmış olsaydınız bunu yapardınız.

resource

Top comments (2)

Collapse
 
sahinmehmetemre profile image
Mehmet Şahin

Kafa karışıklığımı gideren yazınız için teşekkür ederim. Güzel bir çalışma olmuş, elinize sağlık.

Collapse
 
gulsenkeskin profile image
Gülsen Keskin

Ben teşekkür ederim. İşinize yaradıysa ne mutlu :D