0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #14

Gauloran

Global Moderatör
7 Tem 2013
8,128
619
Merhabalar seriye devam edelim ama bu da nedir diyenler için Flutter ile mobil uygulama geliştirmeye yönelik güzel bir seri ilerletiyorum. Önceki konular:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #6
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #7
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #8
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #9
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #10
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #11
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #12
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #13

devam edelim Stateless widgettan bahsederek devam edebiliriz. stless şu demek sayfa yapıyoruz örneğin ve bu sayfada herhangi bir data işlemi yapılmayacaksa stateless widget kullanılır sadece gösterme yapacağımız işlemlerde statik sayfa yapılarında stless widget kullanılması gerekir özetle alınanı gösterme üzerine kurulu bir yapıya sahip.

stateless_widget_learn.dart veya bu tarz bir dart dosyası açarak not alabilirsiniz.

0*4dAnkDc2odhmeyjv.png



Kod:
import 'package:flutter/material.dart';
class StatelessLearn extends StatelessWidget {
  const StatelessLearn({super.key});

importu yaptık StatelessLearn diye bir sınıf oluşturduk ve bu sınıf StatelessWidget sınıfından türüyor. st yazınca zaten vscode üzerinde otomatik stless gelir direkt oluşturur tek tek yazmanıza gerek yok ama alışkanlık olsun diye yazmanızı tavsiye ederim. bir stateless widget sınıfından türeyen bir sınıf oluşturduk bizden 1 metodu override edilmeyi zorunlu kılıyor build metodunu peki bu build metodu ne? bizlere widgetlarımızın oluşturulması için ana yeri verir build metodlarımızın içerisinde ana ekranlarımızı gelişitiririz. build metodunun içerisine yazılan return ifadesiyle artık tasarımımızı verebiliriz şu şekilde:

Kod:
@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            _emptyBox(), //! buraya bir sizedBox oluşturmuştuk height i 10 olan fakat bu tarz basit işlemlerde extract Method diyoruz
            const _CustomContainer(), //! buraya bir Container oluşturduk aslında daha sonra extract Widget diyerek otomatik olarak bunu stlesswidget tan türeyen bir sınıfa dönüştürüyor
          ],
        ));
  }

extract metod sayesinde otomatik olarak bu şekilde oluşturuyor bakalım:

Kod:
class _CustomContainer extends StatelessWidget {
  //! otomatik olarak oluşturuldu bu extract Widget demiştik, bir sınıfın başına sadece bu dosyadan buna erişilir olmasını istiyorsak _ atıyoruz başına isminin
  const _CustomContainer({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        color: Colors.red,
      ),
    );
  }
}

diğeri ise şu:

Kod:
class TitleTextWidget extends StatelessWidget {
  const TitleTextWidget({super.key, required this.text});

  final String? text;

  @override
  Widget build(BuildContext context) {
    return Text("data", style: Theme.of(context).textTheme.displaySmall);
  }
}

Yani yazdığımız kodlarda bakıyoruz kalabalık var o var bu var extract diyerek vscode bize yardımcı oluyor kodumuz okunabilir gözüküyor.

maxresdefault.jpg


Şimdi padding'ten bahsedelim padding_widget falan diye veya paddinglearn diye bir dart dosyası daha oluşturun not alabilirsiniz bu şekilde. düzgün bir tasarımda paddingler değişmemelidir ve padding iki kompanent arasında boşluk vermeyi sağlar padding vermek doğru bir kullanım sizedBox vererek her şeyi çözemezsiniz. hizalama işlemleri için önemlidir ve bu kodda eğer Column a wrap with widget diyerek Padding verseydik içerisindeki elemanlar otomatik olarak o padding ile başlayacaktı:

Kod:
class PaddingLearn extends StatelessWidget {
  const PaddingLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
              child: Container(
                color: Colors.white,
                height: 100,
              ),
            ),
            Container(
              color: Colors.white,
              height: 100,
            ),
            const Padding(
                padding: EdgeInsets.only(right: 20, top: 10),
                child: Text("Ali")),
            Padding(
              padding: const EdgeInsets.only(right: 20) +
                  const EdgeInsets.symmetric(vertical: 10),
              //!bu şekilde + metodu ile iki edgeinstets i bu şekilde kullanabiliyoruz vererek
            ),
          ],
        ));
  }
}

tabi paddingi direkt olarak vermek yerine bir önceki konuda olduğu gibi şu tarz yaklaşımlarda bulunmanız çok daha iyi olur

Kod:
class ProjectPadding {
  //! böyle bir sınıf oluşturup padding: ProjectPadding.pagePaddingVertical, olarak vermek çok daha mantıklıdır
  static const pagePaddingVertical = EdgeInsets.symmetric(vertical: 10);
  static const pagePaddingRightOnly = EdgeInsets.only(right: 20);
}

basitçe açıklayacak olursak artık EdgeInsets.symmetric(vertical:10) yazacağınıza okunabilirliğinizi arttırıyorsunuz ve her seferinde uğraşmıyorsunuz çok daha mantıklı bu şekilde vermeniz. ProjectPadding sınıfını oluşturduktan sonra kullanımı size bırakıyorum. Tabii padding yine aynı padding olacağından bir şey fark etmezsiniz ama böyle yapmaya alışın. Tabii bu da aslında pek doğru değil fakat şu anda geldiğimiz seviye için fena değil.

Flutter-Card-Widget-640x320.jpg


Şimdi card widgetına bakalım yine kendi kafanıza göre dart dosyası oluşturun

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

class CardLearn extends StatelessWidget {
  const CardLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [

şimdi buraya kadar geldik bir Column oluşturduk children dedik widgetlarını vereceğiz falan. Burada card widgetını öğrenmemiz gerekli. İşimize çok yarıyor.

Kod:
 Card(
            //! kart widgetımız güzeldir
            elevation: 15, //! gölge ekler öne çıkartır
            margin: ProjectMargins
                .cardMargin, //! paddingin benzeri dışarıyla ilgili içeriyle ilgili değil dışardan
            //color: Theme.of(context).colorScheme.onPrimary,
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(
                    20)), //! stadyum şeklini almasını sağlar shape olarak card widgetımıza bunu verebiliyoruz CircleBorder() var ve RoundedRectangleBorder() vardır bunlar karta şekil veriyor işte
            child: const SizedBox(
              height: 100,
              width: 100,
              child: Center(child: Text("Zireael")),
            ),
          ),

zaten yorum satırlarında açıkladım fakat her koddan sonra böyle yorum satırlarında açıklama yapmanın aslında mantıklı olmadığını fark ettim de bunu fark edene kadar çok zaman geçti yapacak bir şey yok yine idare edin. Card widgetında burada elevation vermişiz gölge diyebiliriz bu özelliğe daha sonra margin vermişiz paddingin benzeri demişiz dışardan veriyor o tarz bir olayı var onun dışında shape vermişiz RoundedRectangleBorder ile borderRadius özelliğine de circular olsun demişiz 20 vermişiz oranı tabii RoundedRectangleBorder yerine farklı şeyler de kullanılabilir bunların örneklerini araştırabilirsiniz. Cardın childına da bir Text widgetı vermişiz daha doğrusu text widgetının üstüne center ve sizedbox gelmiş o şekilde ayarlamışız ortalansın diye card widgetı. Texte de witcher 3 oynayanlar beğenebilir ufak bir easter egg bıraktım String olarak. devame edelim

Sa5yXZ.jpg


Kod:
 const Card(
            elevation: 15,
            child: SizedBox(
              height: 100,
              width: 100,
            ),
          ),
Bu arada bu üstteki değil de onun üstündeki kodda o margin nerden geldi diyenler için aşağıya şöyle temsili bir sınıf yazmıştım

Kod:
class ProjectMargins {
  static const cardMargin = EdgeInsets.all(10);
}

şimdi burada yapacağımız şey özel bir card widgetı oluşturmak. deneyelim:

Kod:
class _CustomCard extends StatelessWidget {
  //! oop mantığı ile bir CustomCard widgetı oluşturuyoruz sadece bu dosyadan erişilebilecek buna StatelessWidget tan türesin diyoruz sınıfımız
  final Widget child;
  var roundedRectangleBorder =
      RoundedRectangleBorder(borderRadius: BorderRadius.circular(20));
  _CustomCard(
      {super.key, required this.child, required this.roundedRectangleBorder});

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 15,
      margin: ProjectMargins.cardMargin,
      //color: Theme.of(context).colorScheme.onPrimary,
      shape: roundedRectangleBorder,
      child: child,
    );
  }
}

yukarıdaki kodda file private olan bir CustomCard sınıfı oluşturmuşuz stlesswidget sınıfından türüyor özetle bir stless widget oluşturmuşuz diyebiliriz. özelliklerini vermişiz yani bildiğimiz OOP mantığı bu sınıftan nesne oluşturulduğunda bir child beklenecek. daha sonra diğer özellikleri vermişiz ve stless widget sınıfının build metodunu override ederek bir Card tasarımı döndürmüşüz istediğimiz şekilde. Bunu yapmamızdaki olay şu artık ben her seferinde Card widgetı çatır çutur sürekli her yere aynı card widgetını copy paste yapıp 50 kere yazmak yerine 1 kere burada yazdım tabii bu sınıf file private oldu ama en azından bu dosya içerisinde 30 kere farklı card widgetı oluşturmak yerine 1 tane oluşturuyoruz ve bunu veriyoruz childını da bu sınıftan nesne oluştururken istediğimiz gibi veririz böylece Card widgetının içerisindeki şeyleri de değiştire değiştire kullanabiliyor oluruz.

kullanırken de bu şekilde işte:

Kod:
 _CustomCard(
            //! doğru düzgün kullanım bu şekilde olmalı oop mantığı yine
            roundedRectangleBorder:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
            child: const SizedBox(
              height: 100,
              width: 100,
              child: Center(child: Text("Zireael")),
            ),
          ),

Son olarak Image wigdetlarından bahsetmek istiyorum Image widgetları için kendinize bir dosya oluşturun yine

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

class ImageLearn extends StatelessWidget {
  const ImageLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [

import falan ettik tasarım döndürüyoruz stless widget oluşturduk Columnı vermişiz columnın içine de şöyle yapalım:

durun direkt içerisini yazmayalım bu böyle bir kalsın çünkü aslında basit ama karışacak şöyle yapalım.

öncelikle şöyle bir sınıf oluşturalım

Kod:
class ImageItems {
  final String ciri = "ciri";
  final String barbara = "barbara";
  final String barbaraUrl = "https://beeimg.com/images/m47755035032.png";
}

şimdi bu sınıf da neyin nesi demeyin devam edin kod bütünlüğe vardığında anlayacaksınız. ciri, barbara ve barbaraUrl diye özellikler tanımladık değerlerini de verdik ImageItems sınıfını oluşturduk.

Kod:
class PngImage extends StatelessWidget {
  //! bir oop mantığıyla kendimize bir Image widgetı oluşturduk
  final String name;

  const PngImage({super.key, required this.name});

  @override
  Widget build(BuildContext context) {
    return Image.asset(
      nameWithPath,
      fit: BoxFit.cover, //bu tarz BoxFit. diyerek gösterme çeşitleri var
    );
  }

  String get nameWithPath =>
      'assets/$name.png'; //! bu bir metod extract methodu çok kullanıyoruz artık işimize yarıyor
  //! yaptığı şey şu nameWithPath i yazdığın yere => karşısındakini getiriyor olay bu getter diyoruz yani :P
}

Sa5LzK.jpg


burada da şöyle bir şey yaptık. PngImage widgetını oluşturuyoruz bu stless bir widget. name özelliği var. yani bu sınıftan nesne oluştururken name i vermek gerek required yapmışız. stlesswidget sınıfının override edilmesi gereken bir build metodu vardı onu vermek zorundayız onu da vermişiz geriye bir Image.asset widgetı döndürüyor. Image.asset demek şu demek projemizde dosyalarımızın içinde yani projemizin içerisinde assets diye bir klasör açarız ve resimlerimizi buraya koyarız genelde böyle yapılıyor assets diye bir klasör oluşturun tıpkı lib gibi. Daha sonra bu klasörün içerisine de resmi koyun. Ben ciri'nin bir resmini buldum onu koydum. Daha sonra Image.asset( ilk kisim, burası yani ilk kısım bizden bir path bekler. Yani projende resim nerde? onun yolunu ver demek istiyor. Sırf bunun için biz bu sınıfın içerisinde bir getter yazdık. Getter da ne aa ööağ demeyin bunu yüksek ihtimal önceki hatta ilk konularda dart derslerinde falan konuşmuştuk ya da öyle hayal ediyorum metod desekte olur geriye String döndüren nameWithPath diye bir metod diyelim geriye döndürdüğü şey de neymiş assets/$namedegiskeninintasidigideger.png Textini döndürüyormuş. Şimdi oturmaya başladı devam edelim

bu arada resminizi assets klasörünün içerisine ekledikten sonra pubspec.yaml dosyasına gidip şu şekilde ekleme yapmalısınız ki projenize resimler dahil olsun yoksa çalışmaz.

Kod:
# To add assets to your application, add an assets section, like this:
  assets:
    - assets/


daha sonra pub get diye bir seçenek gelir gelmezse de terminalden pub get yaparsınız hop resimler projeye dahil edildi. devam edelim farklı bir resim daha koyun değiştirip denersiniz çünkü kodu yazarken barbara için de yazmıştık ImageItems da

Sa51I8.png


Kod:
SizedBox(
                height: 300,
                width: 200,
                child: PngImage(name: ImageItems().ciri)),
            //! bu şekilde yolu veriyoruz projenin içinden başlıyor direkt assets klasörü içindeki ciri.png diyoruz oop mantığıyla yaptık tabi şimdi normalde "assets/ciri.png" diye vermiştik

kullanırken bu şekilde kullanıyoruz PngImage sınıfından bir nesne oluşturuyoruz name özelliğine de ImageItems sınıfındaki ciri yi vermişiz yani "ciri" daha sonra PngImage sınıfına bu gidiyor ve geriye pathi 'assets/ciri.png' olan bir Image widgetı döndürüyor fit özelliği de BoxFit.cover hatta.




Okuduğunuz için teşekkürler. Serinin bir sonraki konusunda görüşmek üzere <3 Gauloran
 

invisible blood

Uzman üye
15 Eyl 2023
1,177
442
Merhabalar seriye devam edelim ama bu da nedir diyenler için Flutter ile mobil uygulama geliştirmeye yönelik güzel bir seri ilerletiyorum. Önceki konular:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #6
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #7
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #8
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #9
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #10
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #11
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #12
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #13

devam edelim Stateless widgettan bahsederek devam edebiliriz. stless şu demek sayfa yapıyoruz örneğin ve bu sayfada herhangi bir data işlemi yapılmayacaksa stateless widget kullanılır sadece gösterme yapacağımız işlemlerde statik sayfa yapılarında stless widget kullanılması gerekir özetle alınanı gösterme üzerine kurulu bir yapıya sahip.

stateless_widget_learn.dart veya bu tarz bir dart dosyası açarak not alabilirsiniz.

0*4dAnkDc2odhmeyjv.png



Kod:
import 'package:flutter/material.dart';
class StatelessLearn extends StatelessWidget {
  const StatelessLearn({super.key});

importu yaptık StatelessLearn diye bir sınıf oluşturduk ve bu sınıf StatelessWidget sınıfından türüyor. st yazınca zaten vscode üzerinde otomatik stless gelir direkt oluşturur tek tek yazmanıza gerek yok ama alışkanlık olsun diye yazmanızı tavsiye ederim. bir stateless widget sınıfından türeyen bir sınıf oluşturduk bizden 1 metodu override edilmeyi zorunlu kılıyor build metodunu peki bu build metodu ne? bizlere widgetlarımızın oluşturulması için ana yeri verir build metodlarımızın içerisinde ana ekranlarımızı gelişitiririz. build metodunun içerisine yazılan return ifadesiyle artık tasarımımızı verebiliriz şu şekilde:

Kod:
@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            _emptyBox(), //! buraya bir sizedBox oluşturmuştuk height i 10 olan fakat bu tarz basit işlemlerde extract Method diyoruz
            const _CustomContainer(), //! buraya bir Container oluşturduk aslında daha sonra extract Widget diyerek otomatik olarak bunu stlesswidget tan türeyen bir sınıfa dönüştürüyor
          ],
        ));
  }

extract metod sayesinde otomatik olarak bu şekilde oluşturuyor bakalım:

Kod:
class _CustomContainer extends StatelessWidget {
  //! otomatik olarak oluşturuldu bu extract Widget demiştik, bir sınıfın başına sadece bu dosyadan buna erişilir olmasını istiyorsak _ atıyoruz başına isminin
  const _CustomContainer({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        color: Colors.red,
      ),
    );
  }
}

diğeri ise şu:

Kod:
class TitleTextWidget extends StatelessWidget {
  const TitleTextWidget({super.key, required this.text});

  final String? text;

  @override
  Widget build(BuildContext context) {
    return Text("data", style: Theme.of(context).textTheme.displaySmall);
  }
}

Yani yazdığımız kodlarda bakıyoruz kalabalık var o var bu var extract diyerek vscode bize yardımcı oluyor kodumuz okunabilir gözüküyor.

maxresdefault.jpg


Şimdi padding'ten bahsedelim padding_widget falan diye veya paddinglearn diye bir dart dosyası daha oluşturun not alabilirsiniz bu şekilde. düzgün bir tasarımda paddingler değişmemelidir ve padding iki kompanent arasında boşluk vermeyi sağlar padding vermek doğru bir kullanım sizedBox vererek her şeyi çözemezsiniz. hizalama işlemleri için önemlidir ve bu kodda eğer Column a wrap with widget diyerek Padding verseydik içerisindeki elemanlar otomatik olarak o padding ile başlayacaktı:

Kod:
class PaddingLearn extends StatelessWidget {
  const PaddingLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
              child: Container(
                color: Colors.white,
                height: 100,
              ),
            ),
            Container(
              color: Colors.white,
              height: 100,
            ),
            const Padding(
                padding: EdgeInsets.only(right: 20, top: 10),
                child: Text("Ali")),
            Padding(
              padding: const EdgeInsets.only(right: 20) +
                  const EdgeInsets.symmetric(vertical: 10),
              //!bu şekilde + metodu ile iki edgeinstets i bu şekilde kullanabiliyoruz vererek
            ),
          ],
        ));
  }
}

tabi paddingi direkt olarak vermek yerine bir önceki konuda olduğu gibi şu tarz yaklaşımlarda bulunmanız çok daha iyi olur

Kod:
class ProjectPadding {
  //! böyle bir sınıf oluşturup padding: ProjectPadding.pagePaddingVertical, olarak vermek çok daha mantıklıdır
  static const pagePaddingVertical = EdgeInsets.symmetric(vertical: 10);
  static const pagePaddingRightOnly = EdgeInsets.only(right: 20);
}

basitçe açıklayacak olursak artık EdgeInsets.symmetric(vertical:10) yazacağınıza okunabilirliğinizi arttırıyorsunuz ve her seferinde uğraşmıyorsunuz çok daha mantıklı bu şekilde vermeniz. ProjectPadding sınıfını oluşturduktan sonra kullanımı size bırakıyorum. Tabii padding yine aynı padding olacağından bir şey fark etmezsiniz ama böyle yapmaya alışın. Tabii bu da aslında pek doğru değil fakat şu anda geldiğimiz seviye için fena değil.

Flutter-Card-Widget-640x320.jpg


Şimdi card widgetına bakalım yine kendi kafanıza göre dart dosyası oluşturun

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

class CardLearn extends StatelessWidget {
  const CardLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [

şimdi buraya kadar geldik bir Column oluşturduk children dedik widgetlarını vereceğiz falan. Burada card widgetını öğrenmemiz gerekli. İşimize çok yarıyor.

Kod:
 Card(
            //! kart widgetımız güzeldir
            elevation: 15, //! gölge ekler öne çıkartır
            margin: ProjectMargins
                .cardMargin, //! paddingin benzeri dışarıyla ilgili içeriyle ilgili değil dışardan
            //color: Theme.of(context).colorScheme.onPrimary,
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(
                    20)), //! stadyum şeklini almasını sağlar shape olarak card widgetımıza bunu verebiliyoruz CircleBorder() var ve RoundedRectangleBorder() vardır bunlar karta şekil veriyor işte
            child: const SizedBox(
              height: 100,
              width: 100,
              child: Center(child: Text("Zireael")),
            ),
          ),

zaten yorum satırlarında açıkladım fakat her koddan sonra böyle yorum satırlarında açıklama yapmanın aslında mantıklı olmadığını fark ettim de bunu fark edene kadar çok zaman geçti yapacak bir şey yok yine idare edin. Card widgetında burada elevation vermişiz gölge diyebiliriz bu özelliğe daha sonra margin vermişiz paddingin benzeri demişiz dışardan veriyor o tarz bir olayı var onun dışında shape vermişiz RoundedRectangleBorder ile borderRadius özelliğine de circular olsun demişiz 20 vermişiz oranı tabii RoundedRectangleBorder yerine farklı şeyler de kullanılabilir bunların örneklerini araştırabilirsiniz. Cardın childına da bir Text widgetı vermişiz daha doğrusu text widgetının üstüne center ve sizedbox gelmiş o şekilde ayarlamışız ortalansın diye card widgetı. Texte de witcher 3 oynayanlar beğenebilir ufak bir easter egg bıraktım String olarak. devame edelim

Sa5yXZ.jpg


Kod:
 const Card(
            elevation: 15,
            child: SizedBox(
              height: 100,
              width: 100,
            ),
          ),
Bu arada bu üstteki değil de onun üstündeki kodda o margin nerden geldi diyenler için aşağıya şöyle temsili bir sınıf yazmıştım

Kod:
class ProjectMargins {
  static const cardMargin = EdgeInsets.all(10);
}

şimdi burada yapacağımız şey özel bir card widgetı oluşturmak. deneyelim:

Kod:
class _CustomCard extends StatelessWidget {
  //! oop mantığı ile bir CustomCard widgetı oluşturuyoruz sadece bu dosyadan erişilebilecek buna StatelessWidget tan türesin diyoruz sınıfımız
  final Widget child;
  var roundedRectangleBorder =
      RoundedRectangleBorder(borderRadius: BorderRadius.circular(20));
  _CustomCard(
      {super.key, required this.child, required this.roundedRectangleBorder});

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 15,
      margin: ProjectMargins.cardMargin,
      //color: Theme.of(context).colorScheme.onPrimary,
      shape: roundedRectangleBorder,
      child: child,
    );
  }
}

yukarıdaki kodda file private olan bir CustomCard sınıfı oluşturmuşuz stlesswidget sınıfından türüyor özetle bir stless widget oluşturmuşuz diyebiliriz. özelliklerini vermişiz yani bildiğimiz OOP mantığı bu sınıftan nesne oluşturulduğunda bir child beklenecek. daha sonra diğer özellikleri vermişiz ve stless widget sınıfının build metodunu override ederek bir Card tasarımı döndürmüşüz istediğimiz şekilde. Bunu yapmamızdaki olay şu artık ben her seferinde Card widgetı çatır çutur sürekli her yere aynı card widgetını copy paste yapıp 50 kere yazmak yerine 1 kere burada yazdım tabii bu sınıf file private oldu ama en azından bu dosya içerisinde 30 kere farklı card widgetı oluşturmak yerine 1 tane oluşturuyoruz ve bunu veriyoruz childını da bu sınıftan nesne oluştururken istediğimiz gibi veririz böylece Card widgetının içerisindeki şeyleri de değiştire değiştire kullanabiliyor oluruz.

kullanırken de bu şekilde işte:

Kod:
 _CustomCard(
            //! doğru düzgün kullanım bu şekilde olmalı oop mantığı yine
            roundedRectangleBorder:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
            child: const SizedBox(
              height: 100,
              width: 100,
              child: Center(child: Text("Zireael")),
            ),
          ),

Son olarak Image wigdetlarından bahsetmek istiyorum Image widgetları için kendinize bir dosya oluşturun yine

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

class ImageLearn extends StatelessWidget {
  const ImageLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [

import falan ettik tasarım döndürüyoruz stless widget oluşturduk Columnı vermişiz columnın içine de şöyle yapalım:

durun direkt içerisini yazmayalım bu böyle bir kalsın çünkü aslında basit ama karışacak şöyle yapalım.

öncelikle şöyle bir sınıf oluşturalım

Kod:
class ImageItems {
  final String ciri = "ciri";
  final String barbara = "barbara";
  final String barbaraUrl = "https://beeimg.com/images/m47755035032.png";
}

şimdi bu sınıf da neyin nesi demeyin devam edin kod bütünlüğe vardığında anlayacaksınız. ciri, barbara ve barbaraUrl diye özellikler tanımladık değerlerini de verdik ImageItems sınıfını oluşturduk.

Kod:
class PngImage extends StatelessWidget {
  //! bir oop mantığıyla kendimize bir Image widgetı oluşturduk
  final String name;

  const PngImage({super.key, required this.name});

  @override
  Widget build(BuildContext context) {
    return Image.asset(
      nameWithPath,
      fit: BoxFit.cover, //bu tarz BoxFit. diyerek gösterme çeşitleri var
    );
  }

  String get nameWithPath =>
      'assets/$name.png'; //! bu bir metod extract methodu çok kullanıyoruz artık işimize yarıyor
  //! yaptığı şey şu nameWithPath i yazdığın yere => karşısındakini getiriyor olay bu getter diyoruz yani :P
}

Sa5LzK.jpg


burada da şöyle bir şey yaptık. PngImage widgetını oluşturuyoruz bu stless bir widget. name özelliği var. yani bu sınıftan nesne oluştururken name i vermek gerek required yapmışız. stlesswidget sınıfının override edilmesi gereken bir build metodu vardı onu vermek zorundayız onu da vermişiz geriye bir Image.asset widgetı döndürüyor. Image.asset demek şu demek projemizde dosyalarımızın içinde yani projemizin içerisinde assets diye bir klasör açarız ve resimlerimizi buraya koyarız genelde böyle yapılıyor assets diye bir klasör oluşturun tıpkı lib gibi. Daha sonra bu klasörün içerisine de resmi koyun. Ben ciri'nin bir resmini buldum onu koydum. Daha sonra Image.asset( ilk kisim, burası yani ilk kısım bizden bir path bekler. Yani projende resim nerde? onun yolunu ver demek istiyor. Sırf bunun için biz bu sınıfın içerisinde bir getter yazdık. Getter da ne aa ööağ demeyin bunu yüksek ihtimal önceki hatta ilk konularda dart derslerinde falan konuşmuştuk ya da öyle hayal ediyorum metod desekte olur geriye String döndüren nameWithPath diye bir metod diyelim geriye döndürdüğü şey de neymiş assets/$namedegiskeninintasidigideger.png Textini döndürüyormuş. Şimdi oturmaya başladı devam edelim

bu arada resminizi assets klasörünün içerisine ekledikten sonra pubspec.yaml dosyasına gidip şu şekilde ekleme yapmalısınız ki projenize resimler dahil olsun yoksa çalışmaz.

Kod:
# To add assets to your application, add an assets section, like this:
  assets:
    - assets/


daha sonra pub get diye bir seçenek gelir gelmezse de terminalden pub get yaparsınız hop resimler projeye dahil edildi. devam edelim farklı bir resim daha koyun değiştirip denersiniz çünkü kodu yazarken barbara için de yazmıştık ImageItems da

Sa51I8.png


Kod:
SizedBox(
                height: 300,
                width: 200,
                child: PngImage(name: ImageItems().ciri)),
            //! bu şekilde yolu veriyoruz projenin içinden başlıyor direkt assets klasörü içindeki ciri.png diyoruz oop mantığıyla yaptık tabi şimdi normalde "assets/ciri.png" diye vermiştik

kullanırken bu şekilde kullanıyoruz PngImage sınıfından bir nesne oluşturuyoruz name özelliğine de ImageItems sınıfındaki ciri yi vermişiz yani "ciri" daha sonra PngImage sınıfına bu gidiyor ve geriye pathi 'assets/ciri.png' olan bir Image widgetı döndürüyor fit özelliği de BoxFit.cover hatta.




Okuduğunuz için teşekkürler. Serinin bir sonraki konusunda görüşmek üzere <3 Gauloran
Adam yaaaa
 

H@cked BaBy

Basın&Medya Ekibi
28 Haz 2023
2,399
984
Arkana bak
Merhabalar seriye devam edelim ama bu da nedir diyenler için Flutter ile mobil uygulama geliştirmeye yönelik güzel bir seri ilerletiyorum. Önceki konular:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #6
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #7
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #8
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #9
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #10
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #11
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #12
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #13

devam edelim Stateless widgettan bahsederek devam edebiliriz. stless şu demek sayfa yapıyoruz örneğin ve bu sayfada herhangi bir data işlemi yapılmayacaksa stateless widget kullanılır sadece gösterme yapacağımız işlemlerde statik sayfa yapılarında stless widget kullanılması gerekir özetle alınanı gösterme üzerine kurulu bir yapıya sahip.

stateless_widget_learn.dart veya bu tarz bir dart dosyası açarak not alabilirsiniz.

0*4dAnkDc2odhmeyjv.png



Kod:
import 'package:flutter/material.dart';
class StatelessLearn extends StatelessWidget {
  const StatelessLearn({super.key});

importu yaptık StatelessLearn diye bir sınıf oluşturduk ve bu sınıf StatelessWidget sınıfından türüyor. st yazınca zaten vscode üzerinde otomatik stless gelir direkt oluşturur tek tek yazmanıza gerek yok ama alışkanlık olsun diye yazmanızı tavsiye ederim. bir stateless widget sınıfından türeyen bir sınıf oluşturduk bizden 1 metodu override edilmeyi zorunlu kılıyor build metodunu peki bu build metodu ne? bizlere widgetlarımızın oluşturulması için ana yeri verir build metodlarımızın içerisinde ana ekranlarımızı gelişitiririz. build metodunun içerisine yazılan return ifadesiyle artık tasarımımızı verebiliriz şu şekilde:

Kod:
@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            _emptyBox(), //! buraya bir sizedBox oluşturmuştuk height i 10 olan fakat bu tarz basit işlemlerde extract Method diyoruz
            const _CustomContainer(), //! buraya bir Container oluşturduk aslında daha sonra extract Widget diyerek otomatik olarak bunu stlesswidget tan türeyen bir sınıfa dönüştürüyor
          ],
        ));
  }

extract metod sayesinde otomatik olarak bu şekilde oluşturuyor bakalım:

Kod:
class _CustomContainer extends StatelessWidget {
  //! otomatik olarak oluşturuldu bu extract Widget demiştik, bir sınıfın başına sadece bu dosyadan buna erişilir olmasını istiyorsak _ atıyoruz başına isminin
  const _CustomContainer({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        color: Colors.red,
      ),
    );
  }
}

diğeri ise şu:

Kod:
class TitleTextWidget extends StatelessWidget {
  const TitleTextWidget({super.key, required this.text});

  final String? text;

  @override
  Widget build(BuildContext context) {
    return Text("data", style: Theme.of(context).textTheme.displaySmall);
  }
}

Yani yazdığımız kodlarda bakıyoruz kalabalık var o var bu var extract diyerek vscode bize yardımcı oluyor kodumuz okunabilir gözüküyor.

maxresdefault.jpg


Şimdi padding'ten bahsedelim padding_widget falan diye veya paddinglearn diye bir dart dosyası daha oluşturun not alabilirsiniz bu şekilde. düzgün bir tasarımda paddingler değişmemelidir ve padding iki kompanent arasında boşluk vermeyi sağlar padding vermek doğru bir kullanım sizedBox vererek her şeyi çözemezsiniz. hizalama işlemleri için önemlidir ve bu kodda eğer Column a wrap with widget diyerek Padding verseydik içerisindeki elemanlar otomatik olarak o padding ile başlayacaktı:

Kod:
class PaddingLearn extends StatelessWidget {
  const PaddingLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
              child: Container(
                color: Colors.white,
                height: 100,
              ),
            ),
            Container(
              color: Colors.white,
              height: 100,
            ),
            const Padding(
                padding: EdgeInsets.only(right: 20, top: 10),
                child: Text("Ali")),
            Padding(
              padding: const EdgeInsets.only(right: 20) +
                  const EdgeInsets.symmetric(vertical: 10),
              //!bu şekilde + metodu ile iki edgeinstets i bu şekilde kullanabiliyoruz vererek
            ),
          ],
        ));
  }
}

tabi paddingi direkt olarak vermek yerine bir önceki konuda olduğu gibi şu tarz yaklaşımlarda bulunmanız çok daha iyi olur

Kod:
class ProjectPadding {
  //! böyle bir sınıf oluşturup padding: ProjectPadding.pagePaddingVertical, olarak vermek çok daha mantıklıdır
  static const pagePaddingVertical = EdgeInsets.symmetric(vertical: 10);
  static const pagePaddingRightOnly = EdgeInsets.only(right: 20);
}

basitçe açıklayacak olursak artık EdgeInsets.symmetric(vertical:10) yazacağınıza okunabilirliğinizi arttırıyorsunuz ve her seferinde uğraşmıyorsunuz çok daha mantıklı bu şekilde vermeniz. ProjectPadding sınıfını oluşturduktan sonra kullanımı size bırakıyorum. Tabii padding yine aynı padding olacağından bir şey fark etmezsiniz ama böyle yapmaya alışın. Tabii bu da aslında pek doğru değil fakat şu anda geldiğimiz seviye için fena değil.

Flutter-Card-Widget-640x320.jpg


Şimdi card widgetına bakalım yine kendi kafanıza göre dart dosyası oluşturun

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

class CardLearn extends StatelessWidget {
  const CardLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [

şimdi buraya kadar geldik bir Column oluşturduk children dedik widgetlarını vereceğiz falan. Burada card widgetını öğrenmemiz gerekli. İşimize çok yarıyor.

Kod:
 Card(
            //! kart widgetımız güzeldir
            elevation: 15, //! gölge ekler öne çıkartır
            margin: ProjectMargins
                .cardMargin, //! paddingin benzeri dışarıyla ilgili içeriyle ilgili değil dışardan
            //color: Theme.of(context).colorScheme.onPrimary,
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(
                    20)), //! stadyum şeklini almasını sağlar shape olarak card widgetımıza bunu verebiliyoruz CircleBorder() var ve RoundedRectangleBorder() vardır bunlar karta şekil veriyor işte
            child: const SizedBox(
              height: 100,
              width: 100,
              child: Center(child: Text("Zireael")),
            ),
          ),

zaten yorum satırlarında açıkladım fakat her koddan sonra böyle yorum satırlarında açıklama yapmanın aslında mantıklı olmadığını fark ettim de bunu fark edene kadar çok zaman geçti yapacak bir şey yok yine idare edin. Card widgetında burada elevation vermişiz gölge diyebiliriz bu özelliğe daha sonra margin vermişiz paddingin benzeri demişiz dışardan veriyor o tarz bir olayı var onun dışında shape vermişiz RoundedRectangleBorder ile borderRadius özelliğine de circular olsun demişiz 20 vermişiz oranı tabii RoundedRectangleBorder yerine farklı şeyler de kullanılabilir bunların örneklerini araştırabilirsiniz. Cardın childına da bir Text widgetı vermişiz daha doğrusu text widgetının üstüne center ve sizedbox gelmiş o şekilde ayarlamışız ortalansın diye card widgetı. Texte de witcher 3 oynayanlar beğenebilir ufak bir easter egg bıraktım String olarak. devame edelim

Sa5yXZ.jpg


Kod:
 const Card(
            elevation: 15,
            child: SizedBox(
              height: 100,
              width: 100,
            ),
          ),
Bu arada bu üstteki değil de onun üstündeki kodda o margin nerden geldi diyenler için aşağıya şöyle temsili bir sınıf yazmıştım

Kod:
class ProjectMargins {
  static const cardMargin = EdgeInsets.all(10);
}

şimdi burada yapacağımız şey özel bir card widgetı oluşturmak. deneyelim:

Kod:
class _CustomCard extends StatelessWidget {
  //! oop mantığı ile bir CustomCard widgetı oluşturuyoruz sadece bu dosyadan erişilebilecek buna StatelessWidget tan türesin diyoruz sınıfımız
  final Widget child;
  var roundedRectangleBorder =
      RoundedRectangleBorder(borderRadius: BorderRadius.circular(20));
  _CustomCard(
      {super.key, required this.child, required this.roundedRectangleBorder});

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 15,
      margin: ProjectMargins.cardMargin,
      //color: Theme.of(context).colorScheme.onPrimary,
      shape: roundedRectangleBorder,
      child: child,
    );
  }
}

yukarıdaki kodda file private olan bir CustomCard sınıfı oluşturmuşuz stlesswidget sınıfından türüyor özetle bir stless widget oluşturmuşuz diyebiliriz. özelliklerini vermişiz yani bildiğimiz OOP mantığı bu sınıftan nesne oluşturulduğunda bir child beklenecek. daha sonra diğer özellikleri vermişiz ve stless widget sınıfının build metodunu override ederek bir Card tasarımı döndürmüşüz istediğimiz şekilde. Bunu yapmamızdaki olay şu artık ben her seferinde Card widgetı çatır çutur sürekli her yere aynı card widgetını copy paste yapıp 50 kere yazmak yerine 1 kere burada yazdım tabii bu sınıf file private oldu ama en azından bu dosya içerisinde 30 kere farklı card widgetı oluşturmak yerine 1 tane oluşturuyoruz ve bunu veriyoruz childını da bu sınıftan nesne oluştururken istediğimiz gibi veririz böylece Card widgetının içerisindeki şeyleri de değiştire değiştire kullanabiliyor oluruz.

kullanırken de bu şekilde işte:

Kod:
 _CustomCard(
            //! doğru düzgün kullanım bu şekilde olmalı oop mantığı yine
            roundedRectangleBorder:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
            child: const SizedBox(
              height: 100,
              width: 100,
              child: Center(child: Text("Zireael")),
            ),
          ),

Son olarak Image wigdetlarından bahsetmek istiyorum Image widgetları için kendinize bir dosya oluşturun yine

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

class ImageLearn extends StatelessWidget {
  const ImageLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [

import falan ettik tasarım döndürüyoruz stless widget oluşturduk Columnı vermişiz columnın içine de şöyle yapalım:

durun direkt içerisini yazmayalım bu böyle bir kalsın çünkü aslında basit ama karışacak şöyle yapalım.

öncelikle şöyle bir sınıf oluşturalım

Kod:
class ImageItems {
  final String ciri = "ciri";
  final String barbara = "barbara";
  final String barbaraUrl = "https://beeimg.com/images/m47755035032.png";
}

şimdi bu sınıf da neyin nesi demeyin devam edin kod bütünlüğe vardığında anlayacaksınız. ciri, barbara ve barbaraUrl diye özellikler tanımladık değerlerini de verdik ImageItems sınıfını oluşturduk.

Kod:
class PngImage extends StatelessWidget {
  //! bir oop mantığıyla kendimize bir Image widgetı oluşturduk
  final String name;

  const PngImage({super.key, required this.name});

  @override
  Widget build(BuildContext context) {
    return Image.asset(
      nameWithPath,
      fit: BoxFit.cover, //bu tarz BoxFit. diyerek gösterme çeşitleri var
    );
  }

  String get nameWithPath =>
      'assets/$name.png'; //! bu bir metod extract methodu çok kullanıyoruz artık işimize yarıyor
  //! yaptığı şey şu nameWithPath i yazdığın yere => karşısındakini getiriyor olay bu getter diyoruz yani :P
}

Sa5LzK.jpg


burada da şöyle bir şey yaptık. PngImage widgetını oluşturuyoruz bu stless bir widget. name özelliği var. yani bu sınıftan nesne oluştururken name i vermek gerek required yapmışız. stlesswidget sınıfının override edilmesi gereken bir build metodu vardı onu vermek zorundayız onu da vermişiz geriye bir Image.asset widgetı döndürüyor. Image.asset demek şu demek projemizde dosyalarımızın içinde yani projemizin içerisinde assets diye bir klasör açarız ve resimlerimizi buraya koyarız genelde böyle yapılıyor assets diye bir klasör oluşturun tıpkı lib gibi. Daha sonra bu klasörün içerisine de resmi koyun. Ben ciri'nin bir resmini buldum onu koydum. Daha sonra Image.asset( ilk kisim, burası yani ilk kısım bizden bir path bekler. Yani projende resim nerde? onun yolunu ver demek istiyor. Sırf bunun için biz bu sınıfın içerisinde bir getter yazdık. Getter da ne aa ööağ demeyin bunu yüksek ihtimal önceki hatta ilk konularda dart derslerinde falan konuşmuştuk ya da öyle hayal ediyorum metod desekte olur geriye String döndüren nameWithPath diye bir metod diyelim geriye döndürdüğü şey de neymiş assets/$namedegiskeninintasidigideger.png Textini döndürüyormuş. Şimdi oturmaya başladı devam edelim

bu arada resminizi assets klasörünün içerisine ekledikten sonra pubspec.yaml dosyasına gidip şu şekilde ekleme yapmalısınız ki projenize resimler dahil olsun yoksa çalışmaz.

Kod:
# To add assets to your application, add an assets section, like this:
  assets:
    - assets/


daha sonra pub get diye bir seçenek gelir gelmezse de terminalden pub get yaparsınız hop resimler projeye dahil edildi. devam edelim farklı bir resim daha koyun değiştirip denersiniz çünkü kodu yazarken barbara için de yazmıştık ImageItems da

Sa51I8.png


Kod:
SizedBox(
                height: 300,
                width: 200,
                child: PngImage(name: ImageItems().ciri)),
            //! bu şekilde yolu veriyoruz projenin içinden başlıyor direkt assets klasörü içindeki ciri.png diyoruz oop mantığıyla yaptık tabi şimdi normalde "assets/ciri.png" diye vermiştik

kullanırken bu şekilde kullanıyoruz PngImage sınıfından bir nesne oluşturuyoruz name özelliğine de ImageItems sınıfındaki ciri yi vermişiz yani "ciri" daha sonra PngImage sınıfına bu gidiyor ve geriye pathi 'assets/ciri.png' olan bir Image widgetı döndürüyor fit özelliği de BoxFit.cover hatta.




Okuduğunuz için teşekkürler. Serinin bir sonraki konusunda görüşmek üzere <3 Gauloran
Eline emeğine sağlık.
 

harasad

Katılımcı Üye
14 Eyl 2023
307
106
Merhabalar seriye devam edelim ama bu da nedir diyenler için Flutter ile mobil uygulama geliştirmeye yönelik güzel bir seri ilerletiyorum. Önceki konular:

0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #1
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #2
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #3
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #4
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #5
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #6
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #7
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #8
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #9
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #10
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #11
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #12
0'dan İleri Seviyeye Mobil Uygulama Geliştirme Eğitimi Veriyorum #13

devam edelim Stateless widgettan bahsederek devam edebiliriz. stless şu demek sayfa yapıyoruz örneğin ve bu sayfada herhangi bir data işlemi yapılmayacaksa stateless widget kullanılır sadece gösterme yapacağımız işlemlerde statik sayfa yapılarında stless widget kullanılması gerekir özetle alınanı gösterme üzerine kurulu bir yapıya sahip.

stateless_widget_learn.dart veya bu tarz bir dart dosyası açarak not alabilirsiniz.

0*4dAnkDc2odhmeyjv.png



Kod:
import 'package:flutter/material.dart';
class StatelessLearn extends StatelessWidget {
  const StatelessLearn({super.key});

importu yaptık StatelessLearn diye bir sınıf oluşturduk ve bu sınıf StatelessWidget sınıfından türüyor. st yazınca zaten vscode üzerinde otomatik stless gelir direkt oluşturur tek tek yazmanıza gerek yok ama alışkanlık olsun diye yazmanızı tavsiye ederim. bir stateless widget sınıfından türeyen bir sınıf oluşturduk bizden 1 metodu override edilmeyi zorunlu kılıyor build metodunu peki bu build metodu ne? bizlere widgetlarımızın oluşturulması için ana yeri verir build metodlarımızın içerisinde ana ekranlarımızı gelişitiririz. build metodunun içerisine yazılan return ifadesiyle artık tasarımımızı verebiliriz şu şekilde:

Kod:
@override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            const TitleTextWidget(
              text: "veli",
            ),
            _emptyBox(), //! buraya bir sizedBox oluşturmuştuk height i 10 olan fakat bu tarz basit işlemlerde extract Method diyoruz
            const _CustomContainer(), //! buraya bir Container oluşturduk aslında daha sonra extract Widget diyerek otomatik olarak bunu stlesswidget tan türeyen bir sınıfa dönüştürüyor
          ],
        ));
  }

extract metod sayesinde otomatik olarak bu şekilde oluşturuyor bakalım:

Kod:
class _CustomContainer extends StatelessWidget {
  //! otomatik olarak oluşturuldu bu extract Widget demiştik, bir sınıfın başına sadece bu dosyadan buna erişilir olmasını istiyorsak _ atıyoruz başına isminin
  const _CustomContainer({
    super.key,
  });

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(20),
        color: Colors.red,
      ),
    );
  }
}

diğeri ise şu:

Kod:
class TitleTextWidget extends StatelessWidget {
  const TitleTextWidget({super.key, required this.text});

  final String? text;

  @override
  Widget build(BuildContext context) {
    return Text("data", style: Theme.of(context).textTheme.displaySmall);
  }
}

Yani yazdığımız kodlarda bakıyoruz kalabalık var o var bu var extract diyerek vscode bize yardımcı oluyor kodumuz okunabilir gözüküyor.

maxresdefault.jpg


Şimdi padding'ten bahsedelim padding_widget falan diye veya paddinglearn diye bir dart dosyası daha oluşturun not alabilirsiniz bu şekilde. düzgün bir tasarımda paddingler değişmemelidir ve padding iki kompanent arasında boşluk vermeyi sağlar padding vermek doğru bir kullanım sizedBox vererek her şeyi çözemezsiniz. hizalama işlemleri için önemlidir ve bu kodda eğer Column a wrap with widget diyerek Padding verseydik içerisindeki elemanlar otomatik olarak o padding ile başlayacaktı:

Kod:
class PaddingLearn extends StatelessWidget {
  const PaddingLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 20),
              child: Container(
                color: Colors.white,
                height: 100,
              ),
            ),
            Container(
              color: Colors.white,
              height: 100,
            ),
            const Padding(
                padding: EdgeInsets.only(right: 20, top: 10),
                child: Text("Ali")),
            Padding(
              padding: const EdgeInsets.only(right: 20) +
                  const EdgeInsets.symmetric(vertical: 10),
              //!bu şekilde + metodu ile iki edgeinstets i bu şekilde kullanabiliyoruz vererek
            ),
          ],
        ));
  }
}

tabi paddingi direkt olarak vermek yerine bir önceki konuda olduğu gibi şu tarz yaklaşımlarda bulunmanız çok daha iyi olur

Kod:
class ProjectPadding {
  //! böyle bir sınıf oluşturup padding: ProjectPadding.pagePaddingVertical, olarak vermek çok daha mantıklıdır
  static const pagePaddingVertical = EdgeInsets.symmetric(vertical: 10);
  static const pagePaddingRightOnly = EdgeInsets.only(right: 20);
}

basitçe açıklayacak olursak artık EdgeInsets.symmetric(vertical:10) yazacağınıza okunabilirliğinizi arttırıyorsunuz ve her seferinde uğraşmıyorsunuz çok daha mantıklı bu şekilde vermeniz. ProjectPadding sınıfını oluşturduktan sonra kullanımı size bırakıyorum. Tabii padding yine aynı padding olacağından bir şey fark etmezsiniz ama böyle yapmaya alışın. Tabii bu da aslında pek doğru değil fakat şu anda geldiğimiz seviye için fena değil.

Flutter-Card-Widget-640x320.jpg


Şimdi card widgetına bakalım yine kendi kafanıza göre dart dosyası oluşturun

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

class CardLearn extends StatelessWidget {
  const CardLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: [

şimdi buraya kadar geldik bir Column oluşturduk children dedik widgetlarını vereceğiz falan. Burada card widgetını öğrenmemiz gerekli. İşimize çok yarıyor.

Kod:
 Card(
            //! kart widgetımız güzeldir
            elevation: 15, //! gölge ekler öne çıkartır
            margin: ProjectMargins
                .cardMargin, //! paddingin benzeri dışarıyla ilgili içeriyle ilgili değil dışardan
            //color: Theme.of(context).colorScheme.onPrimary,
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(
                    20)), //! stadyum şeklini almasını sağlar shape olarak card widgetımıza bunu verebiliyoruz CircleBorder() var ve RoundedRectangleBorder() vardır bunlar karta şekil veriyor işte
            child: const SizedBox(
              height: 100,
              width: 100,
              child: Center(child: Text("Zireael")),
            ),
          ),

zaten yorum satırlarında açıkladım fakat her koddan sonra böyle yorum satırlarında açıklama yapmanın aslında mantıklı olmadığını fark ettim de bunu fark edene kadar çok zaman geçti yapacak bir şey yok yine idare edin. Card widgetında burada elevation vermişiz gölge diyebiliriz bu özelliğe daha sonra margin vermişiz paddingin benzeri demişiz dışardan veriyor o tarz bir olayı var onun dışında shape vermişiz RoundedRectangleBorder ile borderRadius özelliğine de circular olsun demişiz 20 vermişiz oranı tabii RoundedRectangleBorder yerine farklı şeyler de kullanılabilir bunların örneklerini araştırabilirsiniz. Cardın childına da bir Text widgetı vermişiz daha doğrusu text widgetının üstüne center ve sizedbox gelmiş o şekilde ayarlamışız ortalansın diye card widgetı. Texte de witcher 3 oynayanlar beğenebilir ufak bir easter egg bıraktım String olarak. devame edelim

Sa5yXZ.jpg


Kod:
 const Card(
            elevation: 15,
            child: SizedBox(
              height: 100,
              width: 100,
            ),
          ),
Bu arada bu üstteki değil de onun üstündeki kodda o margin nerden geldi diyenler için aşağıya şöyle temsili bir sınıf yazmıştım

Kod:
class ProjectMargins {
  static const cardMargin = EdgeInsets.all(10);
}

şimdi burada yapacağımız şey özel bir card widgetı oluşturmak. deneyelim:

Kod:
class _CustomCard extends StatelessWidget {
  //! oop mantığı ile bir CustomCard widgetı oluşturuyoruz sadece bu dosyadan erişilebilecek buna StatelessWidget tan türesin diyoruz sınıfımız
  final Widget child;
  var roundedRectangleBorder =
      RoundedRectangleBorder(borderRadius: BorderRadius.circular(20));
  _CustomCard(
      {super.key, required this.child, required this.roundedRectangleBorder});

  @override
  Widget build(BuildContext context) {
    return Card(
      elevation: 15,
      margin: ProjectMargins.cardMargin,
      //color: Theme.of(context).colorScheme.onPrimary,
      shape: roundedRectangleBorder,
      child: child,
    );
  }
}

yukarıdaki kodda file private olan bir CustomCard sınıfı oluşturmuşuz stlesswidget sınıfından türüyor özetle bir stless widget oluşturmuşuz diyebiliriz. özelliklerini vermişiz yani bildiğimiz OOP mantığı bu sınıftan nesne oluşturulduğunda bir child beklenecek. daha sonra diğer özellikleri vermişiz ve stless widget sınıfının build metodunu override ederek bir Card tasarımı döndürmüşüz istediğimiz şekilde. Bunu yapmamızdaki olay şu artık ben her seferinde Card widgetı çatır çutur sürekli her yere aynı card widgetını copy paste yapıp 50 kere yazmak yerine 1 kere burada yazdım tabii bu sınıf file private oldu ama en azından bu dosya içerisinde 30 kere farklı card widgetı oluşturmak yerine 1 tane oluşturuyoruz ve bunu veriyoruz childını da bu sınıftan nesne oluştururken istediğimiz gibi veririz böylece Card widgetının içerisindeki şeyleri de değiştire değiştire kullanabiliyor oluruz.

kullanırken de bu şekilde işte:

Kod:
 _CustomCard(
            //! doğru düzgün kullanım bu şekilde olmalı oop mantığı yine
            roundedRectangleBorder:
                RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
            child: const SizedBox(
              height: 100,
              width: 100,
              child: Center(child: Text("Zireael")),
            ),
          ),

Son olarak Image wigdetlarından bahsetmek istiyorum Image widgetları için kendinize bir dosya oluşturun yine

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

class ImageLearn extends StatelessWidget {
  const ImageLearn({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Column(
          children: [

import falan ettik tasarım döndürüyoruz stless widget oluşturduk Columnı vermişiz columnın içine de şöyle yapalım:

durun direkt içerisini yazmayalım bu böyle bir kalsın çünkü aslında basit ama karışacak şöyle yapalım.

öncelikle şöyle bir sınıf oluşturalım

Kod:
class ImageItems {
  final String ciri = "ciri";
  final String barbara = "barbara";
  final String barbaraUrl = "https://beeimg.com/images/m47755035032.png";
}

şimdi bu sınıf da neyin nesi demeyin devam edin kod bütünlüğe vardığında anlayacaksınız. ciri, barbara ve barbaraUrl diye özellikler tanımladık değerlerini de verdik ImageItems sınıfını oluşturduk.

Kod:
class PngImage extends StatelessWidget {
  //! bir oop mantığıyla kendimize bir Image widgetı oluşturduk
  final String name;

  const PngImage({super.key, required this.name});

  @override
  Widget build(BuildContext context) {
    return Image.asset(
      nameWithPath,
      fit: BoxFit.cover, //bu tarz BoxFit. diyerek gösterme çeşitleri var
    );
  }

  String get nameWithPath =>
      'assets/$name.png'; //! bu bir metod extract methodu çok kullanıyoruz artık işimize yarıyor
  //! yaptığı şey şu nameWithPath i yazdığın yere => karşısındakini getiriyor olay bu getter diyoruz yani :P
}

Sa5LzK.jpg


burada da şöyle bir şey yaptık. PngImage widgetını oluşturuyoruz bu stless bir widget. name özelliği var. yani bu sınıftan nesne oluştururken name i vermek gerek required yapmışız. stlesswidget sınıfının override edilmesi gereken bir build metodu vardı onu vermek zorundayız onu da vermişiz geriye bir Image.asset widgetı döndürüyor. Image.asset demek şu demek projemizde dosyalarımızın içinde yani projemizin içerisinde assets diye bir klasör açarız ve resimlerimizi buraya koyarız genelde böyle yapılıyor assets diye bir klasör oluşturun tıpkı lib gibi. Daha sonra bu klasörün içerisine de resmi koyun. Ben ciri'nin bir resmini buldum onu koydum. Daha sonra Image.asset( ilk kisim, burası yani ilk kısım bizden bir path bekler. Yani projende resim nerde? onun yolunu ver demek istiyor. Sırf bunun için biz bu sınıfın içerisinde bir getter yazdık. Getter da ne aa ööağ demeyin bunu yüksek ihtimal önceki hatta ilk konularda dart derslerinde falan konuşmuştuk ya da öyle hayal ediyorum metod desekte olur geriye String döndüren nameWithPath diye bir metod diyelim geriye döndürdüğü şey de neymiş assets/$namedegiskeninintasidigideger.png Textini döndürüyormuş. Şimdi oturmaya başladı devam edelim

bu arada resminizi assets klasörünün içerisine ekledikten sonra pubspec.yaml dosyasına gidip şu şekilde ekleme yapmalısınız ki projenize resimler dahil olsun yoksa çalışmaz.

Kod:
# To add assets to your application, add an assets section, like this:
  assets:
    - assets/


daha sonra pub get diye bir seçenek gelir gelmezse de terminalden pub get yaparsınız hop resimler projeye dahil edildi. devam edelim farklı bir resim daha koyun değiştirip denersiniz çünkü kodu yazarken barbara için de yazmıştık ImageItems da

Sa51I8.png


Kod:
SizedBox(
                height: 300,
                width: 200,
                child: PngImage(name: ImageItems().ciri)),
            //! bu şekilde yolu veriyoruz projenin içinden başlıyor direkt assets klasörü içindeki ciri.png diyoruz oop mantığıyla yaptık tabi şimdi normalde "assets/ciri.png" diye vermiştik

kullanırken bu şekilde kullanıyoruz PngImage sınıfından bir nesne oluşturuyoruz name özelliğine de ImageItems sınıfındaki ciri yi vermişiz yani "ciri" daha sonra PngImage sınıfına bu gidiyor ve geriye pathi 'assets/ciri.png' olan bir Image widgetı döndürüyor fit özelliği de BoxFit.cover hatta.




Okuduğunuz için teşekkürler. Serinin bir sonraki konusunda görüşmek üzere <3 Gauloran
eline sağlık
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.