Flutter - Hızlı Kılavuz

Genel olarak, bir mobil uygulama geliştirmek karmaşık ve zorlu bir iştir. Bir mobil uygulama geliştirmek için birçok çerçeve mevcuttur. Android, Java diline dayalı yerel bir çerçeve sağlar ve iOS, Objective-C / Swift diline dayalı yerel bir çerçeve sağlar.

Bununla birlikte, her iki işletim sistemini destekleyen bir uygulama geliştirmek için, iki farklı çerçeve kullanarak iki farklı dilde kodlamamız gerekir. Bu karmaşıklığın üstesinden gelmeye yardımcı olmak için, her iki işletim sistemini de destekleyen mobil çerçeveler mevcuttur. Bu çerçeveler, basit HTML tabanlı hibrit mobil uygulama çerçevesinden (Kullanıcı Arabirimi için HTML ve uygulama mantığı için JavaScript kullanır), karmaşık dile özgü çerçeveye (kodu yerel koda dönüştürmenin ağır yükünü yerine getirir) kadar çeşitlilik gösterir. Basitlikleri veya karmaşıklıkları ne olursa olsun, bu çerçevelerin her zaman birçok dezavantajı vardır ve ana dezavantajlarından biri yavaş performanslarıdır.

Bu senaryoda, Dart diline dayalı basit ve yüksek performanslı bir çerçeve olan Flutter, kullanıcı arayüzünü yerel çerçeve yerine doğrudan işletim sisteminin tuvalinde işleyerek yüksek performans sağlar.

Flutter ayrıca modern bir uygulama oluşturmak için birçok kullanıma hazır widget (UI) sunar. Bu widget'lar mobil ortam için optimize edilmiştir ve uygulamayı widget kullanarak tasarlamak HTML tasarlamak kadar basittir.

Spesifik olmak gerekirse, Flutter uygulamasının kendisi bir widget'tır. Flutter widget'ları ayrıca animasyonları ve hareketleri de destekler. Uygulama mantığı, reaktif programlamaya dayanmaktadır. Widget isteğe bağlı olarak bir duruma sahip olabilir. Parçacık durumunu değiştirerek, Flutter otomatik olarak parçacığın durumunu (eski ve yeni) karşılaştırır ve parçacığın tamamını yeniden oluşturmak yerine yalnızca gerekli değişikliklerle oluşturur.

Önümüzdeki bölümlerde tüm mimariyi tartışacağız.

Flutter'ın Özellikleri

Flutter çerçevesi, geliştiricilere aşağıdaki özellikleri sunar -

  • Modern ve reaktif çerçeve.

  • Dart programlama dilini kullanır ve öğrenmesi çok kolaydır.

  • Hızlı gelişme.

  • Güzel ve akıcı kullanıcı arayüzleri.

  • Büyük widget kataloğu.

  • Birden çok platform için aynı kullanıcı arayüzünü çalıştırır.

  • Yüksek performanslı uygulama.

Flutter'ın Avantajları

Flutter, yüksek performans ve olağanüstü mobil uygulama için güzel ve özelleştirilebilir widget'larla birlikte gelir. Tüm özel ihtiyaçları ve gereksinimleri karşılar. Bunların yanı sıra, Flutter aşağıda belirtildiği gibi daha birçok avantaj sunar -

  • Dart, uygulamanızın yeteneklerini genişletmenize olanak tanıyan geniş bir yazılım paketleri havuzuna sahiptir.

  • Geliştiricilerin her iki uygulama (hem Android hem de iOS platformları) için yalnızca tek bir kod tabanı yazmaları gerekir. Flutter , gelecekte başka platformlara da genişletilebilir.

  • Flutter'ın daha az teste ihtiyacı var. Tek kod tabanı nedeniyle, her iki platform için bir kez otomatik testler yazmamız yeterlidir.

  • Flutter'ın basitliği, onu hızlı geliştirme için iyi bir aday yapar. Özelleştirme yeteneği ve genişletilebilirliği onu daha da güçlü kılar.

  • Flutter ile geliştiriciler, widget'lar ve düzeni üzerinde tam kontrole sahiptir.

  • Flutter, olağanüstü hızlı yeniden yükleme ile harika geliştirici araçları sunar.

Flutter'ın dezavantajları

Birçok avantajına rağmen, flutter aşağıdaki dezavantajlara sahiptir:

  • Dart dilinde kodlandığından, geliştiricinin yeni bir dil öğrenmesi gerekir (öğrenmesi kolay olsa da).

  • Modern çerçeve, mantığı ve kullanıcı arayüzünü olabildiğince ayırmaya çalışır, ancak Flutter'da kullanıcı arayüzü ve mantık birbirine karıştırılmıştır. Akıllı kodlama kullanarak ve kullanıcı arayüzü ile mantığı ayırmak için üst düzey modül kullanarak bunun üstesinden gelebiliriz.

  • Flutter, mobil uygulama oluşturmak için başka bir çerçevedir. Geliştiriciler, yüksek nüfuslu segmentte doğru geliştirme araçlarını seçmekte zorlanıyor.

Bu bölüm, Flutter'ın yerel bilgisayarınıza kurulumunda ayrıntılı olarak size rehberlik edecektir.

Windows'ta Kurulum

Bu bölümde, Flutter SDK'nın nasıl kurulacağını ve bir Windows sisteminde gerekliliğini görelim .

Step 1 - URL'ye gidin,https://flutter.dev/docs/get-started/install/windowsve en son Flutter SDK'yı indirin. Nisan 2019 itibarıyla sürüm 1.2.1 ve dosya flutter_windows_v1.2.1-stable.zip.

Step 2 - Zip arşivini bir klasörde açın, C: \ flutter \ deyin

Step 3 - Flutter bin dizinini içerecek şekilde sistem yolunu güncelleyin.

Step 4 - Flutter, flutter gelişiminin tüm gereksinimlerinin karşılandığını kontrol etmek için flutter doktoru bir araç sağlar.

flutter doctor

Step 5 - Yukarıdaki komutu çalıştırmak sistemi analiz edecek ve raporunu aşağıda gösterildiği gibi gösterecektir -

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.2.1, on Microsoft Windows [Version
10.0.17134.706], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version
28.0.3)
[√] Android Studio (version 3.2)
[√] VS Code, 64-bit edition (version 1.29.1)
[!] Connected device
! No devices available
! Doctor found issues in 1 category.

Rapor, tüm geliştirme araçlarının mevcut olduğunu ancak cihazın bağlı olmadığını söylüyor. USB üzerinden bir android cihaz bağlayarak veya bir android emülatör başlatarak bunu düzeltebiliriz.

Step 6 - Flutter doktoru tarafından bildirilmişse, en son Android SDK'yı yükleyin

Step 7 - Flutter doktoru tarafından bildirilmişse, en son Android Studio'yu yükleyin

Step 8 - Bir android emülatörü başlatın veya gerçek bir android cihazı sisteme bağlayın.

Step 9- Android Studio için Flutter ve Dart eklentisini yükleyin. Yeni Flutter uygulaması oluşturmak için başlangıç ​​şablonu, Android stüdyosunun kendisinde Flutter uygulamasını çalıştırma ve hata ayıklama seçeneği vb. Sağlar.

  • Android Studio'yu açın.

  • Dosya → Ayarlar → Eklentiler'i tıklayın.

  • Flutter eklentisini seçin ve Yükle'ye tıklayın.

  • Dart eklentisini yüklemeniz istendiğinde Evet'i tıklayın.

  • Android stüdyosunu yeniden başlatın.

MacOS'ta Kurulum

Flutter'ı MacOS'a yüklemek için aşağıdaki adımları izlemeniz gerekecek -

Step 1 - URL'ye gidin,https://flutter.dev/docs/get-started/install/macosve en son Flutter SDK'yı indirin. Nisan 2019 itibarıyla sürüm 1.2.1 ve dosya flutter_macos_v1.2.1- stable.zip'tir.

Step 2 - Zip arşivini bir klasörde açın, / yol / / flutter deyin

Step 3 - Sistem yolunu flutter bin dizinini içerecek şekilde güncelleyin (~ / .bashrc dosyasında).

> export PATH = "$PATH:/path/to/flutter/bin"

Step 4 - Aşağıdaki komutu kullanarak mevcut oturumda güncellenmiş yolu etkinleştirin ve sonra da doğrulayın.

source ~/.bashrc
source $HOME/.bash_profile
echo $PATH

Flutter, flutter geliştirmenin tüm gereksinimlerinin karşılandığını kontrol etmek için flutter doktoru bir araç sağlar. Windows muadiline benzer.

Step 5 - Flutter doktoru tarafından bildirildiyse en son XCode'u yükleyin

Step 6 - Flutter doktoru tarafından bildirilmişse, en son Android SDK'yı yükleyin

Step 7 - Flutter doktoru tarafından bildirilmişse, en son Android Studio'yu yükleyin

Step 8 - Android uygulamasını geliştirmek için bir android emülatörü başlatın veya sisteme gerçek bir android cihazı bağlayın.

Step 9 - iOS uygulamasını geliştirmek için iOS simülatörünü açın veya gerçek bir iPhone cihazını sisteme bağlayın.

Step 10- Android Studio için Flutter ve Dart eklentisini yükleyin. Yeni bir Flutter uygulaması oluşturmak için başlangıç ​​şablonu, Android stüdyosunun kendisinde Flutter uygulamasını çalıştırma ve hata ayıklama seçeneği vb. Sağlar.

  • Android Studio'yu açın

  • Tıklayın Preferences → Plugins

  • Flutter eklentisini seçin ve Yükle'ye tıklayın

  • Dart eklentisini yüklemeniz istendiğinde Evet'i tıklayın.

  • Android stüdyosunu yeniden başlatın.

Bu bölümde, Android Studio'da bir flutter uygulaması oluşturmanın temellerini anlamak için basit bir Flutter uygulaması oluşturalım.

Step 1 - Android Studio'yu açın

Step 2- Flutter Projesi oluşturun. Bunun için tıklayınFile → New → New Flutter Project

Step 3- Flutter Uygulamasını seçin. Bunun için seçinFlutter Application ve tıklayın Next.

Step 4 - Uygulamayı aşağıdaki gibi yapılandırın ve tıklayın Next.

  • Proje Adı: hello_app

  • Flutter SDK Yolu: <path_to_flutter_sdk>

  • Proje yeri: <path_to_project_folder>

  • Açıklama: Flutter based hello world application

Step 5 - Projeyi Yapılandırın.

Şirket etki alanını şu şekilde ayarlayın: flutterapp.tutorialspoint.com ve tıklayın Finish.

Step 6 - Şirket alan adını girin.

Android Studio, minimum işlevsellikle tam olarak çalışan bir flutter uygulaması oluşturur. Uygulamanın yapısını kontrol edelim ve ardından görevimizi yapmak için kodu değiştirelim.

Uygulamanın yapısı ve amacı aşağıdaki gibidir -

Uygulamanın yapısının çeşitli bileşenleri burada açıklanmıştır -

  • android - Android uygulaması oluşturmak için otomatik oluşturulan kaynak kodu

  • ios - ios uygulaması oluşturmak için otomatik olarak oluşturulan kaynak kodu

  • lib - Flutter çerçevesi kullanılarak yazılmış Dart kodunu içeren ana klasör

  • ib/main.dart - Flutter uygulamasının giriş noktası

  • test - Flutter uygulamasını test etmek için Dart kodunu içeren klasör

  • test/widget_test.dart - Örnek kod

  • .gitignore - Git sürüm kontrol dosyası

  • .metadata - flutter araçları tarafından otomatik olarak oluşturulur

  • .packages - flutter paketlerini izlemek için otomatik olarak oluşturuldu

  • .iml - Android stüdyosu tarafından kullanılan proje dosyası

  • pubspec.yaml - Kullanan Pub, Flutter paket yöneticisi

  • pubspec.lock - Flutter paket yöneticisi tarafından otomatik oluşturuldu, Pub

  • README.md - Markdown formatında yazılmış proje açıklama dosyası

Step 7- lib / main.dart dosyasındaki dart kodunu aşağıdaki kodla değiştirin -

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: 'Hello World Demo Application',
         theme: ThemeData(
            primarySwatch: Colors.blue,
         ),
         home: MyHomePage(title: 'Home page'),
      );
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key);
   final String title;

   @override
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.title),
         ),
         body: Center(
            child:
            Text(
               'Hello World',
            )
         ),
      );
   }
}

Dart kodunu satır satır anlayalım.

  • Line 1- flutter paketini, malzemeyi içe aktarır . Materyal, Android tarafından belirtilen Materyal tasarım yönergelerine göre kullanıcı arayüzü oluşturmak için bir flutter paketidir.

  • Line 3- Bu, Flutter uygulamasının giriş noktasıdır. Aramalar UygulamaÇalıştır fonksiyonu ve bu bir nesne geçmek BenimUygulamam sınıfı. RunApp işlevinin amacı , verilen pencere öğesini ekrana eklemektir.

  • Line 5-17- Widget, flutter çerçevesinde UI oluşturmak için kullanılır. StatelessWidget , pencere aracının herhangi bir durumunu korumayan bir pencere öğesidir. MyApp , StatelessWidget'ı genişletir ve derleme yöntemini geçersiz kılar . Derleme yönteminin amacı , uygulamanın kullanıcı arayüzünün bir bölümünü oluşturmaktır. Burada, derleme yöntemi , uygulamanın kök düzeyi kullanıcı arabirimini oluşturmak için bir pencere öğesi olan MaterialApp'ı kullanır . Üç özelliği vardır - başlık, tema ve ana sayfa .

    • başlık , başvurunun başlığıdır

    • tema , widget'ın temasıdır. Burada, set mavi kullanarak uygulama genel renk olarak ThemeData sınıfını ve onun özelliğini, primarySwatch .

    • home, başka bir widget ayarladığımız uygulamanın iç kullanıcı arayüzüdür, MyHomePage

  • Line 19 - 38- MyHomePage , Scaffold Widget'ı döndürmesi dışında MyApp ile aynıdır . Scaffold , UI uyumlu malzeme tasarımı oluşturmak için kullanılan MaterialApp widget'ının yanındaki üst düzey bir widget'tır . İki önemli özelliği vardır, uygulamanın başlığını göstermek için appBar ve uygulamanın gerçek içeriğini göstermek için gövde. AppBar , uygulamanın başlığını oluşturmak için başka bir widgettır ve bunu appBar özelliğinde kullandık. In vücut özelliği, biz kullandık Merkezini o alt widget merkezleri, hangi widget. Metin , metni göstermek için en son ve en içteki widget'tır ve ekranın ortasında görüntülenir.

Step 8 - Şimdi, uygulamayı kullanarak çalıştırın, Run → Run main.dart

Step 9 - Son olarak, uygulamanın çıktısı aşağıdaki gibidir -

Bu bölümde, Flutter çerçevesinin mimarisini tartışalım.

Widget'lar

Flutter çerçevesinin temel konsepti In Flutter, Everything is a widget. Widget'lar temelde uygulamanın kullanıcı arayüzünü oluşturmak için kullanılan kullanıcı arayüzü bileşenleridir.

Gelen Fluter , uygulamanın kendisi bir widgettır. Uygulama, en üst düzey widget'tır ve kullanıcı arayüzü, yine alt widget'ları kullanarak oluşturulan bir veya daha fazla alt öğe (widget) kullanılarak oluşturulur. Bucomposability özelliği, herhangi bir karmaşıklıkta bir kullanıcı arabirimi oluşturmamıza yardımcı olur.

Örneğin, merhaba dünya uygulamasının (önceki bölümde oluşturulmuş) widget hiyerarşisi aşağıdaki şemada belirtildiği gibidir -

Burada aşağıdaki noktalar dikkate değerdir -

  • MyApp , kullanıcı tarafından oluşturulan pencere aracıdır ve Flutter yerel pencere öğesi MaterialApp kullanılarak oluşturulur .

  • MaterialApp , yine kullanıcı tarafından oluşturulan bir pencere öğesi olan MyHomePage olan giriş sayfasının kullanıcı arayüzünü belirtmek için bir giriş özelliğine sahiptir .

  • MyHomePage , başka bir flutter yerel pencere öğesi olan Scaffold kullanılarak oluşturulmuştur

  • İskele - iki özelliği vardır bedeni ve appbar

  • body , ana kullanıcı arayüzünü belirtmek için kullanılır ve appBar , başlık kullanıcı arayüzünü belirtmek için kullanılır

  • Header UI , flutter native widget kullanılarak oluşturulur, AppBar ve Body UI , Center widget kullanılarak oluşturulur .

  • Merkezi bir özellik vardır Widget Çocuk asıl içeriği eder ve onu kullanarak inşa olduğunu, Metin aracını

Mimik

Flutter widget'ları, özel bir widget olan GestureDetector aracılığıyla etkileşimi destekler . GestureDetector , alt widget'ına dokunma, sürükleme vb. Gibi kullanıcı etkileşimlerini yakalayabilen görünmez bir widgettır. Flutter'ın birçok yerel widget'ı, GestureDetector'ın kullanımıyla etkileşimi destekler . GestureDetector widget'ı ile oluşturarak, etkileşimli özelliği mevcut pencere aracına dahil edebiliriz . Önümüzdeki bölümlerde jestleri ayrı ayrı öğreneceğiz.

Devlet Kavramı

Flutter widget'leri , StatefulWidget adlı özel bir widget sağlayarak Durum bakımını destekler . Araç elde edilmesi gerekmektedir StatefulWidget eklendi destek durumu bakım ve diğer tüm eklendi elde edilmelidir için StatefulWidget . Flutter widget'larıreactiveyerli olarak. Bu, reactjs'ye benzer ve StatefulWidget , dahili durumu her değiştiğinde otomatik olarak yeniden oluşturulur. Yeniden oluşturma, eski ve yeni pencere öğesi kullanıcı arabirimi arasındaki farkı bularak ve yalnızca gerekli değişiklikleri oluşturarak optimize edilir

Katmanlar

Flutter çerçevesinin en önemli kavramı, çerçevenin karmaşıklık açısından birden çok kategoriye ayrılması ve azalan karmaşıklık katmanlarında açıkça düzenlenmiş olmasıdır. Bir katman, hemen sonraki seviye katmanı kullanılarak oluşturulur. En üstteki katman, Android ve iOS'a özel widget'tır . Bir sonraki katman, tüm dalgalanma yerel widget'larına sahiptir. Sonraki katman, düşük seviyeli oluşturucu bileşeni olan ve flutter uygulamasında her şeyi oluşturan Rendering katmanıdır . Katmanlar temel platforma özgü kodlara iner

Flutter'daki bir katmanın genel görünümü aşağıdaki diyagramda belirtilmiştir -

Aşağıdaki noktalar Flutter'ın mimarisini özetlemektedir:

  • Flutter'da her şey bir widget'tır ve karmaşık bir widget, zaten var olan widget'lardan oluşur.

  • Etkileşimli özellikler, gerektiğinde GestureDetector widget'ı kullanılarak dahil edilebilir .

  • Bir parçacığın durumu, gerekli olduğunda StatefulWidget parçacığı kullanılarak korunabilir .

  • Flutter, görevin karmaşıklığına bağlı olarak herhangi bir katmanın programlanabilmesi için katmanlı tasarım sunar.

Tüm bu kavramları ilerleyen bölümlerde detaylı olarak tartışacağız.

Dart, açık kaynaklı bir genel amaçlı programlama dilidir. Başlangıçta Google tarafından geliştirilmiştir. Dart, C tarzı sözdizimine sahip nesne yönelimli bir dildir. Arayüzler, sınıflar gibi programlama konseptlerini destekler, diğer programlama dillerinin aksine Dart dizileri desteklemez. Dart koleksiyonları, diziler, jenerikler ve isteğe bağlı tipleme gibi veri yapılarını kopyalamak için kullanılabilir.

Aşağıdaki kod basit bir Dart programını gösterir -

void main() {
   print("Dart language is easy to learn");
}

Değişkenler ve Veri türleri

Değişken , depolama konumu olarak adlandırılır ve Veri türleri, basitçe değişkenler ve işlevlerle ilişkili verilerin türünü ve boyutunu ifade eder.

Dart , değişkeni bildirmek için var anahtar sözcüğünü kullanır . Sözdizimi var , aşağıda tanımlandığı gibidir

var name = 'Dart';

Nihai ve const anahtar kelime beyan sabitleri için kullanılır. Aşağıdaki gibi tanımlanırlar -

void main() {
   final a = 12;
   const pi = 3.14;
   print(a);
   print(pi);
}

Dart dili aşağıdaki veri türlerini destekler -

  • Numbers - Sayısal değişmezleri temsil etmek için kullanılır - Tamsayı ve Çift.

  • Strings- Bir dizi karakteri temsil eder. Dize değerleri tek veya çift tırnak içinde belirtilir.

  • Booleans- Dart, Boole değerlerini (true ve false) temsil etmek için bool anahtar sözcüğünü kullanır .

  • Lists and Maps- Nesnelerin bir koleksiyonunu temsil etmek için kullanılır. Basit bir Liste aşağıdaki gibi tanımlanabilir -.

void main() {
   var list = [1,2,3,4,5];
   print(list);
}

Yukarıda gösterilen liste [1,2,3,4,5] listesi oluşturur.

Harita burada gösterildiği gibi tanımlanabilir -

void main() {
   var mapping = {'id': 1,'name':'Dart'};
   print(mapping);
}
  • Dynamic- Değişken türü tanımlanmamışsa, varsayılan türü dinamiktir. Aşağıdaki örnek, dinamik tür değişkenini göstermektedir -

void main() {
   dynamic name = "Dart";
   print(name);
}

Karar Verme ve Döngüler

Bir karar verme bloğu, talimatlar yürütülmeden önce bir koşulu değerlendirir. Dart; If, If..else ve switch ifadelerini destekler.

Döngüler, belirli bir koşul karşılanana kadar bir kod bloğunu tekrarlamak için kullanılır. Dart, for..in, while ve do.. while döngülerini destekler.

Kontrol ifadelerinin ve döngülerin kullanımı hakkında basit bir örnek anlayalım -

void main() {
   for( var i = 1 ; i <= 10; i++ ) {
      if(i%2==0) {
         print(i);
      }
   }
}

Yukarıdaki kod, 1'den 10'a kadar olan çift sayıları yazdırır.

Fonksiyonlar

Bir işlev, birlikte belirli bir görevi yerine getiren bir grup deyimdir. Burada gösterildiği gibi Dart'ta basit bir işleve bakalım -

void main() {
   add(3,4);
}
void add(int a,int b) {
   int c;
   c = a+b;
   print(c);
}

Yukarıdaki işlev iki değer ekler ve çıktı olarak 7 üretir.

Nesne yönelimli programlama

Dart, nesne yönelimli bir dildir. Sınıflar, arayüzler vb. Gibi nesne yönelimli programlama özelliklerini destekler.

Sınıf, nesneler oluşturmak için bir plandır. Bir sınıf tanımı aşağıdakileri içerir -

  • Fields
  • Getiriciler ve ayarlayıcılar
  • Constructors
  • Functions

Şimdi, yukarıdaki tanımları kullanarak basit bir sınıf oluşturalım -

class Employee {
   String name;
   
   //getter method
   String get emp_name {
      return name;
   }
   //setter method
   void set emp_name(String name) {
      this.name = name;
   }
   //function definition
   void result() {
      print(name);
   }
}
void main() {
   //object creation
   Employee emp = new Employee();
   emp.name = "employee1";
   emp.result(); //function call
}

Önceki bölümde öğrendiğimiz gibi, widget'lar Flutter çerçevesindeki her şeydir. Önceki bölümlerde yeni pencere öğelerinin nasıl oluşturulacağını zaten öğrendik.

Bu bölümde, Flutter çerçevesinde bulunan widget'ları ve farklı tipteki widget'ları oluşturmanın arkasındaki gerçek kavramı anlayalım .

Bize kontrol edelim Merhaba Dünya uygulamanın MyHomePage widget'ı. Bu amaç için kod aşağıda verilmiştir -

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   
   final String title; 
   @override 
   Widget build(BuildContext context) {
      return Scaffold( 
         appBar: AppBar(title: Text(this.title), ), 
         body: Center(child: Text( 'Hello World',)),
      );
   }
}

Burada StatelessWidget'ı genişleterek yeni bir widget oluşturduk .

StatelessWidget'in yalnızca türetilmiş sınıfında uygulanacak tek bir yöntem derlemesini gerektirdiğini unutmayın . İnşa yöntemi üzerinden pencere öğeleri oluşturmak için gerekli içerik çevre alır BuildContext parametresi ve inşa eklendi döndürür.

Kodda, yapıcı argümanlarından biri olarak title kullandık ve ayrıca başka bir argüman olarak Key'i kullandık . Başlık başlık görüntülemek için kullanılır ve Anahtar yapı ortamında widget'ı tanımlamak için kullanılır.

Burada inşa yöntemini çağırır inşa yöntemini Scaffold sırayla çağırır inşa yöntemi AppBar ve Merkezi'ne için inşa kendi kullanıcı arayüzünü.

Son olarak, Merkez oluşturma yöntemi Metin oluşturma yöntemini çağırır .

Daha iyi bir anlayış için, aynı görsel temsili aşağıda verilmiştir -

Widget Derleme Görselleştirme

In Flutter aşağıda listelendiği gibi, widget'lar, onların özelliklerine göre birden kategoriler halinde toplanabilir -

  • Platforma özel widget'lar
  • Düzen widget'ları
  • Durum bakım widget'ları
  • Platformdan bağımsız / temel araçlar

Şimdi her birini ayrıntılı olarak tartışalım.

Platforma özel widget'lar

Flutter, belirli bir platforma (Android veya iOS) özgü widget'lara sahiptir.

Android'e özgü widget'lar, Android OS'nin Materyal tasarımı kılavuzuna uygun olarak tasarlanmıştır . Android'e özgü widget'lara Malzeme widget'ları denir .

iOS'a özgü pencere öğeleri, Apple tarafından İnsan Arabirimi Yönergelerine uygun olarak tasarlanmıştır ve bunlar Cupertino widget'ları olarak adlandırılır .

En çok kullanılan malzeme gereçlerinden bazıları aşağıdaki gibidir -

  • Scaffold
  • AppBar
  • BottomNavigationBar
  • TabBar
  • TabBarView
  • ListTile
  • RaisedButton
  • FloatingActionButton
  • FlatButton
  • IconButton
  • DropdownButton
  • PopupMenuButton
  • ButtonBar
  • TextField
  • Checkbox
  • Radio
  • Switch
  • Slider
  • Tarih ve Saat Seçiciler
  • SimpleDialog
  • AlertDialog

En çok kullanılan Cupertino widget'larından bazıları aşağıdaki gibidir -

  • CupertinoButton
  • CupertinoPicker
  • CupertinoDatePicker
  • CupertinoTimerPicker
  • CupertinoNavigationBar
  • CupertinoTabBar
  • CupertinoTabScaffold
  • CupertinoTabView
  • CupertinoTextField
  • CupertinoDialog
  • CupertinoDialogAction
  • CupertinoFullscreenDialogTransition
  • CupertinoPageScaffold
  • CupertinoPageTransition
  • CupertinoActionSheet
  • CupertinoActivityIndicator
  • CupertinoAlertDialog
  • CupertinoPopupSurface
  • CupertinoSlider

Düzen widget'ları

Flutter'da, bir veya daha fazla widget oluşturularak bir widget oluşturulabilir. Birden çok parçacığı tek bir parçacığa oluşturmak için Flutter , yerleşim özelliğine sahip çok sayıda parçacık sağlar. Örneğin, alt pencere öğesi Merkez pencere öğesi kullanılarak ortalanabilir .

Popüler düzen widget'larından bazıları aşağıdaki gibidir -

  • Container- Arka plan, kenarlık ve gölge içeren BoxDecoration widget'ları kullanılarak dekore edilmiş dikdörtgen bir kutu .

  • Center - Alt widget'ını ortalayın.

  • Row - Çocuklarını yatay yönde düzenleyin.

  • Column - Çocuklarını dikey yönde düzenleyin.

  • Stack - Birini üst üste düzenleyin.

Düzen widget'larını ilerideki düzen widget'larına giriş bölümünde ayrıntılı olarak kontrol edeceğiz .

Durum bakım widget'ları

Flutter'da, tüm widget'lar StatelessWidget veya StatefulWidget'ten türetilir .

Araç türetilen StatelessWidget bir devlet bilgiye sahip değildir ancak eklendi elde içerebilir StatefulWidget . Uygulamanın dinamik doğası, widget'ların etkileşimli davranışı ve etkileşim sırasında durum değişiklikleri yoluyladır. Örneğin, bir sayaç düğmesine dokunmak sayacın dahili durumunu bir artıracak / azaltacaktır ve Flutter widget'ının reaktif yapısı, yeni durum bilgisini kullanarak widget'ı otomatik olarak yeniden oluşturacaktır.

StatefulWidget widget'ları kavramını ilerideki Durum yönetimi bölümünde ayrıntılı olarak öğreneceğiz .

Platformdan bağımsız / temel araçlar

Flutter , platformdan bağımsız bir şekilde basit ve karmaşık kullanıcı arabirimi oluşturmak için çok sayıda temel widget sağlar. Bu bölümdeki bazı temel araçları görelim.

Text

Metin widget'ı, bir dizi dizeyi görüntülemek için kullanılır. Dizenin stili, style özelliği ve TextStyle sınıfı kullanılarak ayarlanabilir . Bu amaç için örnek kod aşağıdaki gibidir -

Text('Hello World!', style: TextStyle(fontWeight: FontWeight.bold))

Metin widget'ı, dizeyi farklı stilde belirtmek için TextSpan türündeki alt öğeyi kabul eden Text.rich adlı özel bir yapıcıya sahiptir. TextSpan doğada özyinelemeli olduğunu ve kabul Widget TextSpan onun çocukları olarak. Bu amaç için örnek kod aşağıdaki gibidir -

Text.rich( 
   TextSpan( 
      children: <TextSpan>[ 
         TextSpan(text: "Hello ", style:  
         TextStyle(fontStyle: FontStyle.italic)),  
         TextSpan(text: "World", style: 
         TextStyle(fontWeight: FontWeight.bold)),  
      ], 
   ), 
)

Metin widget'ının en önemli özellikleri aşağıdaki gibidir -

  • maxLines, int - Gösterilecek maksimum satır sayısı

  • overflow, TextOverFlow- TextOverFlow sınıfı kullanılarak görsel taşmanın nasıl işleneceğini belirtin

  • style, TextStyle- TextStyle sınıfını kullanarak dizenin stilini belirtin

  • textAlign, TextAlign- TextAlign sınıfını kullanarak metnin sağa, sola, yasla, vb. Gibi hizalanması

  • textDirection, TextDirection - Soldan sağa veya sağdan sola akacak metnin yönü

Image

Resim widget'ı, uygulamada bir resmi görüntülemek için kullanılır. Görüntü gereci, görüntüleri birden çok kaynaktan yüklemek için farklı yapıcılar sağlar ve bunlar aşağıdaki gibidir -

  • Image- ImageProvider kullanan genel resim yükleyici

  • Image.asset - Flutter projesinin varlıklarından görüntü yükleyin

  • Image.file - Sistem klasöründen görüntü yükleyin

  • Image.memory - Bellekten görüntü yükle

  • Image.Network - Ağdan resim yükle

Flutter'da bir görüntüyü yüklemek ve görüntülemek için en kolay seçenek , görüntüyü uygulamanın varlıkları olarak eklemek ve isteğe bağlı olarak widget'a yüklemektir.

  • Proje klasöründe bir klasör, varlıklar oluşturun ve gerekli görüntüleri yerleştirin.

  • Pubspec.yaml'deki varlıkları aşağıda gösterildiği gibi belirtin -

flutter: 
   assets: 
      - assets/smiley.png
  • Şimdi, resmi uygulamaya yükleyin ve görüntüleyin.

Image.asset('assets/smiley.png')
  • Merhaba dünya uygulamasının MyHomePage widget'ının tam kaynak kodu ve sonucu aşağıda gösterildiği gibidir -.

class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 

   @override 
   Widget build(BuildContext context) {
      return Scaffold( 
         appBar: AppBar( title: Text(this.title), ), 
         body: Center( child: Image.asset("assets/smiley.png")),
      ); 
   }
}

Yüklenen görüntü aşağıda gösterildiği gibidir -

Görüntü widget'ının en önemli özellikleri aşağıdaki gibidir -

  • image, ImageProvider - Yüklenecek gerçek görüntü

  • width, double - Görüntünün genişliği

  • height, double - Görüntünün yüksekliği

  • alignment, AlignmentGeometry - Görüntü sınırları içinde nasıl hizalanır

Icon

Simge widget'ı, IconData sınıfında açıklanan bir fonttan bir glifi görüntülemek için kullanılır . Basit bir e-posta simgesi yükleme kodu aşağıdaki gibidir -

Icon(Icons.email)

Merhaba dünya uygulamasında uygulamak için tam kaynak kodu aşağıdaki gibidir -

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 

   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(this.title),),
         body: Center( child: Icon(Icons.email)),
      );
   }
}

Yüklü simge aşağıda gösterildiği gibidir -

Temel kavramı bu yana Fluter olan şey olduğu eklendi , flutter aletler kendisi bir kullanıcı arayüzü düzeni işlevselliğini içerir. Flutter , yalnızca kullanıcı arayüzünü yerleştirmek amacıyla oldukça fazla sayıda Konteyner, Merkez, Hizalama vb. Gibi özel olarak tasarlanmış widget'lar sağlar. Diğer pencere öğelerini oluşturarak oluşturulan pencere öğeleri, normalde düzen pencere öğelerini kullanır. Bu bölümde Flutter düzen konseptini öğrenelim .

Düzen Widget'larının Türü

Düzen widget'ları, alt kategorisine göre iki farklı kategoriye ayrılabilir -

  • Tek bir çocuğu destekleyen widget
  • Birden çok çocuğu destekleyen widget

Gelecek bölümlerde hem widget türlerini hem de işlevselliğini öğrenelim.

Tek Çocuk Widget'ları

Bu kategoride, widget'ların alt öğesi olarak yalnızca bir widget'ı olacak ve her widget'ın özel bir düzen işlevi olacaktır.

Örneğin, Merkez widget'ı , alt widget'ı ana widget'ına göre ortalar ve Konteyner widget'ı, dolgu, dekorasyon vb. Gibi farklı seçenekler kullanarak alt widget'ı içindeki herhangi bir yere yerleştirmek için tam esneklik sağlar.

Tek çocuk widget'lar, düğme, etiket vb. Gibi tek işlevlere sahip yüksek kaliteli widget oluşturmak için harika seçeneklerdir.

Kapsayıcı widget'ını kullanarak basit bir düğme oluşturma kodu aşağıdaki gibidir -

class MyButton extends StatelessWidget {
   MyButton({Key key}) : super(key: key); 

   @override 
   Widget build(BuildContext context) {
      return Container(
         decoration: const BoxDecoration(
            border: Border(
               top: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)),
               left: BorderSide(width: 1.0, color: Color(0xFFFFFFFFFF)),
               right: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
               bottom: BorderSide(width: 1.0, color: Color(0xFFFF000000)),
            ),
         ),
         child: Container(
            padding: const
            EdgeInsets.symmetric(horizontal: 20.0, vertical: 2.0),
            decoration: const BoxDecoration(
               border: Border(
                  top: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)),
                  left: BorderSide(width: 1.0, color: Color(0xFFFFDFDFDF)),
                  right: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
                  bottom: BorderSide(width: 1.0, color: Color(0xFFFF7F7F7F)),
               ),
               color: Colors.grey,
            ),
            child: const Text(
               'OK',textAlign: TextAlign.center, style: TextStyle(color: Colors.black)
            ), 
         ), 
      ); 
   }
}

Burada iki widget kullandık - bir Kapsayıcı widget'ı ve bir Metin widget'ı. Widget'ın sonucu, aşağıda gösterildiği gibi özel bir düğmedir -

Flutter tarafından sağlanan en önemli tek çocuk düzen widget'larından bazılarını kontrol edelim -

  • Padding- Alt widget'ını verilen dolguya göre düzenlemek için kullanılır. Burada, padding EdgeInsets sınıfı tarafından sağlanabilir .

  • Align- alignment özelliğinin değerini kullanarak alt widget'ını kendi içinde hizalayın . Hizalama özelliği değeri, FractionalOffset sınıfı tarafından sağlanabilir . FractionalOffset sınıfı sol üstten bir mesafe açısından uzaklıklar belirtir.

Olası ofset değerlerinden bazıları aşağıdaki gibidir -

  • FractionalOffset (1.0, 0.0) sağ üst köşeyi temsil eder.

  • FractionalOffset (0.0, 1.0) sol alt kısmı temsil eder.

Kaydırmalarla ilgili örnek bir kod aşağıda gösterilmiştir -

Center(
   child: Container(
      height: 100.0, 
      width: 100.0, 
      color: Colors.yellow, child: Align(
         alignment: FractionalOffset(0.2, 0.6),
         child: Container( height: 40.0, width:
            40.0, color: Colors.red,
         ), 
      ), 
   ), 
)
  • FittedBox - Alt parçacığı ölçeklendirir ve ardından onu belirtilen sığmaya göre konumlandırır.

  • AspectRatio - Alt widget'ı belirtilen en boy oranına göre boyutlandırmaya çalışır

  • ConstrainedBox

  • Baseline

  • FractinallySizedBox

  • IntrinsicHeight

  • IntrinsicWidth

  • LiimitedBox

  • OffStage

  • OverflowBox

  • SizedBox

  • SizedOverflowBox

  • Transform

  • CustomSingleChildLayout

Merhaba dünya uygulamamız, ana sayfayı tasarlamak için malzeme tabanlı düzen widget'ları kullanıyor. Merhaba dünya uygulamamızı, aşağıda belirtildiği gibi temel düzen widget'larını kullanarak ana sayfayı oluşturacak şekilde değiştirelim -

  • Container - Zengin stil özellikleriyle birlikte hizalama, dolgu, kenarlık ve kenar boşluğuna sahip genel, tek çocuk, kutu tabanlı kap widget'ı.

  • Center - Alt widget'ını merkezleyen basit, Tek çocuk konteyner widget'ı.

MyHomePage ve MyApp widget'ının değiştirilmiş kodu aşağıdaki gibidir -

class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
      return MyHomePage(title: "Hello World demo app");
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key);
   final String title;
   @override
   Widget build(BuildContext context) {
      return Container(
         decoration: BoxDecoration(color: Colors.white,),
         padding: EdgeInsets.all(25), child: Center(
            child:Text(
               'Hello World', style: TextStyle(
                  color: Colors.black, letterSpacing: 0.5, fontSize: 20,
               ),
               textDirection: TextDirection.ltr,
            ),
         )
      );
   }
}

Buraya,

  • Kapsayıcı pencere öğesi, en üst düzey veya kök pencere öğesidir. Kapsayıcı , içeriğini düzenlemek için dekorasyon ve dolgu özelliği kullanılarak yapılandırılır .

  • BoxDecoration , Konteyner widget'ını süslemek için renk, kenarlık vb. Gibi birçok özelliğe sahiptir ve burada, konteynerin rengini ayarlamak için renk kullanılır.

  • dolgusu ait Container kullanılarak ayarlanır Widget dgeInsets dolgu değerini belirtmek için seçenek sunar sınıfı.

  • Merkez , Kapsayıcı widget'ının alt widget'idir. Yine, Metin , Merkez widget'ının alt öğesidir. Metin mesajı göstermek için kullanılır ve Merkezi ebeveyn widget'ı, göre kısa mesajı ortalamak için kullanılır Konteyner .

Yukarıda verilen kodun nihai sonucu, aşağıda gösterildiği gibi bir düzen örneğidir -

Birden Çok Alt Pencere Öğesi

Bu kategoride, belirli bir widget birden fazla alt widget'a sahip olacaktır ve her bir widget'ın düzeni benzersizdir.

Örneğin, Satır küçük aracı alt öğelerinin yatay yönde yerleştirilmesine izin verirken, Sütun küçük aracı alt öğelerinin dikey yönde yerleştirilmesine izin verir. Satır ve Sütun oluşturularak , herhangi bir karmaşıklık düzeyine sahip widget oluşturulabilir .

Bu bölümde sık kullanılan bazı widget'ları öğrenelim.

  • Row - Çocuklarını yatay bir şekilde düzenlemesine izin verir.

  • Column - Çocuklarının dikey olarak düzenlenmesine izin verir.

  • ListView - Çocuklarını liste halinde düzenlemeye izin verir.

  • GridView - Çocuklarını galeri olarak düzenlemeye izin verir.

  • Expanded - Satır ve Sütun widget'ının alt öğelerinin mümkün olan maksimum alanı kaplamasını sağlamak için kullanılır.

  • Table - Tablo tabanlı widget.

  • Flow - Akış tabanlı widget.

  • Stack - Yığın tabanlı widget.

Gelişmiş Düzen Uygulaması

Bu bölümde, hem tekli hem de çoklu alt düzen widget'larını kullanarak özel tasarımlı ürün listelemenin karmaşık bir kullanıcı arayüzünün nasıl oluşturulacağını öğrenelim .

Bu amaçla, aşağıda verilen sırayı izleyin -

  • Android Studio, product_layout_app'de yeni bir Flutter uygulaması oluşturun .

  • Değiştir main.dart kodunu folowing ile kod -

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,), 
         home: MyHomePage(title: 'Product layout demo home page'),
      ); 
   } 
} 
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
      
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(this.title),), 
         body: Center(child: Text( 'Hello World', )), 
      ); 
   }
}
  • Here,

  • MyHomePage widget'ını , varsayılan StatefulWidget yerine StatelessWidget'i genişleterek oluşturduk ve ardından ilgili kodu kaldırdık.

  • Şimdi, aşağıda gösterildiği gibi belirtilen tasarıma göre ProductBox adlı yeni bir widget oluşturun -

  • ProductBox'ın kodu aşağıdaki gibidir.

class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.name, this.description, this.price, this.image}) 
      : super(key: key); 
   final String name; 
   final String description; 
   final int price; 
   final String image; 

   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), height: 120,  child: Card( 
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: <Widget>[
                  Image.asset("assets/appimages/" +image), Expanded(
                     child: Container(
                        padding: EdgeInsets.all(5), child: Column(
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                              children: <Widget>[ 
                              
                              Text(this.name, style: TextStyle(fontWeight: 
                                 FontWeight.bold)), Text(this.description), 
                              Text("Price: " + this.price.toString()), 
                           ], 
                        )
                     )
                  )
               ]
            )
         )
      );
   }
}
  • Lütfen kodda aşağıdakilere dikkat edin -

  • ProductBox , aşağıda belirtildiği gibi dört bağımsız değişken kullandı -

    • isim - Ürün adı

    • description - Ürün açıklaması

    • fiyat - Ürünün fiyatı

    • resim - Ürün resmi

  • ProductBox , aşağıda belirtildiği gibi yedi yerleşik widget kullanır -

    • Container
    • Expanded
    • Row
    • Column
    • Card
    • Text
    • Image
  • ProductBox , yukarıda belirtilen pencere öğesi kullanılarak tasarlanmıştır. Widget'ın düzeni veya hiyerarşisi aşağıda gösterilen şemada belirtilmiştir -

  • Şimdi, uygulamanın varlıklar klasörüne ürün bilgileri için bir miktar sahte görüntü yerleştirin (aşağıya bakın) ve pubspec.yaml dosyasındaki varlıklar klasörünü aşağıda gösterildiği gibi yapılandırın -

assets: 
   - assets/appimages/floppy.png 
   - assets/appimages/iphone.png 
   - assets/appimages/laptop.png 
   - assets/appimages/pendrive.png 
   - assets/appimages/pixel.png 
   - assets/appimages/tablet.png

iPhone.png

Pixel.png

Laptop.png

Tablet.png

Pendrive.png

Floppy.png

Son olarak, MyHomePage widget'ındaki ProductBox widget'ını aşağıda belirtildiği gibi kullanın -

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 

   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title:Text("Product Listing")), 
         body: ListView(
            shrinkWrap: true, padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), 
            children: <Widget> [
               ProductBox(
                  name: "iPhone", 
                  description: "iPhone is the stylist phone ever", 
                  price: 1000, 
                  image: "iphone.png"
               ), 
               ProductBox(
                  name: "Pixel", 
                  description: "Pixel is the most featureful phone ever", 
                  price: 800, 
                  image: "pixel.png"
               ), 
               ProductBox( 
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox( 
                  name: "Tablet", 
                  description: "Tablet is the most useful device ever for meeting", 
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox(
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ), 
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ), 
            ],
         )
      );
   }
}
  • Burada, ProductBox'ı ListView widget'ının alt öğeleri olarak kullandık .

  • Ürün düzeni uygulamasının (product_layout_app) tam kodu (main.dart) aşağıdaki gibidir -

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,
         ), 
         home: MyHomePage(title: 'Product layout demo home page'), 
      );
   }
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   @override 
   Widget build(BuildContext context) { 
      return Scaffold( 
         appBar: AppBar(title: Text("Product Listing")), 
         body: ListView(
            shrinkWrap: true, 
            padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), 
            children: <Widget>[ 
               ProductBox(
                  name: "iPhone", 
                  description: "iPhone is the stylist phone ever", 
                  price: 1000, 
                  image: "iphone.png"
               ), 
               ProductBox( 
                  name: "Pixel",    
                  description: "Pixel is the most featureful phone ever", 
                  price: 800, 
                  image: "pixel.png"
               ), 
               ProductBox( 
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox( 
                  name: "Tablet", 
                  description: "Tablet is the most useful device ever for meeting", 
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox( 
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ), 
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ), 
            ],
         )
      );
   }
}
class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.name, this.description, this.price, this.image}) :
      super(key: key); 
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 120, 
         child: Card(
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + image), 
                  Expanded( 
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column(    
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(
                                 this.name, style: TextStyle(
                                    fontWeight: FontWeight.bold
                                 )
                              ),
                              Text(this.description), Text(
                                 "Price: " + this.price.toString()
                              ), 
                           ], 
                        )
                     )
                  )
               ]
            )
         )
      );
   }
}

Uygulamanın nihai çıktısı aşağıdaki gibidir -

Hareketler , öncelikle bir kullanıcının bir mobil (veya herhangi bir dokunma tabanlı cihaz) uygulamayla etkileşim kurmasının bir yoludur. Hareketler genellikle, mobil cihazın belirli bir kontrolünü etkinleştirmek amacıyla bir kullanıcının herhangi bir fiziksel eylemi / hareketi olarak tanımlanır. Hareketler, oyun uygulamalarında kullanılan daha karmaşık eylemler için mobil cihazın ekranına dokunmak kadar basittir.

Yaygın olarak kullanılan hareketlerden bazıları burada belirtilmiştir -

  • Tap - Cihazın yüzeyine kısa bir süre parmak ucuyla dokunmak ve ardından parmak ucunu bırakmak.

  • Double Tap - Kısa sürede iki kez dokunun.

  • Drag - Cihazın yüzeyine parmak ucuyla dokunmak ve ardından parmak ucunu sabit bir şekilde hareket ettirmek ve ardından parmak ucunu serbest bırakmak.

  • Flick - Sürüklemeye benzer, ancak daha hızlı bir şekilde yapmak.

  • Pinch - Cihazın yüzeyini iki parmağınızla sıkıştırın.

  • Spread/Zoom - Sıkışmanın tam tersi.

  • Panning - Cihazın yüzeyine parmak ucuyla dokunmak ve parmak ucunu bırakmadan herhangi bir yönde hareket ettirmek.

Flutter, özel pencere öğesi aracılığıyla her tür hareket için mükemmel bir destek sağlar, GestureDetector. GestureDetector, öncelikle kullanıcının hareketini algılamak için kullanılan görsel olmayan bir pencere öğesidir. Bir pencere aracında hedeflenen bir hareketi tanımlamak için, pencere öğesi GestureDetector widget'ının içine yerleştirilebilir. GestureDetector, hareketi yakalayacak ve harekete göre birden fazla olay gönderecektir.

Hareketlerden bazıları ve ilgili olaylar aşağıda verilmiştir -

  • Tap
    • onTapDown
    • onTapUp
    • onTap
    • onTapCancel
  • Çift dokunun
    • onDoubleTap
  • Uzun basma
    • onLongPress
  • Dikey sürükleme
    • onVerticalDragStart
    • onVerticalDragUpdate
    • onVerticalDragEnd
  • Yatay sürükleme
    • onHorizontalDragStart
    • onHorizontalDragUpdate
    • onHorizontalDragEnd
  • Pan
    • onPanStart
    • onPanUpdate
    • onPanEnd

Şimdi, merhaba dünya uygulamasını hareket algılama özelliğini içerecek şekilde değiştirelim ve konsepti anlamaya çalışalım.

  • MyHomePage widget'ının gövde içeriğini aşağıda gösterildiği gibi değiştirin -

body: Center( 
   child: GestureDetector( 
      onTap: () { 
         _showDialog(context); 
      }, 
      child: Text( 'Hello World', ) 
   ) 
),
  • Burada, GestureDetector widget'ını widget hiyerarşisindeki Metin widget'ının üstüne yerleştirdiğimizi , onTap olayını yakaladığımızı ve ardından son olarak bir iletişim penceresi gösterdiğimizi gözlemleyin.

  • Kullanıcı merhaba dünya mesajına sekme eklediğinde bir iletişim kutusu sunmak için * _showDialog * işlevini uygulayın . Yeni bir iletişim kutusu widget'ı oluşturmak için genel showDialog ve AlertDialog widget'ını kullanır . Kod aşağıda gösterilmiştir -

// user defined function void _showDialog(BuildContext context) { 
   // flutter defined function 
   showDialog( 
      context: context, builder: (BuildContext context) { 
         // return object of type Dialog
         return AlertDialog( 
            title: new Text("Message"), 
            content: new Text("Hello World"),   
            actions: <Widget>[ 
               new FlatButton( 
                  child: new Text("Close"),  
                  onPressed: () {   
                     Navigator.of(context).pop();  
                  }, 
               ), 
            ], 
         ); 
      }, 
   ); 
}
  • Uygulama, Hızlı Yeniden Yükleme özelliğini kullanarak cihaza yeniden yüklenecektir. Şimdi, Hello World mesajına tıklamanız yeterlidir ve aşağıdaki iletişim kutusunu gösterecektir -

  • Şimdi, iletişim kutusundaki kapat seçeneğine tıklayarak iletişim kutusunu kapatın .

  • Tam kod (main.dart) aşağıdaki gibidir -

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: 'Hello World Demo Application', 
         theme: ThemeData( primarySwatch: Colors.blue,), 
         home: MyHomePage(title: 'Home page'), 
      ); 
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   // user defined function 
   void _showDialog(BuildContext context) { 
      // flutter defined function showDialog( 
         context: context, builder: (BuildContext context) { 
            // return object of type Dialog return AlertDialog(
               title: new Text("Message"), 
               content: new Text("Hello World"),   
               actions: <Widget>[
                  new FlatButton(
                     child: new Text("Close"), 
                     onPressed: () {   
                        Navigator.of(context).pop();  
                     }, 
                  ), 
               ],
            );
         },
      );
   }
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(this.title),),
         body: Center(
            child: GestureDetector( 
               onTap: () {
                  _showDialog(context);
               },
            child: Text( 'Hello World', )
            )
         ),
      );
   }
}

Son olarak, Flutter ayrıca Dinleyici widget'ı aracılığıyla düşük seviyeli bir hareket algılama mekanizması sağlar . Tüm kullanıcı etkileşimlerini algılar ve ardından aşağıdaki olayları gönderir -

  • PointerDownEvent
  • PointerMoveEvent
  • PointerUpEvent
  • PointerCancelEvent

Flutter ayrıca, özel ve gelişmiş hareketler yapmak için küçük bir widget seti sağlar. Widget'lar aşağıda listelenmiştir -

  • Dismissible - Widget'ı kapatmak için fiske hareketini destekler.

  • Draggable - Widget'ı taşımak için sürükleme hareketini destekler.

  • LongPressDraggable - Üst widget'ı da sürüklenebilir olduğunda bir widget'ı taşımak için sürükleme hareketini destekler.

  • DragTarget- Herhangi bir Sürüklenebilir widget'ı kabul eder

  • IgnorePointer - Widget'ı ve alt öğelerini hareket algılama işleminden gizler.

  • AbsorbPointer - Hareket algılama işleminin kendisini durdurur ve böylece örtüşen herhangi bir pencere öğesi de hareket algılama sürecine katılamaz ve dolayısıyla hiçbir olay ortaya çıkmaz.

  • Scrollable - Widget içinde bulunan içeriğin kaydırılmasını destekleyin.

Bir uygulamada durumu yönetmek, bir uygulamanın yaşam döngüsündeki en önemli ve gerekli süreçlerden biridir.

Basit bir alışveriş sepeti uygulamasını düşünelim.

  • Kullanıcı, kimlik bilgilerini kullanarak uygulamaya giriş yapacaktır.

  • Kullanıcı oturum açtıktan sonra, uygulama oturum açmış kullanıcı ayrıntılarını tüm ekranda saklamalıdır.

  • Yine, kullanıcı bir ürün seçip bir sepete kaydettiğinde, alışveriş sepeti bilgileri, kullanıcı alışveriş sepetini ödünç alana kadar sayfalar arasında kalmalıdır.

  • Herhangi bir örnekteki kullanıcı ve alışveriş sepeti bilgileri, o örnekteki uygulamanın durumu olarak adlandırılır.

Bir devlet yönetimi, bir uygulamada belirli bir durumun sürdüğü süreye bağlı olarak iki kategoriye ayrılabilir.

  • Ephemeral- Bir animasyonun mevcut durumu gibi birkaç saniye veya bir ürünün mevcut değerlendirmesi gibi tek bir sayfa için son. Flutter , StatefulWidget aracılığıyla bunu destekler.

  • app state- Son olarak, oturum açılmış kullanıcı ayrıntıları, alışveriş sepeti bilgileri, vb. Gibi tüm uygulama için, Flutter , kapsamlı_model aracılığıyla destekler.

Gezinme ve Yönlendirme

Herhangi bir uygulamada, bir sayfadan / ekrandan diğerine gitmek, uygulamanın iş akışını tanımlar. Bir uygulamanın navigasyonunun işlenme şekline Yönlendirme denir. Flutter, bir uygulamanın iş akışını tanımlamak için temel bir yönlendirme sınıfı - MaterialPageRoute ve iki yöntem - Navigator.push ve Navigator.pop sağlar.

MaterialPageRoute

MaterialPageRoute, tüm ekranı platforma özel bir animasyonla değiştirerek kullanıcı arayüzünü oluşturmak için kullanılan bir widget'tır.

MaterialPageRoute(builder: (context) => Widget())

Burada, oluşturucu, uygulamanın mevcut bağlamını sunarak içeriğini oluşturmak için bir işlevi kabul edecektir.

Navigation.push

Navigation.push, MaterialPageRoute widget'ını kullanarak yeni ekrana gitmek için kullanılır.

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

Navigation.pop

Bir önceki ekrana gitmek için Navigation.pop kullanılır.

Navigator.pop(context);

Navigasyon konseptini daha iyi anlamak için yeni bir uygulama oluşturalım.

Android stüdyosunda yeni bir Flutter uygulaması oluşturun, product_nav_app

  • Varlıklar klasörünü product_nav_app'den product_state_app'e kopyalayın ve varlıkları pubspec.yaml dosyasına ekleyin.

flutter:
   assets: 
   - assets/appimages/floppy.png 
   - assets/appimages/iphone.png 
   - assets/appimages/laptop.png 
   - assets/appimages/pendrive.png 
   - assets/appimages/pixel.png 
   - assets/appimages/tablet.png
  • Varsayılan başlangıç ​​kodunu (main.dart) başlangıç ​​kodumuzla değiştirin.

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, 
         ), 
         home: MyHomePage(
            title: 'Product state demo home page'
         ),
      );
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key);
   final String title;
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.title), 
         ), 
         body: Center(
            child: Text('Hello World',)
         ), 
      ); 
   } 
}
  • Ürün bilgilerini düzenlemek için bir Ürün sınıfı oluşturalım.

class Product { 
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   Product(this.name, this.description, this.price, this.image); 
}
  • Sahte ürün kayıtlarımızı oluşturmak için Product sınıfında getProducts yöntemini yazalım.

static List<Product> getProducts() {
   List<Product> items = <Product>[]; 
   
   items.add(
      Product( 
         "Pixel", 
         "Pixel is the most feature-full phone ever", 800, 
         "pixel.png"
      )
   ); 
   items.add(
      Product(
         "Laptop", 
         "Laptop is most productive development tool", 
         2000, "
         laptop.png"
      )
   ); 
   items.add(
      Product( 
         "Tablet", 
         "Tablet is the most useful device ever for meeting", 
         1500, 
         "tablet.png"
      )
   ); 
   items.add(
      Product( 
         "Pendrive", 
         "Pendrive is useful storage medium",
         100, 
         "pendrive.png"
      )
   ); 
   items.add(
      Product( 
         "Floppy Drive", 
         "Floppy drive is useful rescue storage medium", 
         20, 
         "floppy.png"
      )
   ); 
   return items; 
}
import product.dart in main.dart
import 'Product.dart';
  • Yeni widget'ımız RatingBox'ı ekleyelim.

class RatingBox extends StatefulWidget {
   @override 
   _RatingBoxState createState() =>_RatingBoxState(); 
} 
class _RatingBoxState extends State<RatingBox> {
   int _rating = 0; 
   void _setRatingAsOne() {
      setState(() {
         _rating = 1; 
      }); 
   } 
   void _setRatingAsTwo() {
      setState(() {
         _rating = 2; 
      }); 
   }
   void _setRatingAsThree() {
      setState(() {
         _rating = 3;
      });
   }
   Widget build(BuildContext context) {
      double _size = 20; 
      print(_rating); 
      return Row(
         mainAxisAlignment: MainAxisAlignment.end, 
         crossAxisAlignment: CrossAxisAlignment.end, 
         mainAxisSize: MainAxisSize.max, 
         children: <Widget>[
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 1? 
                     Icon( 
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon(
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsOne, 
                  iconSize: _size, 
               ), 
            ), 
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 2? 
                     Icon(
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon(
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsTwo, 
                  iconSize: _size, 
               ), 
            ), 
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 3 ? 
                     Icon(
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon( 
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsThree, 
                  iconSize: _size, 
               ), 
            ), 
         ], 
      ); 
   }
}
  • ProductBox widget'ımızı yeni Ürün sınıfımızla çalışacak şekilde değiştirelim.

class ProductBox extends StatelessWidget {    
   ProductBox({Key key, this.item}) : super(key: key); 
   final Product item; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 140, 
         child: Card( 
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + this.item.image), 
                  Expanded(
                     child: Container(
                        padding: EdgeInsets.all(5), 
                        child: Column(
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[
                              Text(this.item.name, 
                              style: TextStyle(fontWeight: FontWeight.bold)), 
                              Text(this.item.description), 
                              Text("Price: " + this.item.price.toString()), 
                              RatingBox(), 
                           ], 
                        )
                     )
                  )
               ]
            ), 
         )
      ); 
   }
}

MyHomePage widget'ımızı Product model ile çalışacak ve ListView kullanarak tüm ürünleri listeleyecek şekilde yeniden yazalım.

class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   final items = Product.getProducts(); 
   
   @override 
   Widget build(BuildContext context) { 
      return Scaffold( appBar: AppBar(title: Text("Product Navigation")), 
      body: ListView.builder( 
         itemCount: items.length, 
         itemBuilder: (context, index) {
            return GestureDetector( 
               child: ProductBox(item: items[index]), 
               onTap: () { 
                  Navigator.push( 
                     context, MaterialPageRoute( 
                        builder: (context) => ProductPage(item: items[index]), 
                     ), 
                  ); 
               }, 
            ); 
         }, 
      )); 
   } 
}

Burada, ürün ayrıntıları sayfasına gitmek için MaterialPageRoute'u kullandık.

  • Şimdi ürün detaylarını göstermek için ProductPage ekleyelim.

class ProductPage extends StatelessWidget { 
   ProductPage({Key key, this.item}) : super(key: key); 
   final Product item; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar( 
            title: Text(this.item.name), 
         ), 
         body: Center(
            child: Container(
               padding: EdgeInsets.all(0), 
               child: Column(
                  mainAxisAlignment: MainAxisAlignment.start, 
                  crossAxisAlignment: CrossAxisAlignment.start, 
                  children: <Widget>[
                     Image.asset("assets/appimages/" + this.item.image), 
                     Expanded(
                        child: Container(
                           padding: EdgeInsets.all(5), 
                           child: Column(
                              mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                              children: <Widget>[
                                 Text(
                                    this.item.name, style: TextStyle(
                                       fontWeight: FontWeight.bold
                                    )
                                 ), 
                                 Text(this.item.description), 
                                 Text("Price: " + this.item.price.toString()), 
                                 RatingBox(),
                              ], 
                           )
                        )
                     )
                  ]
               ), 
            ), 
         ), 
      ); 
   } 
}

Uygulamanın tam kodu aşağıdaki gibidir -

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp()); 

class Product {
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   Product(this.name, this.description, this.price, this.image); 
   
   static List<Product> getProducts() {
      List<Product> items = <Product>[]; 
      items.add(
         Product(
            "Pixel", 
            "Pixel is the most featureful phone ever", 
            800, 
            "pixel.png"
         )
      );
      items.add(
         Product(
            "Laptop", 
            "Laptop is most productive development tool", 
            2000, 
            "laptop.png"
         )
      ); 
      items.add(
         Product(
            "Tablet", 
            "Tablet is the most useful device ever for meeting", 
            1500, 
            "tablet.png"
         )
      ); 
      items.add(
         Product( 
            "Pendrive", 
            "iPhone is the stylist phone ever", 
            100, 
            "pendrive.png"
         )
      ); 
      items.add(
         Product(
            "Floppy Drive", 
            "iPhone is the stylist phone ever", 
            20, 
            "floppy.png"
         )
      ); 
      items.add(
         Product(
            "iPhone", 
            "iPhone is the stylist phone ever", 
            1000, 
            "iphone.png"
         )
      ); 
      return items; 
   }
}
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: 'Product Navigation demo home page'), 
      ); 
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   final items = Product.getProducts(); 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text("Product Navigation")), 
         body: ListView.builder( 
            itemCount: items.length, 
            itemBuilder: (context, index) { 
               return GestureDetector( 
                  child: ProductBox(item: items[index]), 
                  onTap: () { 
                     Navigator.push( 
                        context, 
                        MaterialPageRoute( 
                           builder: (context) => ProductPage(item: items[index]), 
                        ), 
                     ); 
                  }, 
               ); 
            }, 
         )
      ); 
   }
} 
class ProductPage extends StatelessWidget {
   ProductPage({Key key, this.item}) : super(key: key); 
   final Product item; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.item.name), 
         ), 
         body: Center(
            child: Container( 
               padding: EdgeInsets.all(0), 
               child: Column( 
                  mainAxisAlignment: MainAxisAlignment.start, 
                  crossAxisAlignment: CrossAxisAlignment.start, 
                  children: <Widget>[ 
                     Image.asset("assets/appimages/" + this.item.image), 
                     Expanded( 
                        child: Container( 
                           padding: EdgeInsets.all(5), 
                           child: Column( 
                              mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                              children: <Widget>[ 
                                 Text(this.item.name, style: TextStyle(fontWeight: FontWeight.bold)), 
                                 Text(this.item.description), 
                                 Text("Price: " + this.item.price.toString()), 
                                 RatingBox(), 
                              ], 
                           )
                        )
                     ) 
                  ]
               ), 
            ), 
         ), 
      ); 
   } 
}
class RatingBox extends StatefulWidget { 
   @override 
   _RatingBoxState createState() => _RatingBoxState(); 
} 
class _RatingBoxState extends State<RatingBox> { 
   int _rating = 0;
   void _setRatingAsOne() {
      setState(() {
         _rating = 1; 
      }); 
   }
   void _setRatingAsTwo() {
      setState(() {
         _rating = 2; 
      }); 
   } 
   void _setRatingAsThree() { 
      setState(() {
         _rating = 3; 
      }); 
   }
   Widget build(BuildContext context) {
      double _size = 20; 
      print(_rating); 
      return Row(
         mainAxisAlignment: MainAxisAlignment.end, 
         crossAxisAlignment: CrossAxisAlignment.end, 
         mainAxisSize: MainAxisSize.max, 
         children: <Widget>[
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 1 ? Icon( 
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon( 
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsOne, 
                  iconSize: _size, 
               ), 
            ), 
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton( 
                  icon: (
                     _rating >= 2 ? 
                     Icon( 
                        Icons.star, 
                        size: _size, 
                     ) 
                     : Icon( 
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsTwo, 
                  iconSize: _size, 
               ), 
            ), 
            Container(
               padding: EdgeInsets.all(0), 
               child: IconButton(
                  icon: (
                     _rating >= 3 ? 
                     Icon( 
                        Icons.star, 
                        size: _size, 
                     )
                     : Icon( 
                        Icons.star_border, 
                        size: _size, 
                     )
                  ), 
                  color: Colors.red[500], 
                  onPressed: _setRatingAsThree, 
                  iconSize: _size, 
               ), 
            ), 
         ], 
      ); 
   } 
} 
class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.item}) : super(key: key); 
   final Product item; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 140, 
         child: Card(
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + this.item.image), 
                  Expanded( 
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column( 
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(this.item.name, style: TextStyle(fontWeight: FontWeight.bold)), Text(this.item.description), 
                              Text("Price: " + this.item.price.toString()), 
                              RatingBox(), 
                           ], 
                        )
                     )
                  ) 
               ]
            ), 
         )
      ); 
   } 
}

Uygulamayı çalıştırın ve herhangi bir ürün öğesine tıklayın. İlgili ayrıntılar sayfasını gösterecektir. Geri butonuna tıklayarak ana sayfaya geçebiliriz. Uygulamanın ürün listesi sayfası ve ürün detayları sayfası aşağıdaki gibidir -

Animasyon, herhangi bir mobil uygulamadaki karmaşık bir prosedürdür. Animasyon, karmaşıklığına rağmen kullanıcı deneyimini yeni bir düzeye çıkarır ve zengin bir kullanıcı etkileşimi sağlar. Zenginliği nedeniyle animasyon, modern mobil uygulamanın ayrılmaz bir parçası haline gelir. Flutter çerçevesi, Animasyonun öneminin farkındadır ve her türden animasyonu geliştirmek için basit ve sezgisel bir çerçeve sağlar.

Giriş

Animasyon, bir hareket yanılsaması vermek için bir dizi görüntüyü / resmi belirli bir süre içinde belirli bir sırada gösterme işlemidir. Animasyonun en önemli yönleri aşağıdaki gibidir -

  • Animasyonun iki farklı değeri vardır: Başlangıç ​​değeri ve Bitiş değeri. Animasyon Başlangıç değerinden başlar ve bir dizi ara değerden geçer ve son olarak Bitiş değerlerinde sona erer. Örneğin, bir widget'ı kaybolacak şekilde hareketlendirmek için, başlangıç ​​değeri tam opaklık ve son değer sıfır opaklık olacaktır.

  • Ara değerler, doğası gereği doğrusal olabilir veya doğrusal olmayabilir (eğri) ve yapılandırılabilir. Animasyonun yapılandırıldığı gibi çalıştığını anlayın. Her konfigürasyon, animasyona farklı bir his verir. Örneğin, bir parçacığın solması doğası gereği doğrusal olacaktır, oysa bir topun zıplaması doğası gereği doğrusal olmayacaktır.

  • Animasyon işleminin süresi, animasyonun hızını (yavaşlığı veya hızı) etkiler.

  • Animasyonu başlatma, animasyonu durdurma, animasyonu defalarca ayarlamak için tekrar etme, animasyon sürecini tersine çevirme gibi animasyon sürecini kontrol etme yeteneği,

  • Flutter'da animasyon sistemi gerçek bir animasyon yapmaz. Bunun yerine, yalnızca görüntüleri işlemek için her karede gereken değerleri sağlar.

Animasyona Dayalı Sınıflar

Flutter animasyon sistemi, Animasyon nesnelerine dayanmaktadır. Çekirdek animasyon sınıfları ve kullanımı aşağıdaki gibidir -

Animasyon

Belirli bir süre boyunca iki sayı arasında enterpolasyonlu değerler üretir. En yaygın Animasyon sınıfları şunlardır:

  • Animation<double> - iki ondalık sayı arasındaki değerleri enterpolate edin

  • Animation<Color> - iki renk arasında renklerin enterpolasyonu

  • Animation<Size> - iki boyut arasındaki boyutları enterpolate edin

  • AnimationController- Animasyonun kendisini kontrol etmek için Özel Animasyon nesnesi. Uygulama yeni bir çerçeveye hazır olduğunda yeni değerler üretir. Doğrusal tabanlı animasyonu destekler ve değer 0,0 ile 1,0 arasında başlar

controller = AnimationController(duration: const Duration(seconds: 2), vsync: this);

Burada, kontrolör animasyonu kontrol eder ve süre seçeneği animasyon işleminin süresini kontrol eder. vsync, animasyonda kullanılan kaynağı optimize etmek için kullanılan özel bir seçenektir.

Eğri Animasyon

AnimationController'a benzer, ancak doğrusal olmayan animasyonu destekler. CurvedAnimation, aşağıdaki gibi Animasyon nesnesiyle birlikte kullanılabilir -

controller = AnimationController(duration: const Duration(seconds: 2), vsync: this); 
animation = CurvedAnimation(parent: controller, curve: Curves.easeIn)

<T> ara

Animatable <T> 'den türetilmiştir ve 0 ve 1 dışındaki herhangi iki sayı arasında sayılar oluşturmak için kullanılır. Animate yöntemi kullanılarak ve gerçek Animation nesnesini ileterek Animation nesnesiyle birlikte kullanılabilir.

AnimationController controller = AnimationController( 
   duration: const Duration(milliseconds: 1000), 
vsync: this); Animation<int> customTween = IntTween(
   begin: 0, end: 255).animate(controller);
  • Tween, aşağıdaki gibi CurvedAnimation ile birlikte de kullanılabilir -

AnimationController controller = AnimationController(
   duration: const Duration(milliseconds: 500), vsync: this); 
final Animation curve = CurvedAnimation(parent: controller, curve: Curves.easeOut); 
Animation<int> customTween = IntTween(begin: 0, end: 255).animate(curve);

Burada, denetleyici gerçek animasyon denetleyicisidir. eğri, doğrusal olmama türünü sağlar ve customTween, 0 ile 255 arasında özel aralık sağlar.

Flutter Animasyonunun iş akışı

Animasyonun iş akışı aşağıdaki gibidir -

  • StatefulWidget initState öğesinde animasyon denetleyicisini tanımlayın ve başlatın.

AnimationController(duration: const Duration(seconds: 2), vsync: this); 
animation = Tween<double>(begin: 0, end: 300).animate(controller); 
controller.forward();
  • Widget'ın durumunu değiştirmek için animasyon tabanlı dinleyici, addListener ekleyin.

animation = Tween<double>(begin: 0, end: 300).animate(controller) ..addListener(() {
   setState(() { 
      // The state that has changed here is the animation object’s value. 
   }); 
});
  • Yerleşik widget'lar, AnimatedWidget ve AnimatedBuilder bu işlemi atlamak için kullanılabilir. Her iki widget da Animasyon nesnesini kabul eder ve animasyon için gerekli olan geçerli değerleri alır.

  • Widget'ın oluşturma işlemi sırasında animasyon değerlerini alın ve ardından bunu orijinal değer yerine genişlik, yükseklik veya ilgili herhangi bir özellik için uygulayın.

child: Container( 
   height: animation.value, 
   width: animation.value, 
   child: <Widget>, 
)

Çalışma Uygulaması

Flutter çerçevesinde animasyon kavramını anlamak için basit bir animasyon tabanlı uygulama yazalım.

  • Android stüdyosunda yeni bir Flutter uygulaması oluşturun , product_animation_app.

  • Varlıklar klasörünü product_nav_app'den product_animation_app'e kopyalayın ve varlıkları pubspec.yaml dosyasının içine ekleyin.

flutter: 
   assets: 
   - assets/appimages/floppy.png 
   - assets/appimages/iphone.png 
   - assets/appimages/laptop.png 
   - assets/appimages/pendrive.png 
   - assets/appimages/pixel.png 
   - assets/appimages/tablet.png
  • Varsayılan başlangıç ​​kodunu (main.dart) kaldırın.

  • İçe aktarma ve temel ana işlevi ekleyin.

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp());
  • StatefulWidgtet'ten türetilen Uygulamam widget'ını oluşturun.

class MyApp extends StatefulWidget { 
   _MyAppState createState() => _MyAppState(); 
}
  • _MyAppState widget'ı oluşturun ve initState'i uygulayın ve varsayılan derleme yöntemine ek olarak atın.

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin { 
   Animation<double> animation; 
   AnimationController controller; 
   @override void initState() {
      super.initState(); 
      controller = AnimationController(
         duration: const Duration(seconds: 10), vsync: this
      ); 
      animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller); 
      controller.forward(); 
   } 
   // This widget is the root of your application. 
   @override 
   Widget build(BuildContext context) {
      controller.forward(); 
      return MaterialApp(
         title: 'Flutter Demo',
         theme: ThemeData(primarySwatch: Colors.blue,), 
         home: MyHomePage(title: 'Product layout demo home page', animation: animation,)
      ); 
   } 
   @override 
   void dispose() {
      controller.dispose();
      super.dispose();
   }
}

Buraya,

  • İnitState yönteminde, bir animasyon denetleyici nesnesi (controller), bir animasyon nesnesi (animasyon) oluşturduk ve controller.forward kullanarak animasyonu başlattık.

  • Dispose yönteminde, animasyon denetleyici nesnesini (denetleyici) yerleştirdik.

  • Derleme yönteminde, yapıcı aracılığıyla MyHomePage widget'ına animasyon gönderin. Artık MyHomePage widget'ı, içeriğini canlandırmak için animasyon nesnesini kullanabilir.

  • Şimdi ProductBox widget'ını ekleyin

class ProductBox extends StatelessWidget {
   ProductBox({Key key, this.name, this.description, this.price, this.image})
      : super(key: key);
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 140, 
         child: Card( 
            child: Row( 
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + image), 
                  Expanded( 
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column( 
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(this.name, style: 
                                 TextStyle(fontWeight: FontWeight.bold)), 
                              Text(this.description), 
                                 Text("Price: " + this.price.toString()), 
                           ], 
                        )
                     )
                  )
               ]
            )
         )
      ); 
   }
}
  • Opaklık kullanarak basit solma animasyonu yapmak için yeni bir widget, MyAnimatedWidget oluşturun.

class MyAnimatedWidget extends StatelessWidget { 
   MyAnimatedWidget({this.child, this.animation}); 
      
   final Widget child; 
   final Animation<double> animation; 
   
   Widget build(BuildContext context) => Center( 
   child: AnimatedBuilder(
      animation: animation, 
      builder: (context, child) => Container( 
         child: Opacity(opacity: animation.value, child: child), 
      ), 
      child: child), 
   ); 
}
  • Burada, animasyonumuzu yapmak için AniatedBuilder'ı kullandık. AnimatedBuilder, aynı anda animasyonu yaparken içeriğini oluşturan bir widget'tır. Mevcut animasyon değerini almak için bir animasyon nesnesini kabul eder. Alt widget'ın opaklığını ayarlamak için animasyon değeri, animation.value kullandık. Gerçekte, widget, opaklık konseptini kullanarak alt widget'ı hareketlendirecektir.

  • Son olarak, MyHomePage widget'ını oluşturun ve içeriğinden herhangi birine animasyon uygulamak için animasyon nesnesini kullanın.

class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title, this.animation}) : super(key: key); 
   
   final String title; 
   final Animation<double> 
   animation; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text("Product Listing")),body: ListView(
            shrinkWrap: true,
            padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), 
            children: <Widget>[
               FadeTransition(
                  child: ProductBox(
                     name: "iPhone", 
                     description: "iPhone is the stylist phone ever", 
                     price: 1000, 
                     image: "iphone.png"
                  ), opacity: animation
               ), 
               MyAnimatedWidget(child: ProductBox(
                  name: "Pixel", 
                  description: "Pixel is the most featureful phone ever", 
                  price: 800, 
                  image: "pixel.png"
               ), animation: animation), 
               ProductBox(
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox(
                  name: "Tablet", 
                  description: "Tablet is the most useful device ever for meeting", 
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox(
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ),
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ),
            ],
         )
      );
   }
}

Burada, listedeki ilk iki öğeyi canlandırmak için FadeAnimation ve MyAnimationWidget'ı kullandık. FadeAnimation, opaklık kavramını kullanarak çocuğunu canlandırmak için kullandığımız yerleşik bir animasyon sınıfıdır.

  • Kodun tamamı aşağıdaki gibidir -

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp()); 

class MyApp extends StatefulWidget { 
   _MyAppState createState() => _MyAppState(); 
} 
class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
   Animation<double> animation; 
   AnimationController controller; 
   
   @override 
   void initState() {
      super.initState(); 
      controller = AnimationController(
         duration: const Duration(seconds: 10), vsync: this); 
      animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller); 
      controller.forward(); 
   } 
   // This widget is the root of your application. 
   @override 
   Widget build(BuildContext context) {
      controller.forward(); 
      return MaterialApp( 
         title: 'Flutter Demo', theme: ThemeData(primarySwatch: Colors.blue,), 
         home: MyHomePage(title: 'Product layout demo home page', animation: animation,) 
      ); 
   } 
   @override 
   void dispose() {
      controller.dispose();
      super.dispose(); 
   } 
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title, this.animation}): super(key: key);
   final String title; 
   final Animation<double> animation; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text("Product Listing")), 
         body: ListView(
            shrinkWrap: true, 
            padding: const EdgeInsets.fromLTRB(2.0, 10.0, 2.0, 10.0), 
            children: <Widget>[
               FadeTransition(
                  child: ProductBox(
                     name: "iPhone", 
                     description: "iPhone is the stylist phone ever", 
                     price: 1000, 
                     image: "iphone.png"
                  ), 
                  opacity: animation
               ), 
               MyAnimatedWidget(
                  child: ProductBox( 
                     name: "Pixel", 
                     description: "Pixel is the most featureful phone ever", 
                     price: 800, 
                     image: "pixel.png"
                  ), 
                  animation: animation
               ), 
               ProductBox( 
                  name: "Laptop", 
                  description: "Laptop is most productive development tool", 
                  price: 2000, 
                  image: "laptop.png"
               ), 
               ProductBox(
                  name: "Tablet",
                  description: "Tablet is the most useful device ever for meeting",
                  price: 1500, 
                  image: "tablet.png"
               ), 
               ProductBox(
                  name: "Pendrive", 
                  description: "Pendrive is useful storage medium", 
                  price: 100, 
                  image: "pendrive.png"
               ), 
               ProductBox(
                  name: "Floppy Drive", 
                  description: "Floppy drive is useful rescue storage medium", 
                  price: 20, 
                  image: "floppy.png"
               ), 
            ], 
         )
      ); 
   } 
} 
class ProductBox extends StatelessWidget { 
   ProductBox({Key key, this.name, this.description, this.price, this.image}) :
      super(key: key);
   final String name; 
   final String description; 
   final int price; 
   final String image; 
   Widget build(BuildContext context) {
      return Container(
         padding: EdgeInsets.all(2), 
         height: 140, 
         child: Card(
            child: Row(
               mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
               children: <Widget>[ 
                  Image.asset("assets/appimages/" + image), 
                  Expanded(
                     child: Container( 
                        padding: EdgeInsets.all(5), 
                        child: Column( 
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly, 
                           children: <Widget>[ 
                              Text(
                                 this.name, style: TextStyle(
                                    fontWeight: FontWeight.bold
                                 )
                              ), 
                              Text(this.description), Text(
                                 "Price: " + this.price.toString()
                              ), 
                           ], 
                        )
                     )
                  ) 
               ]
            )
         )
      ); 
   } 
}
class MyAnimatedWidget extends StatelessWidget { 
   MyAnimatedWidget({this.child, this.animation}); 
   final Widget child; 
   final Animation<double> animation; 
 
   Widget build(BuildContext context) => Center( 
      child: AnimatedBuilder(
         animation: animation, 
         builder: (context, child) => Container( 
            child: Opacity(opacity: animation.value, child: child), 
         ), 
         child: child
      ), 
   ); 
}
  • Sonuçları görmek için uygulamayı derleyin ve çalıştırın. Uygulamanın ilk ve son versiyonu aşağıdaki gibidir -

Flutter, platforma özgü özelliğe erişmek için genel bir çerçeve sağlar. Bu, geliştiricinin platforma özel kod kullanarak Flutter çerçevesinin işlevselliğini genişletmesini sağlar . Kamera, pil seviyesi, tarayıcı vb. Gibi platforma özgü işlevlere çerçeve aracılığıyla kolayca erişilebilir.

Platforma özel koda erişmenin genel fikri basit mesajlaşma protokolüdür. Flutter kodu, İstemci ve platform kodu ve Ana Bilgisayar, ortak bir Mesaj Kanalına bağlanır. Müşteri, Mesaj Kanalı üzerinden Toplantı Sahibine mesaj gönderir. Host, Mesaj Kanalını dinler, mesajı alır ve gerekli işlevselliği yapar ve son olarak, mesajı Mesaj Kanalı üzerinden Müşteriye geri gönderir.

Platforma özgü kod mimarisi, aşağıda verilen blok şemada gösterilmektedir -

Mesajlaşma protokolü, sayılar, dizeler, boole vb. Gibi JSON benzeri değerlerin ikili serileştirmesini destekleyen standart bir mesaj codec bileşeni (StandardMessageCodec sınıfı) kullanır. Serileştirme ve serileştirmeden çıkarma, istemci ve ana bilgisayar arasında şeffaf bir şekilde çalışır.

Android SDK kullanarak bir tarayıcı açmak için basit bir uygulama yazalım ve nasıl olduğunu anlayalım

  • Android stüdyosunda yeni bir Flutter uygulaması oluşturun, flutter_browser_app

  • Main.dart kodunu aşağıdaki kodla değiştirin -

import 'package:flutter/material.dart'; 
void main() => runApp(MyApp()); 
class MyApp extends StatelessWidget { 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(title: 'Flutter Demo Home Page'),
      );
   }
}
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(
            title: Text(this.title), 
         ), 
         body: Center(
            child: RaisedButton( 
               child: Text('Open Browser'), 
               onPressed: null, 
            ), 
         ), 
      ); 
   }
}
  • Burada, tarayıcıyı açmak ve onPressed yöntemini null olarak ayarlamak için yeni bir düğme oluşturduk.

  • Şimdi, aşağıdaki paketleri içe aktarın -

import 'dart:async'; 
import 'package:flutter/services.dart';
  • Burada services.dart, platforma özel kodu çağırma işlevini içerir.

  • MyHomePage widget'ında yeni bir mesaj kanalı oluşturun.

static const platform = const 
MethodChannel('flutterapp.tutorialspoint.com/browser');
  • İleti kanalı aracılığıyla platforma özel yöntemi, openBrowser yöntemini çağırmak için bir yöntem, _openBrowser yazın.

Future<void> _openBrowser() async { 
   try {
      final int result = await platform.invokeMethod(
         'openBrowser', <String, String>{ 
            'url': "https://flutter.dev" 
         }
      ); 
   } 
   on PlatformException catch (e) { 
      // Unable to open the browser 
      print(e); 
   }
}

Burada openBrowser'ı çağırmak için platform.invokeMethod'u kullandık (sonraki adımlarda açıklanmıştır). openBrowser'ın belirli bir url'yi açmak için bir url'si var.

  • RaisedButton öğesinin onPressed özelliğinin değerini null iken _openBrowser olarak değiştirin.

onPressed: _openBrowser,
  • MainActivity.java'yı (android klasörünün içinde) açın ve gerekli kitaplığı içe aktarın -

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 

import io.flutter.app.FlutterActivity; 
import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel; 
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugins.GeneratedPluginRegistrant;
  • Bir yöntem yazın, tarayıcı açmak için tarayıcı açın

private void openBrowser(MethodCall call, Result result, String url) { 
   Activity activity = this; 
   if (activity == null) { 
      result.error("ACTIVITY_NOT_AVAILABLE", 
      "Browser cannot be opened without foreground 
      activity", null); 
      return; 
   } 
   Intent intent = new Intent(Intent.ACTION_VIEW); 
   intent.setData(Uri.parse(url)); 
   
   activity.startActivity(intent); 
   result.success((Object) true); 
}
  • Şimdi, MainActivity sınıfında kanal adını ayarlayın -

private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser";
  • OnCreate yönteminde mesaj işlemeyi ayarlamak için android'e özel kod yazın -

new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler( 
   new MethodCallHandler() { 
   @Override 
   public void onMethodCall(MethodCall call, Result result) { 
      String url = call.argument("url"); 
      if (call.method.equals("openBrowser")) {
         openBrowser(call, result, url); 
      } else { 
         result.notImplemented(); 
      } 
   } 
});

Burada MethodChannel sınıfını kullanarak bir mesaj kanalı oluşturduk ve mesajı işlemek için MethodCallHandler sınıfını kullandık. onMethodCall, mesajı kontrol ederek doğru platforma özel kodu çağırmaktan sorumlu gerçek yöntemdir. onMethodCall yöntemi, url'yi mesajdan çıkarır ve ardından openBrowser'ı yalnızca yöntem çağrısı openBrowser olduğunda çağırır. Aksi takdirde notImplemented yöntemini döndürür.

Uygulamanın tam kaynak kodu aşağıdaki gibidir -

main.dart

MainActivity.java

package com.tutorialspoint.flutterapp.flutter_browser_app; 

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 
import io.flutter.app.FlutterActivity; 
import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugins.GeneratedPluginRegistrant; 

public class MainActivity extends FlutterActivity { 
   private static final String CHANNEL = "flutterapp.tutorialspoint.com/browser"; 
   @Override 
   protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      GeneratedPluginRegistrant.registerWith(this); 
      new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
         new MethodCallHandler() {
            @Override 
            public void onMethodCall(MethodCall call, Result result) {
               String url = call.argument("url"); 
               if (call.method.equals("openBrowser")) { 
                  openBrowser(call, result, url); 
               } else { 
                  result.notImplemented(); 
               }
            }
         }
      ); 
   }
   private void openBrowser(MethodCall call, Result result, String url) {
      Activity activity = this; if (activity == null) {
         result.error(
            "ACTIVITY_NOT_AVAILABLE", "Browser cannot be opened without foreground activity", null
         ); 
         return; 
      } 
      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      activity.startActivity(intent); 
      result.success((Object) true); 
   }
}

main.dart

import 'package:flutter/material.dart'; 
import 'dart:async'; 
import 'package:flutter/services.dart'; 

void main() => runApp(MyApp()); 
class MyApp extends StatelessWidget {
   @override 
   Widget build(BuildContext context) {
      return MaterialApp(
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(
            title: 'Flutter Demo Home Page'
         ), 
      ); 
   }
}
class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   static const platform = const MethodChannel('flutterapp.tutorialspoint.com/browser'); 
   Future<void> _openBrowser() async {
      try {
         final int result = await platform.invokeMethod('openBrowser', <String, String>{ 
            'url': "https://flutter.dev" 
         });
      }
      on PlatformException catch (e) { 
         // Unable to open the browser print(e); 
      } 
   }
   @override 
   Widget build(BuildContext context) {
      return Scaffold( 
         appBar: AppBar( 
            title: Text(this.title), 
         ), 
         body: Center(
            child: RaisedButton( 
               child: Text('Open Browser'), 
               onPressed: _openBrowser, 
            ), 
         ),
      );
   }
}

Uygulamayı çalıştırın ve Tarayıcıyı Aç düğmesine tıklayın ve tarayıcının başlatıldığını görebilirsiniz. Tarayıcı uygulaması - Ana sayfa, buradaki ekran görüntüsünde gösterildiği gibidir -

İOS'a özgü koda erişim, iOS'a özgü dilleri kullanması dışında Android platformundakine benzer - Objective-C veya Swift ve iOS SDK. Aksi takdirde, konsept Android platformunun konseptiyle aynıdır.

İOS platformu için de bir önceki bölümde olduğu gibi aynı uygulamayı yazalım.

  • Android Studio (macOS) flutter_browser_ios_app'da yeni bir uygulama oluşturalım

  • Önceki bölümde olduğu gibi 2-6. Adımları izleyin.

  • XCode'u başlatın ve tıklayın File → Open

  • Flutter projemizin ios dizini altındaki xcode projesini seçin.

  • AppDelegate.m dosyasını açın Runner → Runner path. Aşağıdaki kodu içerir -

#include "AppDelegate.h" 
#include "GeneratedPluginRegistrant.h" 
@implementation AppDelegate 

- (BOOL)application:(UIApplication *)application
   didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
      // [GeneratedPluginRegistrant registerWithRegistry:self];
      // Override point for customization after application launch.
      return [super application:application didFinishLaunchingWithOptions:launchOptions];
   } 
@end
  • Tarayıcıyı belirtilen url ile açmak için openBrowser adlı bir yöntem ekledik. Tek bağımsız değişken olan url'yi kabul eder.

- (void)openBrowser:(NSString *)urlString { 
   NSURL *url = [NSURL URLWithString:urlString]; 
   UIApplication *application = [UIApplication sharedApplication]; 
   [application openURL:url]; 
}
  • DidFinishLaunchingWithOptions yönteminde denetleyiciyi bulun ve denetleyici değişkeninde ayarlayın.

FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController;
  • DidFinishLaunchingWithOptions yönteminde, tarayıcı kanalını flutterapp.tutorialspoint.com/browse olarak ayarlayın -

FlutterMethodChannel* browserChannel = [
   FlutterMethodChannel methodChannelWithName:
   @"flutterapp.tutorialspoint.com/browser" binaryMessenger:controller];
  • Bir değişken oluşturun, poorSelf ve mevcut sınıfı ayarlayın -

__weak typeof(self) weakSelf = self;
  • Şimdi setMethodCallHandler'ı uygulayın. Call.method ile eşleştirerek openBrowser'ı çağırın. Call.arguments'ı çağırarak url'yi alın ve openBrowser'ı çağırırken iletin.

[browserChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
   if ([@"openBrowser" isEqualToString:call.method]) { 
      NSString *url = call.arguments[@"url"];   
      [weakSelf openBrowser:url]; 
   } else { result(FlutterMethodNotImplemented); } 
}];
  • Kodun tamamı aşağıdaki gibidir -

#include "AppDelegate.h" 
#include "GeneratedPluginRegistrant.h" 
@implementation AppDelegate 

- (BOOL)application:(UIApplication *)application 
   didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
   
   // custom code starts 
   FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; 
   FlutterMethodChannel* browserChannel = [
      FlutterMethodChannel methodChannelWithName:
      @"flutterapp.tutorialspoint.com /browser" binaryMessenger:controller]; 
   
   __weak typeof(self) weakSelf = self; 
   [browserChannel setMethodCallHandler:^(
      FlutterMethodCall* call, FlutterResult result) { 
      
      if ([@"openBrowser" isEqualToString:call.method]) { 
         NSString *url = call.arguments[@"url"];
         [weakSelf openBrowser:url]; 
      } else { result(FlutterMethodNotImplemented); } 
   }]; 
   // custom code ends 
   [GeneratedPluginRegistrant registerWithRegistry:self]; 
   
   // Override point for customization after application launch. 
   return [super application:application didFinishLaunchingWithOptions:launchOptions]; 
}
- (void)openBrowser:(NSString *)urlString { 
   NSURL *url = [NSURL URLWithString:urlString]; 
   UIApplication *application = [UIApplication sharedApplication]; 
   [application openURL:url]; 
} 
@end
  • Proje ayarını açın.

  • Git Capabilities ve etkinleştir Background Modes.

  • Ekle *Background fetch ve Remote Notification**.

  • Şimdi uygulamayı çalıştırın. Android sürümüne benzer şekilde çalışır ancak Chrome yerine Safari tarayıcısı açılacaktır.

Dart'ın bir dizi işlevi organize etme ve paylaşma yolu, Paket yoluyla yapılır. Dart Paketi, paylaşılabilir kitaplıklar veya modüllerdir. Genel olarak, Dart Paketi, Dart Paketi'nin ana uygulama giriş noktasına sahip olmaması dışında Dart Uygulaması ile aynıdır.

Paketin genel yapısı (bir demo paketi düşünün, my_demo_package) aşağıdaki gibidir -

  • lib/src/* - Özel Dart kodu dosyaları.

  • lib/my_demo_package.dart- Ana Dart kod dosyası. Bir uygulamaya şu şekilde aktarılabilir:

import 'package:my_demo_package/my_demo_package.dart'
  • Diğer özel kod dosyası, gerekirse aşağıda gösterildiği gibi ana kod dosyasına (my_demo_package.dart) aktarılabilir -

export src/my_private_code.dart
  • lib/*- Herhangi bir özel klasör yapısında düzenlenmiş herhangi bir sayıda Dart kodu dosyası. Koda şu şekilde erişilebilir:

import 'package:my_demo_package/custom_folder/custom_file.dart'
  • pubspec.yaml - Uygulama ile aynı proje spesifikasyonu,

Paketteki tüm Dart kodu dosyaları basitçe Dart sınıflarıdır ve Dart kodunun onu bir Pakete dahil etmesi için herhangi bir özel gereksinimi yoktur.

Paket Türleri

Dart Paketleri temelde benzer işlevselliklerin küçük bir koleksiyonu olduğundan, işlevselliğine göre kategorize edilebilir.

Dart Paketi

Hem web hem de mobil ortamda kullanılabilen genel Dart kodu. Örneğin, english_words, yaklaşık 5000 kelime içeren ve isimler (İngilizce isimleri listeleme), heceler (bir kelimedeki hece sayısını belirtin) gibi temel yardımcı fonksiyonlara sahip böyle bir pakettir.

Flutter Paketi

Flutter çerçevesine bağlı olan ve yalnızca mobil ortamda kullanılabilen genel Dart kodu. Örneğin fluro, flutter için özel bir yönlendiricidir. Flutter çerçevesine bağlıdır.

Flutter Eklentisi

Flutter çerçevesine ve temel platform koduna (Android SDK veya iOS SDK) bağlı olan genel Dart kodu. Örneğin, kamera, cihaz kamerasıyla etkileşim kurmak için bir eklentidir. Kameraya erişim sağlamak için Flutter çerçevesine ve temel çerçeveye bağlıdır.

Dart Paketi Kullanmak

Dart Paketleri, canlı sunucuda barındırılır ve yayınlanır, https://pub.dartlang.org.Ayrıca, Flutter, uygulamadaki Dart Paketlerini yönetmek için basit bir araç, pub sağlar. Paket olarak kullanmak için gereken adımlar aşağıdaki gibidir -

  • Paket adını ve gereken sürümü pubspec.yaml'ye aşağıda gösterildiği gibi ekleyin -

dependencies: english_words: ^3.1.5
  • En son sürüm numarası çevrimiçi sunucuyu kontrol ederek bulunabilir.

  • Aşağıdaki komutu kullanarak paketi uygulamaya yükleyin -

flutter packages get
  • Android Studio, Android stüdyosunda geliştirme yaparken, pubspec.yaml'deki herhangi bir değişikliği tespit eder ve aşağıda gösterildiği gibi geliştiriciye bir Android stüdyo paketi uyarısı görüntüler -

  • Dart Paketleri, menü seçenekleri kullanılarak Android Studio'da yüklenebilir veya güncellenebilir.

  • Aşağıda gösterilen komutu kullanarak gerekli dosyayı içe aktarın ve çalışmaya başlayın -

import 'package:english_words/english_words.dart';
  • Pakette bulunan herhangi bir yöntemi kullanın,

nouns.take(50).forEach(print);
  • Burada, ilk 50 kelimeyi almak ve yazdırmak için isimler işlevini kullandık.

Flutter Eklenti Paketi Geliştirin

Flutter Eklentisi geliştirmek, bir Dart uygulaması veya Dart Paketi geliştirmeye benzer. Bunun tek istisnası, eklentinin platforma özgü gerekli işlevselliği elde etmek için Sistem API'sini (Android veya iOS) kullanmasıdır.

Önceki bölümlerde platform koduna nasıl erişeceğimizi zaten öğrendiğimiz gibi, eklenti geliştirme sürecini anlamak için my_browser adlı basit bir eklenti geliştirelim. My_browser eklentisinin işlevselliği, uygulamanın belirli web sitesini platforma özel tarayıcıda açmasına izin vermektir.

  • Android Studio'yu başlatın.

  • Tıklayın File → New Flutter Project ve Flutter Plugin seçeneğini seçin.

  • Burada gösterildiği gibi bir Flutter eklenti seçim penceresi görebilirsiniz -

  • My_browser proje adı olarak girin ve Next'e tıklayın.

  • Eklenti adını ve diğer ayrıntıları burada gösterildiği gibi pencereye girin -

  • Aşağıda gösterilen pencerede şirket etki alanını, flutterplugins.tutorialspoint.com adresini girin ve ardından Finish. Yeni eklentimizi geliştirmek için bir başlangıç ​​kodu oluşturacaktır.

  • My_browser.dart dosyasını açın ve platforma özel openBrowser yöntemini çağırmak için bir yöntem olan openBrowser yazın.

Future<void> openBrowser(String urlString) async { 
   try {
      final int result = await _channel.invokeMethod(
         'openBrowser', <String, String>{ 'url': urlString }
      );
   }
   on PlatformException catch (e) { 
      // Unable to open the browser print(e); 
   } 
}
  • MyBrowserPlugin.java dosyasını açın ve aşağıdaki sınıfları içe aktarın -

import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle;
  • Burada, Android'den bir tarayıcı açmak için gerekli kitaplığı içe aktarmamız gerekiyor.

  • MyBrowserPlugin sınıfına Registrar türünde yeni özel değişken mRegistrar ekleyin.

private final Registrar mRegistrar;
  • Burada Registrar, çağıran kodun bağlam bilgisini almak için kullanılır.

  • MyBrowserPlugin sınıfında Registrar'ı ayarlamak için bir yapıcı ekleyin.

private MyBrowserPlugin(Registrar registrar) { 
   this.mRegistrar = registrar; 
}
  • Yeni kurucumuzu MyBrowserPlugin sınıfına dahil etmek için registerWith öğesini değiştirin.

public static void registerWith(Registrar registrar) { 
   final MethodChannel channel = new MethodChannel(registrar.messenger(), "my_browser"); 
   MyBrowserPlugin instance = new MyBrowserPlugin(registrar); 
   channel.setMethodCallHandler(instance); 
}
  • OnMethodCall'ı MyBrowserPlugin sınıfına openBrowser yöntemini dahil edecek şekilde değiştirin.

@Override 
public void onMethodCall(MethodCall call, Result result) { 
   String url = call.argument("url");
   if (call.method.equals("getPlatformVersion")) { 
      result.success("Android " + android.os.Build.VERSION.RELEASE); 
   } 
   else if (call.method.equals("openBrowser")) { 
      openBrowser(call, result, url); 
   } else { 
      result.notImplemented(); 
   } 
}
  • MyBrowserPlugin sınıfında tarayıcıya erişmek için platforma özel openBrowser yöntemini yazın.

private void openBrowser(MethodCall call, Result result, String url) { 
   Activity activity = mRegistrar.activity(); 
   if (activity == null) {
      result.error("ACTIVITY_NOT_AVAILABLE", 
      "Browser cannot be opened without foreground activity", null); 
      return; 
   } 
   Intent intent = new Intent(Intent.ACTION_VIEW); 
   intent.setData(Uri.parse(url)); 
   activity.startActivity(intent); 
   result.success((Object) true); 
}
  • My_browser eklentisinin tam kaynak kodu aşağıdaki gibidir -

my_browser.dart

import 'dart:async'; 
import 'package:flutter/services.dart'; 

class MyBrowser {
   static const MethodChannel _channel = const MethodChannel('my_browser'); 
   static Future<String> get platformVersion async { 
      final String version = await _channel.invokeMethod('getPlatformVersion'); return version; 
   } 
   Future<void> openBrowser(String urlString) async { 
      try {
         final int result = await _channel.invokeMethod(
            'openBrowser', <String, String>{'url': urlString}); 
      } 
      on PlatformException catch (e) { 
         // Unable to open the browser print(e); 
      }
   }
}

MyBrowserPlugin.java

package com.tutorialspoint.flutterplugins.my_browser; 

import io.flutter.plugin.common.MethodCall; 
import io.flutter.plugin.common.MethodChannel; 
import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 
import io.flutter.plugin.common.MethodChannel.Result; 
import io.flutter.plugin.common.PluginRegistry.Registrar; 
import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 

/** MyBrowserPlugin */ 
public class MyBrowserPlugin implements MethodCallHandler {
   private final Registrar mRegistrar; 
   private MyBrowserPlugin(Registrar registrar) { 
      this.mRegistrar = registrar; 
   } 
   /** Plugin registration. */
   public static void registerWith(Registrar registrar) {
      final MethodChannel channel = new MethodChannel(
         registrar.messenger(), "my_browser"); 
      MyBrowserPlugin instance = new MyBrowserPlugin(registrar); 
      channel.setMethodCallHandler(instance); 
   } 
   @Override 
   public void onMethodCall(MethodCall call, Result result) { 
      String url = call.argument("url"); 
      if (call.method.equals("getPlatformVersion")) { 
         result.success("Android " + android.os.Build.VERSION.RELEASE); 
      } 
      else if (call.method.equals("openBrowser")) { 
         openBrowser(call, result, url); 
      } else { 
         result.notImplemented(); 
      } 
   } 
   private void openBrowser(MethodCall call, Result result, String url) { 
      Activity activity = mRegistrar.activity(); 
      if (activity == null) {
         result.error("ACTIVITY_NOT_AVAILABLE",
            "Browser cannot be opened without foreground activity", null); 
         return; 
      }
      Intent intent = new Intent(Intent.ACTION_VIEW); 
      intent.setData(Uri.parse(url)); 
      activity.startActivity(intent); 
      result.success((Object) true); 
   } 
}
  • Yeni oluşturulan eklentimizi test etmek için yeni bir proje, my_browser_plugin_test oluşturun.

  • Pubspec.yaml dosyasını açın ve my_browser'ı eklenti bağımlılığı olarak ayarlayın.

dependencies: 
   flutter: 
      sdk: flutter 
   my_browser: 
      path: ../my_browser
  • Android stüdyosu, pubspec.yaml dosyasının aşağıda verilen Android stüdyo paketi uyarısında gösterildiği gibi güncellendiğini bildirir -

  • Bağımlılıkları al seçeneğini tıklayın. Android stüdyosu paketi İnternet'ten alacak ve uygulama için uygun şekilde yapılandıracaktır.

  • Main.dart'ı açın ve my_browser eklentisini aşağıdaki gibi ekleyin -

import 'package:my_browser/my_browser.dart';
  • My_browser eklentisinden aşağıda gösterildiği gibi openBrowser işlevini çağırın -

onPressed: () => MyBrowser().openBrowser("https://flutter.dev"),
  • Main.dart'ın tam kodu aşağıdaki gibidir -

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

void main() => runApp(MyApp()); 

class MyApp extends StatelessWidget { 
   @override 
   Widget build(BuildContext context) {
      return MaterialApp( 
         title: 'Flutter Demo', 
         theme: ThemeData( 
            primarySwatch: Colors.blue, 
         ), 
         home: MyHomePage(
            title: 'Flutter Demo Home Page'
         ), 
      );,
   }
} 
class MyHomePage extends StatelessWidget { 
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar( 
            title: Text(this.title), 
         ), 
         body: Center(
            child: RaisedButton(
               child: Text('Open Browser'), 
               onPressed: () => MyBrowser().openBrowser("https://flutter.dev"), 
            ),
         ), 
      ); 
   }
}
  • Uygulamayı çalıştırın ve Tarayıcıyı Aç düğmesine tıklayın ve tarayıcının başlatıldığını görün. Aşağıda gösterilen ekran görüntüsünde gösterildiği gibi bir Tarayıcı uygulaması - Ana sayfa görebilirsiniz -

Aşağıda gösterilen ekran görüntüsünde gösterildiği gibi bir Tarayıcı uygulaması - Tarayıcı ekranı görebilirsiniz -

  • Print
  •  Not Ekle
  •  Bu sayfayı işaretle
  •  Hata bildir
  •  Suggestions

Kaydet Kapat