Bir önceki yazımda Flutter’ın bilgisayarınıza nasıl kurulacağını ve Flutter örnek projesinin oluşturulmasını anlatmıştım. Tüm yönergeleri doğru bir şekilde tamamladıysanız muhtemelen karşınıza yukarıda görmüş olduğunuz kodlar geldi. Flutter ve Dart kod yazım stiline ne kadar aşinasınız bilemiyorum ancak ben sizler için yukarıdaki kodu detaylı bir şekilde inceleyeceğim. Böylece hem widget yapısı hem de kod yapısı kafanızda oturacaktır diye ümit ediyorum.
Bu proje için dikkate alacağımız dosyalar 2 tanedir. Uygulamanın dependencies yani bağımlılıklarının yazıldığı dosya pubspec.yaml dosyasıdır. Burada projede kullanacağınız farklı kütüphaneleri ekleyebilirsiniz. Diğer bir dosya da main.dart dosyasıdır. Main.dart dosyası bizim kodlarımızı yazdığımız dosyadır. Bunun gibi birden fazla dosyaya kod yazacaksanız bu dosyaları lib klasörüne oluşturabilirsiniz. main.dart projenin başlayacağı kodların bulunduğu en üst seviye kod dosyasıdır. Hadi şimdi main.dart dosyasını inceleyelim.
Flutter Örnek Proje Kodlarındaki Yorumları Silelim
İlk olarak main.dart dosyasında bulunan yorum satırlarını silelim. Yorum satırları yazılan kodda asla gereksiz değildir ancak bu bir eğitim projesi olduğu için geliştiriciler yorum satırı sayısını biraz abartmışlar. Bu satırları kafamı karıştırmasın ve kod fazla uzun gözükmesin diye silelim. Şimdi de Flutter örnek proje içerisinde bulunan tüm kodlara bakalım ve inceleyim.
import 'package:flutter/material.dart';
Yukarıdaki kod eğer yazılım geliştirme üzerine biraz çalıştıysanız hemen anlayacağınız cinstendir. Projeye Flutter sdk dosyasını eklediğimizi söylemektedir. Eğer bu import işlemini yapmaz isek yazılan kodlar tanınmayacaktır ve proje oluşturulamayacaktır.
void main() => runApp(MyApp());
Her Flutter uygulamasının bir main (ana) fonksiyona ihtiyacı vardır. Bu ana fonksiyon programın nereden başlayacağını söylemektedir. Ana fonksiyon herhangi bir değer döndürmeyeceğinden dolayı return tipine void dedik. Fonksiyonun adına main dedik ve içerisine herhangi bir parametre vermedik. runApp Flutter SDK’inde tanımlanmış bir fonksiyondur. Bu fonksiyon içerisine parametre olarak bir widget almaktadır. O zaman MyApp de bir widget diyoruz ve şimdi MyApp’in kodlarına bakıyoruz.
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, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } }
Söylemeyi unuttum ancak bu kadar yeni bir dil dedim Google geliştiriyor dedim amacımız mobil cihazlar dedim hepiniz class yani sınıf yapısının Flutter’da olduğunu tahmin etmişsinizdir diye düşünüyorum. MyApp adında bir sınıf tanımladık ve bu sınıfın StatelessWidget üzerinden extend olduğunu söyledik. Yani MyApp değişmeyecek bir duruma sahiptir. MyApp içerisine bir widget oluşturuyoruz. Bunu yaparken Widget buildden yardım alıyoruz. Build metodu widgetın tasarımını dile getiren metoddur. Metod bize MaterialApp döndürecek ve bu MaterialApp’in başlığı ‘Flutter Demo’, teması ana rengi mavi olan bir tema olacaktır. Uygulamanın başlığını oluşturduysak gövdesine gelebiliriz. Gövdesine MyHomePage adındaki widgetı çocuk olarak veriyoruz.
Kodlar içerisinde hep bir ebeveyn ve çocuk ilişkisi bulunmaktadır. Çocuklar bir üst nesilden özellik alabilmektedirler.
Widget Olayını Kodumuza Uyarlayalım
class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); }
MyHomePage adında bir sınıf oluşturuyoruz ve bunu StatefulWidget sınıfından extend ediyoruz. Bu demek oluyor ki bu sınıfın (widgetın) bir durumu olacaktır. MyHomePage sınıfı içerisinde sınıftan bir üye oluştururken içerisine parametre olarak verdiğimiz titile değişkenini karşılıyoruz ve bunu sınıf içerisinde bulunan title değişkenine atıyoruz. Final olarak tanımladığımız değişken bir daha değiştirilemeyecektir. Stateful widgetlarda build methodu olmaz, bunun yerine createState adında metodları vardır. createState Flutter state türünce bir sınıftan yapı alan widget döndürür.
class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.display1, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), ); } }
MyHomePage türünden bir durum widgetı oluşturuyoruz. İşin aslında bu durum widgetı içerisinde ekranda gördüğünüz her şeye ait görüntü olacaktır. Bu durum widgetı her değiştiğinde arayüzünüz ve değişkenleriniz güncellenecektir. Durum içerisinde int tipinde private bir değişken tanımlıyoruz ve başlangıçta değerini 0’a eşitliyoruz. incrementCounter adında bir fonksiyon tanımlıyoruz. Bu fonksiyon içerisine herhangi bir parametre almamaktadır ve private bir fonksiyondur. Sayaç değişkenimizi arttırmak için Flutter SDK’de tanımlı olan setState fonksiyonu içerisini dolduracağız. setState fonksiyonu çalıştığı zaman, state içerisinde tanımlı olan build methodu çalışacaktır. Build metodu değişkenlerimizin yeni değerleri ile ekranı yeniden oluşturacaktır. Eğer setState kullanmadan bu işlemi yapmış olsaydık, sayaç değişkenimiz arkaplanda değişecekti ancak kullanıcı arayüzünde değişmediği için kullanıcı sayacın güncellendiğini anlamayacaktı.
Scaffold Widgetını Aslında Hepimiz Biliyoruz
State içerisinde tanımlı olan build methodundan bahsedelim. Bu method setState her çağırıldığında çalışacak ve ekrandaki durumu güncelleyecektir. Build metodunun içerisinde ekranda görmüş olduğunuz her widgetın kodları bulunmaktadır. Build metodu ekranda Scaffold widgetını oluşturacaktır. Bu widget aslında hepimizin aşina olduğu material uygulama dizaynının şablonudur. Bu şablon içerisinde özellik olarak appBar, body ve floatingActionButton bulundurmaktadır.
appBar içerisine AppBar widgetı koyduk. AppBar widgetının title özelliğine de Text widgetı koyduk ve Text widgetı içerisine parametre olarak bir üst widgetta bulunan title değişkenini verdik.
body içerisine Center widgetı koyduk. Bu widget içerisine aldığı her widgetı merkezleyecektir. İçerisine tek bir widget alan center objesine senin çocuğun bir Column widgetıdır dedik. Column widgetı içerisinde birden çok widget alabilir ve bunların hepsini dikey bir şekilde sıralamaktadır. Column konum özelliklerini bir üst hiyerarşisinde bulunan widgettan alacaktır. mainAxisAligment özelliği çocukların sıralanış biçimini söylemektedir. Çocuklarımız widget için ana tanımlı şekilde sıralansın dedik ve içerisine sıralanacak çocuk widgetlarımızı verdik. Çocuk widgetlarımız 2 adet Text widgetıdır. 1. Text widgetımız değişmeyecek bir yazıyı içerisine alırken ikinci widgetımız içerisine sayaç olarak tanımladığımız değişkeni alacaktır. Bu sayaçlı Textin yazım stilini de daha önce tanımlanan tasarım şeklinde gösterilmesini söyledik.
floatingActionButton içerisine floatinAction button widgetı ekledik. Bu widgetın onPressed özelliğine yazmış olduğumuz sayaç arttırıcı fonksiyonu verdik. onPressed özelliği bir fonksiyon alır ve butona basınca bu fonksiyon çalıştıracaktır. tooltip özelliği buton üzerine parmağınızı basılı tutunca ekranda belirecek açıklamayı içerisinde barındırır. Bu kullanıcılar için butonun ne yaptığını hatırlatmaya bire biredir. Butonun içerisine bir ekle ikonu ekledik. Bazı ikonlar Flutter SDK içerisinde hazır tanımlıdır. Artık bu ikon butonun bir çocuğudur.
Daha çok örnek uygulama için Flutter’ın örnek uygulama kataloğunu inceleyebilir ya da Türkçe anlatım için bizi takipte kalabilirsiniz.
Çocukluğumdan beri arabalara olan ilgim babam sayesinde başlamıştır. Araba manyağı seviyesinde bir ilgim var ancak bunu her ortamda dile getirmem. Teknolojiye ve bilgisayara olan ilgim kendimi tanımaya başladım başlayalı oldu. Şimdi ise kendimce kod yazabilen bir bilgisayar mühendisi olarak çalışıyorum.