Merhaba,
Bugün sizlere Flutter öğrenme sürecimde beni epey zorlayan, karmaşık bulduğum ve anlamak için oldukça fazla zaman ayırdığım bir yapıdan bahsetmek ve bunu örneklemek istiyorum. Konumuz Flutter’da Provider yapısı. Daha önce Flutter’da “State” mantığından, stateful ve stateless widget’ların farklılıklarından söz etmiştim. Aşağıya hatırlatma linki bırakıyorum:
Stateful Widget’ları uygulamada kullanıcı etkileşimi sonucu veya başka sebeplerle değişiklik olacaksa kullanıyoruz. Yani State nesnesi içermesi gereken noktalarda. Ve çok basit mantıkla eğer ortada bir “State” var ise, bunun yönetilmesi gerekir yani State Management yöntemlerinden birini seçmemi ve kullanmamız gerekir ki State’in durumunu takip edebilelim ve etkileşim sonucu değişen arayüzü kullanıcıya anlık olarak gösterebilelim. Ben size bu yöntemlerden biri olan Provider yapısından bahsetmek istiyorum. Hazırsak başlayalım.
Provider Nedir?
Provider, Flutter’da state management için kullanılan bir paket olup, uygulamanın belirli bölgelerinde veya genelinde durumu (state) yönetmek ve bu durumu paylaşmak için kullanılır. Provider, durumun yeniden oluşturulması, güncellenmesi ve paylaşılması konusunda basit ve etkili bir yol sunar.
Yukarıda kullandığım ansiklopedik bir bilgi, her yerde bulunabilir. Ben kısa ve basit bir todo uygulaması ile açıklamalı olarak bunun nasıl kullanılacağını göstereceğim.
Projemiz tamamlandığında aşağıdaki gibi görünecek:
1. Adım:
İlk olarak yeni bir Flutter uygulaması oluşturup isimlendiriyoruz. Proje oluştuktan sonra pubspec.yaml dosyasını açarak buraya Provider paketini ekliyoruz.
dependencies:
flutter:
sdk: flutter
provider: ^6.0.0 //versiyon numarası
//sizin uygulamayı oluşturduğunuz
//tarihe göre değişebilir.
2. Adım:
İkinci adım olarak durumu (state) temsil eden bir model oluşturuyoruz. Uygulamamız TodoApp olduğu için bir Todo sınıfı oluşturabiliriz:
class Todo {
//todo maddelerini checkbox ile kontrol edeceğiz.
String title;
bool isDone;
Todo({
required this.title,
this.isDone = false, //checkbox başlangıçta işaretlenmemiş olarak gelecek
});
void toggleDone() {
isDone = !isDone; //checkbox tıklandığında tick yok ise eklenmesini,
//var ise silinmesini sağlayan metod
}
}
3. Adım:
Bir sonraki aşamada State’i yöneten bir sınıf oluşturmamız gerekiyor ve “ChangeNotifier” ile genişletiyoruz. ChangeNotifier, durum değişikliklerini dinleyen ve bildiren bir sınıftır. Bu sınıfa ait notifyListeners() isimli metodunu çağırarak d,a değişiklikleri dinleyen tüm bileşenlere (widget'lara) bu değişikliği bildirmiş oluyoruz. Örneğimizden gidecek olursak, kullanıcı Todo listesine eklediği bir maddenin üzerini çizmek istedi ve checkbox’ı işaretledi diyelim, bu sınıf sayesinde kullanıcı arayüzüne değişiklik anında bildiriliyor ve checkbox tick’i beliriyor ve maddenin üzeri çiziliyor.
class TodoProvider with ChangeNotifier {
List<Todo> _todos = [];
List<Todo> get todos => _todos;
void addTodo(String title) { //CRUD işlemlerinden eklemeyi sağlayan metot
_todos.add(Todo(title: title));
notifyListeners(); //değişikliklerin anlık olarak arayüze yansıtılmasını
//sağlayan metot
}
void toggleTodoStatus(int index) {
_todos[index].toggleDone();
notifyListeners();
}
}
4. Adım:
Bu adımda main.dart dosyamıza Provider yapısını entegre ediyoruz. ChangeNotifierProvider, ChangeNotifier sınıfının bir örneğini oluşturuyor (instance almak gibi düşünebiliriz) ve alt bileşenlere State bildirimi yapıyor.
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => TodoProvider(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: TodoListScreen(),
);
}
}
5. Adım:
Son olarak todoListScreen.dart adında bir dosya daha oluşturuyoruz ve MaterialApp’in home sayfasını buna yönlendiriyoruz.
class TodoListScreen extends StatelessWidget {
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('To-Do List'),
),
body: Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _controller,
decoration: InputDecoration(labelText: 'New To-Do'),
),
),
IconButton(
icon: Icon(Icons.add),
onPressed: () {
if (_controller.text.isNotEmpty) {
Provider.of<TodoProvider>(context, listen: false)
.addTodo(_controller.text);
_controller.clear();
}
},
),
],
),
),
Expanded(
child: Consumer<TodoProvider>(
builder: (context, todoProvider, child) {
return ListView.builder(
itemCount: todoProvider.todos.length,
itemBuilder: (context, index) {
final todo = todoProvider.todos[index];
return ListTile(
title: Text(
todo.title,
style: TextStyle(
decoration: todo.isDone
? TextDecoration.lineThrough
: TextDecoration.none,
),
),
trailing: Checkbox(
value: todo.isDone,
onChanged: (value) {
todoProvider.toggleTodoStatus(index);
},
),
);
},
);
},
),
),
],
),
);
}
}
Burada açıklamam gereken iki kullanım var. Birincisi Consumer.
Consumer’ın yer aldığı Expanded widget’ı todo maddelerinin görüntüleneceği yeri oluşturuyor. Burada Consumer bize kullanıcı bir madde eklediğinde hemen altında görüntülenmesini sağlıyor. Çünkü Consumer, builder metodunu kullanarak, sağlayıcıyı (TodoProvider) dinliyor ve durum değiştiğinde otomatik olarak widget'ı yeniden oluşturuyor.
İkinci kullanım ise Provider.of<T>(context) yapısı. Bu metod belirtilen türdeki provider’a ulaşıyor, ki bu bizim örneğimizde TodoProvider. Burada addTodo isimli bir metodumuz var ve bu metodu kullanarak listeye yeni todo maddeleri eklenebiliyor. Burada durum değişikliğini dinlemeden sadece duruma erişmek istediğimizden listen parametresini false olarak veriyoruz. true verirsek bu değişiklikleri de dinler ancak burada gereksiz olduğundan performans sorunlarına yol açabilir.
Son olarak, basit To-Do Listesi uygulaması ile Provider yapısını birleştirerek state management (durum yönetimi) konusunu deneyimlemiş olduk. Bu projeyi daha da geliştirebilir, kalıcı veri depolama veya daha gelişmiş kullanıcı arayüzü özellikleri ekleyebiliriz.
Provider yapısını oldukça kısa ve basit şekliyle anlatmaya çalıştım. Umarım faydası olmuştur.
Hepimize iyi kodlamalar.
Selin.
Hiç yorum yok:
Yorum Gönder