Flutter Uygulamalarında GetX Paketine Başlarken

Yayınlanan: 2022-03-10
Hızlı özet ↬ GetX, Flutter uygulamaları için durum, gezinme ve bağımlılık yönetimi için ekstra hafif bir çözümdür. Bu yazıda faydalarına, özelliklerine ve Flutter uygulamalarında kullanmaya nasıl başlayacağınıza bakacağız.

Flutter, gerçek anlamda platformlar arası yerel uygulamalar oluşturmanın en hızlı yollarından biridir. Geliştiricinin, kullanıcıları için gerçekten güzel bir UI deneyimi oluşturmasına olanak tanıyan özellikler sağlar.

Bununla birlikte, çoğu zaman ekranlarda gezinme, durum yönetimi ve uyarıları gösterme gibi şeyleri başarmak için çok sayıda ortak bilgi gerekir. Bu standartlar, özellikleri oluşturmaya ve son teslim tarihlerini karşılamaya çalışan geliştiricilerin geliştirme verimliliğini yavaşlatma eğilimindedir.

Örneğin, bir Flutter uygulamasında bir ekrana gitmek için gereken ortak plakayı alın. AboutScreen adlı bir ekrana gitmek istediğinizi varsayalım. yazmanız gerekecek:

 Navigator.push( context, MaterialPageRoute(builder: (context) => AboutScreen()), );

Aşağıdaki gibi bir şey yapmak daha verimli ve geliştirici dostu olacaktır:

 Get.to(AboutScreen());

Flutter'da bir önceki sayfaya geri dönmeniz gerektiğinde şunu yazmanız gerekecek:

 Navigator.pop(context);

Ekranlar arasında gezinmek gibi sıradan bir şey için her zaman bağlam özelliğine bağlı olduğumuzu fark edeceksiniz. Bunun yerine şöyle bir şey yapabilirsek:

 Get.back();

Yukarıdaki örnekler, Flutter'da uygulama geliştirmenin daha az standart ile daha sezgisel ve verimli olacak şekilde iyileştirilebileceği yollardan bazılarıdır. Özellikler ve fikirler oluşturmada basitliği ve verimli olmayı tercih ediyorsanız, Flutter'da Get paketi ilginizi çekecektir.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

GetX Nedir?

Get or GetX, Flutter uygulamaları oluşturmak için hızlı, kararlı, ekstra hafif bir çerçevedir.

GetX, yüksek performanslı durum yönetimi, akıllı bağımlılık ekleme ve rota yönetimi ile kutudan çıktığı gibi basit ve pratik bir şekilde gönderilir.

GetX, geliştiricilerin uygulamalarını oluştururken kullanmaları için basit ve sezgisel sözdizimi sağlarken aynı zamanda ortak kalıpları en aza indirmeyi amaçlar. GetX'in özünde şu 3 ilke vardır:

  • Verim
    GetX, özelliklerini mümkün olduğunca az kaynak tüketecek şekilde uygulayarak uygulamanızın performansına odaklanır.
  • üretkenlik
    GetX, geliştiricilerin mümkün olduğunca çabuk üretken olmak için özelliklerini kullanmasını istiyor. Bunu, hatırlanması kolay sözdizimi ve uygulamaları kullanarak yapar. Örneğin, genellikle geliştirici, denetleyicileri bellekten kaldırmakla ilgilenmelidir, ancak kutudan çıktığı haliyle GetX, uygulamanızdaki denetleyicileri izleyen ve varsayılan olarak kullanılmadıklarında bunları kaldıran akıllı yönetim sağlar.
  • organizasyon
    GetX, Flutter uygulamanızda Görünüm, sunum mantığı, iş mantığı, bağımlılık enjeksiyonu ve navigasyonun ayrıştırılmasına izin verir. Rotalar arasında gezinmek için bağlama ihtiyacınız yoktur, bu nedenle navigasyon için widget ağacına bağımlı değilsiniz. Denetleyicilerinize/bloklarınıza inheritedWidget bir Widget aracılığıyla erişmek için bağlama ihtiyacınız yoktur, böylece sunum mantığınızı ve iş mantığınızı görünüm katmanınızdan tamamen ayırabilirsiniz. Çoklu sağlayıcılar aracılığıyla widget ağacınıza Controllers/Models/Blocs sınıflarınızı enjekte etmeniz gerekmez, çünkü bu GetX, DI'yi görünümünden tamamen ayırarak kendi bağımlılık ekleme özelliğini kullanır.

GetX'in Özellikleri

GetX, Flutter'da günlük uygulama geliştirmenizde ihtiyaç duyacağınız birkaç özellikle birlikte gelir. Onlara bakalım:

Durum Yönetimi

GetX'in amiral gemisi özelliklerinden biri, sezgisel durum yönetimi özelliğidir. GetX'te durum yönetimi, çok az veya hiç ortak plaka olmadan gerçekleştirilebilir.

Rota Yönetimi

GetX, Flutter uygulamasında gezinmek için API sağlar. Bu API basittir ve daha az kod gerektirir.

Bağımlılık Yönetimi

GetX, Flutter uygulamanızdaki görünüm denetleyicileri gibi bağımlılıkları yönetmenin akıllı bir yolunu sunar. GetX, o anda kullanılmayan tüm denetleyicileri bellekten kaldıracaktır. Bu, geliştirici olarak sizin manuel olarak yapmanız gereken bir görevdi, ancak GetX bunu sizin için kutudan çıkar çıkmaz otomatik olarak yapıyor.

Uluslararasılaşma

GetX, çeşitli dil desteği ile uygulamalar yazmanıza izin veren kutudan çıktığı gibi i18n sağlar.

doğrulama

GetX, Flutter uygulamalarınızda giriş doğrulaması gerçekleştirmek için doğrulama yöntemleri sağlar. Ayrı bir doğrulama paketi yüklemeniz gerekmeyeceğinden bu oldukça kullanışlıdır.

Depolamak

GetX, her işlemde verileri diske yedekleyen bellekte hızlı, ekstra hafif ve senkronize bir anahtar/değer çifti sağlar. Tamamen Dart'ta yazılmıştır ve temel GetX paketiyle kolayca bütünleşir.

GetX'e Başlarken

Artık GetX'in ne olduğunu ve sağladığı özellik ve faydaları gördüğünüze göre, onu uygulamanızda nasıl kuracağınızı görelim. Bahsettiğimiz özelliklerin çoğunu çalışırken görmek için bir demo uygulaması oluşturacağız. Başlayalım.

Yepyeni Bir Flutter Uygulaması Oluşturun

Flutter CLI aracılığıyla yepyeni bir Flutter uygulaması oluşturarak başlayacağız. Makinenizin Flutter ile uygulama geliştirmeye hazır olduğunu varsayıyorum. Bu yüzden koşuyoruz:

 flutter create getx_demo

Bu, bir Flutter uygulaması için gereken temel kodu üretecektir. Ardından, seçtiğiniz editörde az önce oluşturduğunuz projeyi açın (Bu makale için VS Code kullanacağız). Ardından, düzgün çalıştığından emin olmak için projeyi çalıştıracağız (Bir aygıtın bağlı olduğundan veya bir emülatör/simülatörün çalıştığından emin olun).

Uygulama çalıştığında, yeni bir Flutter uygulaması oluşturduğunuzda Flutter'ın sizin için oluşturduğu varsayılan sayaç uygulamasını göreceksiniz. Yapacağımız şey, aynı sayaç uygulamasını uygulamak, ancak GetX ile uygulamanın durumunu (sayım değişkeni olan) yönetmek.

main.dart temizleyerek ve yalnızca bu kod parçasını bırakarak başlayacağız:

 # main.dart import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }

Artık MyHomePage widget'ı olmadığı için uygulamamız bozulacaktı. Bunu düzeltelim. GetX ile durum bilgisi olan widget'lara ihtiyacımız yok ve ayrıca kullanıcı arayüzümüz iş mantığımızdan açıkça ayrılabilir. Böylece lib/ içinde iki dizin oluşturacağız. Bu dizinler şunlardır:

views/ Uygulamamızdaki ekranları tutmak için.
controllers/ Uygulamamızdaki ekranlar için tüm kontrolörleri tutmak için.

views/ içinde MyHomePage widget'ı oluşturalım. Dosyanın adı my_home_page.dart olacaktır. Oluşturduktan sonra aşağıdaki kod parçasını buna ekleyin:

 import 'package:flutter/material.dart'; class MyHomePage extends StatelessWidget { final String title; MyHomePage({this.title}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '0', style: Theme.of(context).textTheme.headline4, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: null, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }

Şimdi MyHomePage widget'ımız var, onu main.dart içine aktaralım. import deyimini main.dart dosyasının en üstüne import 'package:flutter/material.dart';

 import './views/my_home_page.dart';

Şimdi main.dart dosyanız şöyle görünmelidir:

 import 'package:flutter/material.dart'; import './views/my_home_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }

Şimdi başvurunuzu kaydettiğinizde, tüm hataların giderilmiş olması gerekir ve uygulama çalışacaktır. Ancak butona tekrar tıkladığınızda sayacın güncellenmediğini fark edeceksiniz. views/my_home_page.dart koduna bakarsanız, Text parçacığının değeri olarak 0 kodladığımızı ve düğmenin onPressed işleyicisine null değerini geçtiğimizi göreceksiniz. Uygulamayı tekrar işlevsel hale getirmek için GetX'i karışıma getirelim.

GetX'i Yükleme

pub.dev'deki GetX kurulum sayfasına gidin ve GetX'i kurmak için pubspec.yml dosyanıza kopyalanacak kod satırını göreceksiniz. Bu makalenin yazıldığı tarih itibariyle GetX'in güncel sürümü 3.23.1'dir. Bu yüzden satırı kopyalayacağız:

 get: ^3.23.1

Ardından bunu pubspec.yml dosyamızın dependencies bölümünün altına yapıştırın. Dosyayı kaydettiğinizde, get sizin için otomatik olarak yüklenmelidir. Veya terminalinizde manuel olarak çalıştırabilirsiniz.

 flutter pub get

pubspec.yml dosyanızın bağımlılıklar bölümü şöyle görünmelidir:

 dependencies: flutter: sdk: flutter get: ^3.23.1

GetxController

GetX'in uygulamanızın UI'sini mantıktan ayırmanıza izin verdiğinden bahsetmiştik. Bunu, uygulamanızın görünümleri için denetleyici sınıfları oluşturmak üzere devralabileceğiniz bir GetxController sınıfı sağlayarak yapar. Mevcut uygulamamız için tek bir görünümümüz var, bu nedenle bu görünüm için bir denetleyici oluşturacağız. controllers/ dizinine gidin ve my_home_page_controller.dart adlı bir dosya oluşturun. Bu, MyHomePage görünümü için denetleyiciyi tutacaktır.

Dosyayı oluşturduktan sonra, önce bunu dosyanın en üstüne ekleyerek GetX paketini içe aktarın:

 import 'package:get/get.dart';

Ardından içinde MyHomePageController adında bir sınıf oluşturacak ve GetxController sınıfını genişleteceksiniz. Dosya şöyle görünmelidir:

 import 'package:get/get.dart'; class MyHomePageController extends GetxController {}

oluşturduğumuz sınıfa count durumunu ekleyelim.

 final count = 0;

GetX'te, bir değişkeni gözlemlenebilir yapmak için - bu, değiştiğinde, uygulamamızın buna bağlı diğer bölümlerinin bilgilendirileceği anlamına gelir. Bunu yapmak için değişken başlatmaya .obs eklememiz yeterlidir. Yani yukarıdaki count değişkenimiz için 0 .obs ekleyeceğiz. Yani yukarıdaki beyan şimdi şöyle görünecek:

 final count = 0.obs;

Denetleyici dosyamız şu anda böyle görünüyor:

 import 'package:get/get.dart'; class MyHomePageController extends GetxController { final count = 0.obs; }

İşleri MyHomePageController ile tamamlamak için increment yöntemini uygulayacağız. Bunu yapmak için snippet:

 increment() => count.value++;

Bunu artırmak için count değişkenine .value eklememiz gerektiğini fark edeceksiniz. Bunu yaptık çünkü bir değişkene .obs eklemek onu gözlemlenebilir bir değişken yapar ve gözlemlenebilir bir değişkenin değerini almak için bunu value özelliğinden yaparsınız.

Böylece controller ile işimiz bitti. Artık count değeri değiştiğinde, onu kullanan uygulamamızın herhangi bir kısmı otomatik olarak güncellenecektir.

Şimdi görüşümüze gideceğiz ve yeni oluşturduğumuz denetleyici hakkında bilgi vereceğiz. Bunu, GetX bağımlılık yönetimi özelliğini kullanarak denetleyici sınıfını somutlaştırarak yapacağız. Bu, artık gerekmediğinde denetleyicimizin bellekte olmamasını sağlayacaktır.

views/my_home_page.dart içinde Get paketini ve ayrıca oluşturduğunuz denetleyiciyi içe aktarın:

 import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart';

Ardından MyHomePage sınıfının içinde MyHomePageController :

 final MyHomePageController controller = Get.put(MyHomePageController());

Artık MyHomePageController örneğine sahibiz, durum değişkenini ve yöntemi kullanabiliriz. Durumdan başlayarak, bir durum değişkeni değiştiğinde yeniden oluşturulacak kullanıcı arayüzünüzün bir bölümünü işaretlemek için GetX'te, o kısmı Obx parçacığıyla saracaksınız. GetX bunu yapmanın başka yollarını sunar, ancak bu yöntem çok daha basit ve temizdir.

Sayım uygulamamız için Metin widget'ının mevcut sayımla güncellenmesini istiyoruz. Böylece, Metin parçacığını Obx parçacığı ile şu şekilde saracağız:

 Obx(() => Text('0',style: Theme.of(context).textTheme.headline4,),)

Ardından, 0 statik dizesini MyHomePageController gelen sayı değişkeniyle şu şekilde değiştireceğiz:

 Obx(() => Text('${controller.count.value}', ,style: Theme.of(context).textTheme.headline4,),)

Son olarak, floatingActionButton şu şekilde basıldığında artırma yöntemini çağıracağız:

 floatingActionButton: FloatingActionButton( onPressed: controller.increment, tooltip: 'Increment', child: Icon(Icons.add), ),

Genel olarak, MyHomePage görünüm dosyamız şu şekilde görünmelidir:

 import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart'; class MyHomePage extends StatelessWidget { final String title; final MyHomePageController controller = Get.put(MyHomePageController()); MyHomePage({this.title}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Obx( () => Text( '${controller.count.value}', style: Theme.of(context).textTheme.headline4, ), ) ], ), ), floatingActionButton: FloatingActionButton( onPressed: controller.increment, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }

Uygulamanızı kaydettiğinizde veya yeniden çalıştırdığınızda, sayaç uygulaması, uygulamayı ilk oluşturduğumuz zamanki gibi çalışıyor olmalıdır.

GetX ile durum yönetiminin ne kadar sezgisel olduğunu gördüğünüze inanıyorum, çok fazla standart yazmak zorunda kalmadık ve uygulamanız karmaşıklaştıkça bu basitlik daha belirgin hale gelecektir. Ayrıca, görüşümüzün herhangi bir durumu tutmadığını veya sürdürmediğini fark edeceksiniz, bu nedenle durumsuz bir pencere öğesi olabilir. Görünümün beyni, artık görünüm ve yöntemler için durumu tutacak bir denetleyici sınıfıdır.

GetX'te Gezinme

GetX'te durum yönetimini gördük. Şimdi GetX'in uygulamanız içinde Navigasyonu nasıl desteklediğine bakalım. GetX'in Gezinme özelliğini etkinleştirmek için, ana.dart'ta MaterialApp pencere öğesini bir main.dart parçacığına dönüştürmek için tek bir değişiklik yapmanız GetMaterialApp . Bunu önce get in top in main.dart içe aktararak yapalım.

 import 'package:get/get.dart';

Ardından, main.dart dosyamızın şu şekilde görünmesi için MaterialApp değişiklik yapıyoruz:

 import 'package:flutter/material.dart'; import 'package:get/get.dart'; import './views/my_home_page.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return GetMaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }

Artık uygulamamız GetX navigasyonunu destekleyecek şekilde ayarlandı. Bunu test etmek için views/ dizinde başka bir görünüm oluşturacağız. Bunu about_page.dart üzerinde arayacağız ve aşağıdaki kodu içerecektir:

 import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/my_home_page_controller.dart'; class AboutPage extends StatelessWidget { final MyHomePageController controller = Get.put(MyHomePageController()); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('About GetX'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(16.0), child: Text( 'GetX is an extra-light and powerful solution for Flutter. It combines high performance state management, intelligent dependency injection, and route management in a quick and practical way.', ), ), ], ), ), ); } }

Daha sonra MyHomePage gideceğiz ve basıldığında bizi AboutPage bir düğme ekleyeceğiz. Öyle gibi. Düğme, Obx widget'ının altında olmalıdır. İşte burada:

 FlatButton(onPressed: () {}, child: Text('About GetX'))

Ayrıca MyHomePage dosyasının üstüne AboutPage içe aktarmamız gerekecek:

 import './about_page.dart';

GetX'e AboutPage gitmesini söylemek için tek ihtiyacımız olan bir kod satırı:

 Get.to(AboutPage());

Bunu, FlatButton parçacığının onPressed geri çağrısına şu şekilde ekleyelim:

 FlatButton( onPressed: () { Get.to(AboutPage()); }, child: Text('About GetX'))

Başvurunuzu şimdi kaydettiğinizde, artık AboutPage sayfasına gidebilirsiniz.

Ayrıca MyHomePage görünümünü AboutPage ile değiştirmeyi de seçebilirsiniz, böylece kullanıcı cihaz geri düğmesine basarak önceki sayfaya geri dönemez. Bu, oturum açma ekranları gibi ekranlar için kullanışlıdır. Bunu yapmak için onPressed işleyicisinin içeriğini aşağıdaki kodla değiştirin:

 Get.off(AboutPage());

Bu, MyHomePage görünümünü açar ve onu AboutPage ile değiştirir.

Artık onPressed gidebildiğimize göre, bunu yapmak için AboutPage geri MyHomePage o kadar da kötü olmayacağını AboutPage . MyHomePage'e geri gitmek için MyHomePage Get.back() 'e:

 FlatButton( onPressed: () { Get.back(); }, child: Text('Go Home') )

snack bar

Flutter'da geleneksel olarak bir Snackbar göstermek için şöyle bir şey yazmanız gerekir:

 final snackBar = SnackBar(content: Text('Yay! A SnackBar!')); // Find the Scaffold in the widget tree and use it to show a SnackBar. Scaffold.of(context).showSnackBar(snackBar);

Hala context özelliğine bağlı olduğumuzu gözlemleyebilirsiniz. GetX'te bunu nasıl başarabileceğimize bakalım. MyHomePage görünümüne gidin ve son eklediğimiz düğmenin altına başka bir FlatButton widget'ı ekleyin. İşte buton için snippet:

 FlatButton( onPressed: () { // TODO: Implement Snackbar }, child: Text('Show Snackbar'))

'Yay! Harika GetX Snackbar'. onPressed işleyici işlevinin içine aşağıdaki kod satırını ekleyin:

 Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar');

Uygulamanızı çalıştırın ve “Snackbar Göster düğmesini” tıkladığınızda uygulamanızın üstünde bir snackbar göreceksiniz!

Bir Flutter uygulamasında snackbar göstermek için gereken satır sayısını nasıl azalttığımızı gördünüz mü? Snackbar'da biraz daha özelleştirme yapalım; Uygulamanın altında görünmesini sağlayalım. Kodu şu şekilde değiştirin:

 Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, );

Uygulamanızı kaydedin ve çalıştırın; Snackbar artık uygulamanın altında görünecektir. Snackbar'ın arka plan rengini şu anda şeffaf olduğu için değiştirelim. Flutter'daki Colors sınıfından amberAccent rengine değiştireceğiz. Kodu şu şekilde güncelleyin:

 Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar',snackPosition:SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent );

Genel olarak, düğme kodu şöyle görünmelidir:

 FlatButton( onPressed: () { Get.snackbar('GetX Snackbar', 'Yay! Awesome GetX Snackbar', snackPosition: SnackPosition.BOTTOM, backgroundColor: Colors.amberAccent); }, child: Text('Show Snackbar'))

iletişim kutusu

GetX, Flutter'da AlertDialog oluşturmak için basit bir yöntem sağlar. Eylemde görelim. Bir öncekinin altında başka bir düğme oluşturun:

 FlatButton( onPressed: () { // TODO: Show alert dialog }, child: Text('Show AlertDialog'))

Bir uyarı İletişim Kutusu görüntülemek için GetX'i arayalım:

 Get.defaultDialog();

Bu, İletişim Kutusunun dışına dokunarak kapatılabilen varsayılan bir Uyarı İletişim Kutusu gösterecektir. Nasıl bir kod satırında çalışan bir uyarı iletişim kutusuna sahip olduğumuzu görebilirsiniz. Biraz özelleştirelim. Başlığı ve mesajı değiştirelim:

 Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert');

Uygulamanızı kaydedin ve çalıştırın; "Show AlertDialog" düğmesine bastığınızda değişiklikleri göreceksiniz. Onay ve İptal butonlarını şu şekilde ekleyebiliriz:

 Get.defaultDialog( title: 'GetX Alert', middleText: 'Simple GetX alert', textConfirm: 'Okay', confirmTextColor: Colors.amberAccent, textCancel: 'Cancel');

GetX iletişim kutusunu özelleştirmenin birçok yolu vardır ve API oldukça sezgisel ve basittir.

Çözüm

GetX, Flutter geliştiricilerinin özellikleri oluştururken üretkenliğini artırmak için oluşturuldu. Durum yönetimi, gezinme yönetimi ve daha fazlası gibi şeyleri yapmak için gereken standart arama yapmak yerine GetX, performanstan ödün vermeden bu etkinlikleri gerçekleştirmek için basit, sezgisel bir API sağlar. Bu makale size GetX'i ve onu Flutter uygulamalarınızda kullanmaya nasıl başlayacağınızı tanıtmaktadır.

  • Demoyu burada bulabilirsiniz →