Gereksinimler ve Ön Hazırlık
Bu projeye başlamadan önce sisteminizde Flutter 3.24 veya üzeri bir sürümün kurulu olduğundan emin olmalısınız. Ayrıca, sürükle-bırak (drag and drop) işlemlerini yönetmek için flutter_staggered_grid_view gibi performanslı kütüphanelerden faydalanacağız.
- Flutter SDK (En güncel kararlı sürüm).
- Dart diline orta seviye hakimiyet.
- State Management (Durum yönetimi) konusunda temel bilgi (Provider veya Riverpod önerilir).
- VS Code veya Android Studio üzerinde yapılandırılmış emülatör.
Adım 1: Dashboard Veri Modelini Oluşturma
Özelleştirilebilir bir dashboard, her bir widget'ın özelliklerini (id, tip, konum, veri kaynağı) tutan bir veri modeline ihtiyaç duyar. Bu model, uygulamanın dinamik yapısının temelini oluşturur.
class DashboardWidgetModel {
final String id;
final String title;
final WidgetType type;
int x;
int y;
int width;
int height;
DashboardWidgetModel({
required this.id,
required this.title,
required this.type,
this.x = 0,
this.y = 0,
this.width = 1,
this.height = 1,
});
}
enum WidgetType { chart, summary, list, weather }
Bu kod bloğu, her bir dashboard öğesinin koordinatlarını ve boyutlarını tanımlar. x ve y değerleri, grid üzerinde hangi konumda duracağını belirlemek için kullanılır.
Adım 2: Dinamik Widget Fabrikası (Factory Pattern)
Dashboard üzerindeki farklı widget türlerini (grafik, özet kartı vb.) tek bir yerden yönetmek için bir "Factory" sınıfı kullanmak, kodunuzun sürdürülebilirliğini artırır.
class WidgetFactory {
static Widget buildWidget(DashboardWidgetModel model) {
switch (model.type) {
case WidgetType.chart:
return Card(child: Center(child: Text("${model.title} - Grafik")));
case WidgetType.summary:
return Card(child: Center(child: Text("${model.title} - Özet")));
default:
return Card(child: Center(child: Text("Bilinmeyen Widget")));
}
}
}
Bu yapı, uygulama genişledikçe yeni widget türlerini eklemeyi kolaylaştırır. WidgetFactory, modelden gelen veriye göre ilgili UI bileşenini döndürür.
Adım 3: Sürükle ve Bırak (Drag & Drop) Entegrasyonu
Kullanıcının dashboard öğelerini yer değiştirebilmesi için ReorderableGridView mantığını uygulamamız gerekir. 2026 standartlarında, performans kaybı yaşamamak için flutter_staggered_grid_view kütüphanesini kullanmanızı öneririm.
StaggeredGridView.countBuilder(
crossAxisCount: 2,
itemCount: dashboardWidgets.length,
itemBuilder: (context, index) {
return Draggable(
data: dashboardWidgets[index],
child: WidgetFactory.buildWidget(dashboardWidgets[index]),
feedback: Material(child: SizedBox(width: 100, height: 100, child: Text("Taşınıyor..."))),
);
},
staggeredTileBuilder: (index) => StaggeredTile.fit(1),
)
Bu kod, kullanıcıların öğeleri basılı tutarak sürüklemesine olanak tanır. feedback parametresi, sürükleme esnasında parmağın altında görünen görseli temsil eder.
Adım 4: Dashboard Yapılandırmasını Kaydetme
Kullanıcının yaptığı değişikliklerin uygulama kapandıktan sonra da kalıcı olması gerekir. Bunun için shared_preferences veya yerel bir veritabanı olan isar kullanabilirsiniz.
Future saveLayout(List layout) async {
final prefs = await SharedPreferences.getInstance();
final String encodedData = jsonEncode(layout.map((e) => e.toJson()).toList());
await prefs.setString('user_dashboard_layout', encodedData);
}
Verileri JSON formatına çevirerek yerel depolamaya kaydetmek, uygulamanızın offline (çevrimdışı) çalışmasını destekler. Güvenlik için kullanıcı verilerini şifrelemeden saklamamaya dikkat edin.
Karşılaştırma: Dashboard Yönetim Yöntemleri
| Yöntem | Avantaj | Dezavantaj |
|---|---|---|
| Statik Yerleşim | Hızlı geliştirme | Kullanıcı özelleştiremez |
| Dinamik Grid (Önerilen) | Yüksek UX | Karmaşık state yönetimi |
| JSON Tabanlı Yapı | Sunucu ile senkronize | Ekstra veri işleme yükü |
Güvenlik Uyarısı: Uygulama içerisinde kullanıcı tarafından tanımlanan widget içeriklerini (özellikle webview içeren widget'ları) render ederken, XSS (Cross-Site Scripting) saldırılarına karşı dikkatli olun. Kullanıcıdan gelen verileri mutlaka sanitize edin ve güvenli olmayan kaynaklardan script çalıştırmayın.
Sıkça Sorulan Sorular
Flutter'da sürükle-bırak performansı nasıl korunur?
Performansı korumak için widget'ları const olarak işaretleyin ve setState yerine Riverpod veya Bloc gibi reaktif state yönetim kütüphanelerini kullanarak sadece güncellenen widget'ın yeniden çizilmesini sağlayın.
Farklı ekran boyutlarında dashboard nasıl ölçeklenir?
LayoutBuilder kullanarak ekranın genişliğini (constraints.maxWidth) kontrol edin ve grid sütun sayısını (crossAxisCount) ekran genişliğine göre dinamik olarak güncelleyin.
Dashboard verilerini sunucu ile nasıl senkronize ederim?
Her bir yerleşim değişikliğinden sonra (onReorder) bir API isteği tetikleyerek güncel JSON dizisini sunucuya gönderin. İstek başarısız olursa yerel veritabanını güncelleyip "retry" mekanizması kurun.
Widget içeriklerini dinamik olarak nasıl güncellerim?
Widget'ları bir StreamBuilder ile sarmalayarak, veritabanı veya API'den gelen canlı verilerin anlık olarak dashboard'a yansımasını sağlayabilirsiniz.
Kullanıcının widget ekleyip çıkarmasına nasıl izin veririm?
Bir "Widget Ekle" menüsü oluşturun. Bu menüden seçilen widget türünü bir DashboardWidgetModel nesnesine dönüştürün ve mevcut listenize ekleyerek state'i güncelleyin.
Dashboard Performansını Optimize Etme Stratejileri
Dinamik ve sürükle-bırak destekli bir dashboard yapısında, widget sayısı arttıkça render performansında düşüşler yaşanabilir. Özellikle her bir widget'ın kendi içinde bir API çağrısı yaptığı senaryolarda, uygulamanın donmaması için aşağıdaki stratejileri uygulamalısınız.
Widget Bazlı Lazy Loading Uygulaması
Tüm widget'ları aynı anda yüklemek yerine, sadece ekranda görünen (viewport içindeki) widget'ların verilerini çekmek kaynak tüketimini ciddi oranda azaltır. VisibilityDetector paketini kullanarak widget'ın ekrana gelip gelmediğini kontrol edebilirsiniz.
VisibilityDetector(
key: Key(widgetId),
onVisibilityChanged: (visibilityInfo) {
if (visibilityInfo.visibleFraction > 0.1) {
// Widget görünür olduğunda veriyi yükle
context.read().add(LoadWidgetData(widgetId));
}
},
child: MyDashboardWidget(data: widgetData),
)
RepaintBoundary ile Çizim Yükünü Azaltma
Sürükle-bırak işlemi sırasında dashboard sürekli olarak yeniden çizilir. Karmaşık grafikler içeren widget'ların her karede (frame) yeniden çizilmesini engellemek için RepaintBoundary widget'ını kullanın. Bu, widget'ın çizimini bir katman (layer) olarak önbelleğe alır.
RepaintBoundary(
child: Container(
padding: EdgeInsets.all(16),
child: MyComplexChartWidget(),
),
)
Dashboard İçin İleri Seviye Hata Ayıklama (Debugging)
Dinamik widget yapılarında en sık karşılaşılan sorunlar, "Key" çakışmaları ve state kaybıdır. Dashboard'unuzun kararlı çalışması için aşağıdaki hata ayıklama tekniklerini izleyin.
Global Key Yönetimi ve Hata İzleme
Sürükle-bırak işlemlerinde ReorderableListView veya benzeri yapılar kullanırken, her widget'ın benzersiz bir ValueKey'e sahip olduğundan emin olun. Eğer widget'larınız state tutuyorsa, GlobalKey kullanarak widget'ın ağaçtaki yerini koruyabilirsiniz.
| Hata Türü | Belirti | Çözüm |
|---|---|---|
| Key Çakışması | Widget'lar yer değiştirmiyor veya kayboluyor. | Benzersiz ID'leri Key olarak atayın. |
| State Kaybı | Widget sürüklenince içeriği sıfırlanıyor. | State'i widget içinde değil, Provider/Bloc ile dışarıda tutun. |
| Overflow Hatası | Widget kutu dışına taşıyor. | LayoutBuilder ile kısıtlayıcı kapsayıcılar kullanın. |
LayoutBuilder ile Ölçeklenebilirlik Analizi
Dashboard'unuzun farklı cihazlarda nasıl görüneceğini test etmek için LayoutBuilder kullanarak widget'ların boyutlarını dinamik olarak hesaplayın. Aşağıdaki kod bloğu, widget'ın genişliğine göre içerik yoğunluğunu nasıl değiştirebileceğinizi gösterir:
LayoutBuilder(
builder: (context, constraints) {
if (constraints.maxWidth < 300) {
return CompactWidgetView(); // Daha az bilgi göster
} else {
return DetailedWidgetView(); // Detaylı grafik göster
}
},
)
İpucu: Dashboard'unuzda çok fazla animasyon kullanıyorsanız,flutter_animategibi kütüphaneler yerine Flutter'ın yerleşikImplicitlyAnimatedWidgetsınıflarını tercih ederek CPU yükünü minimize edin.
Sonuç
Flutter & mobil ile özelleştirilebilir widget tabanlı dashboard yapmak, uygulamanıza profesyonel bir esneklik kazandırır. Bu rehberde; veri modelleme, widget fabrikası oluşturma, sürükle-bırak etkileşimi ve veri kalıcılığı konularını ele aldık. Bir sonraki adım olarak, dashboard'unuza "Dark Mode" desteği eklemeyi veya widget'ların içeriklerini kullanıcıların kendi API anahtarlarıyla özelleştirebileceği bir ayarlar sayfası geliştirmeyi deneyebilirsiniz.
Sorumluluk Reddi: Bu makaledeki kod örnekleri eğitim amaçlıdır. Üretim (production) ortamında kullanmadan önce güvenlik açıklarını denetleyin, hata yönetimi (error handling) ekleyin ve verilerinizi uygun şekilde şifreleyerek saklayın.


Yorumlar (0)
Yorum Yaz