1. Giriş
Materyal Bileşenleri (MDC), geliştiricilerin Materyal Tasarım'ı uygulamasına yardımcı olur. Google'da mühendislerden ve kullanıcı deneyimi tasarımcılarından oluşan bir ekip tarafından oluşturulan MDC, onlarca güzel ve işlevsel kullanıcı arayüzü bileşeni içerir. Ayrıca Android, iOS, web ve Flutter.material.io/develop'da kullanılabilir. |
MDC-101 codelab'inde bir giriş sayfası oluşturmak için iki Materyal Bileşeni kullandınız: metin alanları ve mürekkep dalgalı düğmeler. Şimdi gezinme, yapı ve veri ekleyerek bu temelin kapsamını genişletelim.
Oluşturacaklarınız
Bu codelab'de, giysi ve ev eşyaları satan bir e-ticaret uygulaması olan Shrine adlı uygulama için bir ana ekran oluşturacaksınız. Şunları içerecektir:
- Üst uygulama çubuğu
- Ürünlerle dolu bir tablo listesi
Android | iOS |
Bu codelab'deki Material Flutter bileşenleri ve alt sistemleri
- Üst uygulama çubuğu
- Izgaralar
- Kartlar
Flutter geliştirme ile ilgili deneyim düzeyinizi nasıl değerlendirirsiniz?
2. Flutter geliştirme ortamınızı kurma
Bu laboratuvarı tamamlamak için iki yazılıma ihtiyacınız vardır: Flutter SDK'sı ve düzenleyici.
Codelab'i aşağıdaki cihazlardan birini kullanarak çalıştırabilirsiniz:
- Bilgisayarınıza bağlı ve Geliştirici moduna ayarlanmış fiziksel bir Android veya iOS cihaz.
- iOS simülatörü (Xcode araçlarının yüklenmesini gerektirir).
- Android Emülatör (Android Studio'da kurulum gerektirir).
- Tarayıcı (hata ayıklama için Chrome gereklidir).
- Windows, Linux veya macOS masaüstü uygulaması olarak Uygulamayı dağıtmayı planladığınız platformda gerçekleştirmeniz gerekir. Bu nedenle, bir Windows masaüstü uygulaması geliştirmek istiyorsanız uygun derleme zincirine erişmek için Windows'da geliştirme yapmanız gerekir. İşletim sistemine özgü gereksinimler docs.flutter.dev/desktop sayfasında ayrıntılı olarak açıklanmıştır.
3. codelab başlangıç uygulamasını indirme
MDC-101'den mi devam ediyorsunuz?
MDC-101 kursunu tamamladıysanız kodunuz bu codelab için hazırlanmış olmalıdır. Şu adıma atlayın: Üst uygulama çubuğu ekleme.
Sıfırdan mı başlıyorsunuz?
Codelab başlangıç uygulamasını indirin
Başlangıç uygulaması material-components-flutter-codelabs-102-starter_and_101-complete/mdc_100_series
dizininde bulunur.
...veya GitHub'dan klonlayın
Bu codelab'i GitHub'dan klonlamak için şu komutları çalıştırın:
git clone https://github.com/material-components/material-components-flutter-codelabs.git cd material-components-flutter-codelabs/mdc_100_series git checkout 102-starter_and_101-complete
Projeyi açın ve uygulamayı çalıştırın
- Projeyi istediğiniz düzenleyicide açın.
- "Uygulamayı çalıştırma" talimatlarını izleyin Başlarken: Seçtiğiniz düzenleyici için uygulamayı test edin.
Başarıyla gerçekleştirildi. Cihazınızda MDC-101 codelab'inde bulunan Tapınak giriş sayfası gösterilir.
Android | iOS |
Artık giriş ekranı iyi göründüğüne göre uygulamaya bazı ürünler ekleyelim.
4. Üst uygulama çubuğu ekle
Hemen şimdi "Sonraki"yi tıklarsanız düğmesini tıkladığınızda, ana ekranda "You do it!" (Başardınız!) ifadesini görürsünüz. Harika! Ama artık kullanıcımızın herhangi bir işlem yapması veya uygulamanın hangi noktasında olduğunu bilmesi gerekmiyor. Yardımcı olmak için navigasyon eklemenin zamanı geldi.
Materyal Tasarım, yüksek derecede kullanılabilirlik sağlayan gezinme kalıpları sunar. En görünür bileşenlerden biri üst uygulama çubuğudur.
Gezinme olanağı sunmak ve kullanıcıların diğer işlemlere hızlı erişmesini sağlamak için üst kısımda uygulama çubuğu ekleyelim.
AppBar widget'ı ekleme
home.dart
ürününde, İskeleye bir AppBar ekleyin ve vurgulanan const
işaretini kaldırın:
return const Scaffold(
// TODO: Add app bar (102)
appBar: AppBar(
// TODO: Add buttons and title (102)
),
İskele'nin appBar:
alanına AppBar'ı eklemek, AppBar'ın sayfanın üst kısmında, gövdenin de altında kalmasını sağlayarak bize ücretsiz olarak mükemmel bir düzen sağlar.
Metin widget'ı ekleme
home.dart
uygulamasında AppBar'a başlık ekleyin:
// TODO: Add app bar (102)
appBar: AppBar(
// TODO: Add buttons and title (102)
title: const Text('SHRINE'),
// TODO: Add trailing buttons (102)
Projenizi kaydedin.
Android | iOS |
Birçok uygulama çubuğunda, başlığın yanında bir düğme bulunur. Şimdi uygulamamıza bir menü simgesi ekleyelim.
Başa bir iconButton ekle
home.dart
içindeyken AppBar'ın leading:
alanı için bir iconButton ayarlayın. (Baştan sona doğru sıralamayı taklit etmek için bunu title:
alanının önüne koyun):
// TODO: Add buttons and title (102)
leading: IconButton(
icon: const Icon(
Icons.menu,
semanticLabel: 'menu',
),
onPressed: () {
print('Menu button');
},
),
Projenizi kaydedin.
Android | iOS |
Menü simgesi ("hamburger" olarak da bilinir), tam da beklediğiniz yerde görünür.
Başlığın son tarafına da düğmeler ekleyebilirsiniz. Flutter'da bunlara "eylemler" adı verilir.
İşlem ekleme
İki iconButtons için daha yer var.
Bunları başlıktan sonra AppBar örneğine ekleyin:
// TODO: Add trailing buttons (102)
actions: <Widget>[
IconButton(
icon: const Icon(
Icons.search,
semanticLabel: 'search',
),
onPressed: () {
print('Search button');
},
),
IconButton(
icon: const Icon(
Icons.tune,
semanticLabel: 'filter',
),
onPressed: () {
print('Filter button');
},
),
],
Projenizi kaydedin. Ana ekranınız şu şekilde görünmelidir:
Android | iOS |
Artık uygulamanın başında bir düğme, başlık ve sağ tarafta iki işlem var. Uygulama çubuğu, içerikten farklı bir katmanda olduğunu gösteren hafif bir gölge kullanarak yüksekliği de gösterir.
5. Izgaraya kart ekleme
Artık uygulamamızın bir yapısı var. Şimdi içerikleri kartlara yerleştirerek düzenleyelim.
GridView ekleme
Üst uygulama çubuğunun altına bir kart ekleyerek başlayalım. Card widget'ı tek başına yeterli bilgiye sahip olmadığı için onu bir GridView widget'ında göstermek istiyoruz.
Yapı İskelesinin gövdesindeki Merkezi bir GridView ile değiştirin:
// TODO: Add a grid view (102)
body: GridView.count(
crossAxisCount: 2,
padding: const EdgeInsets.all(16.0),
childAspectRatio: 8.0 / 9.0,
// TODO: Build a grid of cards (102)
children: <Widget>[Card()],
),
Kodu açalım. Gösterdiği öğelerin sayısı sonsuz değil, sayılabilir olduğundan GridView count()
oluşturucusunu çağırır. Ancak düzenini tanımlamak için daha fazla bilgiye ihtiyacı vardır.
crossAxisCount:
, sitede kaç öğe olduğunu belirtir. 2 sütun istiyoruz.
padding:
alanı, GridView'un 4 tarafında da alan sağlar. Elbette, henüz yanlarında GridView alt öğesi olmadığından sondaki veya alt kenarlardaki dolguyu göremezsiniz.
childAspectRatio:
alanı, öğelerin boyutunu en boy oranına (genişlik-yükseklik) göre tanımlar.
Varsayılan olarak GridView, aynı boyutta bloklar oluşturur.
Bir kartımız var ama o kart boş. Kartımıza alt widget'ları ekleyelim.
İçerikleri düzenleme
Kartlarda resim, başlık ve ikincil metin için bölgeler bulunmalıdır.
GridView'un alt öğelerini güncelleyin:
// TODO: Build a grid of cards (102)
children: <Widget>[
Card(
clipBehavior: Clip.antiAlias,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
AspectRatio(
aspectRatio: 18.0 / 11.0,
child: Image.asset('assets/diamond.png'),
),
Padding(
padding: const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('Title'),
const SizedBox(height: 8.0),
Text('Secondary Text'),
],
),
),
],
),
)
],
Bu kod, alt widget'ları dikey olarak yerleştirmek için kullanılan bir Sütun widget'ı ekler.
crossAxisAlignment: field
, "metni ön kenara hizala" anlamına gelen CrossAxisAlignment.start
değerini belirtir.
AspectRatio widget'ı, sağlanan resmin türünden bağımsız olarak resmin hangi şekle sahip olacağını belirler.
Dolgu, metni kenardan biraz daha içe aktarır.
İki Text widget'ı, aralarında 8 nokta boşluk olacak şekilde dikey olarak üst üste dizilmiştir (SizedBox). Bunları Dolgu'nun içinde barındırmak için başka bir Sütun oluştururuz.
Projenizi kaydedin.
Android | iOS |
Bu önizlemede, kartın yuvarlatılmış köşeleri ve bir gölge (kartın yüksekliğini ifade eden) ile kenardan içe yerleştirildiğini görebilirsiniz. Şeklin tamamına "kapsayıcı" adı verilir Materyal. (Kapsayıcı adlı gerçek widget sınıfıyla karıştırılmamalıdır.)
Kartlar genellikle diğer kartlarla birlikte bir koleksiyonda gösterilir. Şimdi, bunları bir koleksiyon halinde bir ızgara üzerine yerleştirelim.
6. Kart koleksiyonu oluşturma
Bir ekranda birden fazla kart olduğunda, bunlar bir veya daha fazla koleksiyonda gruplanır. Bir koleksiyondaki kartlar aynı düzlemde yer alır, yani kartların alınma veya sürüklenmedikleri sürece aynı dinlenme yüksekliğine sahiptirler, ancak burada bunu yapmayacağız.
Kartı bir koleksiyon halinde çoğaltın
Şu anda Kartımız GridView'un children:
alanında satır içinde oluşturuluyor. Bu iç içe yerleştirilmiş çok fazla sayıda kod olduğu için okunması zor olabilir. Bunu, istediğimiz sayıda boş kart oluşturabilen ve Kartlar listesi döndüren bir işleve çıkaralım.
build()
işlevinin üzerinde yeni bir gizli işlev oluşturun (Alt çizgiyle başlayan işlevlerin gizli API olduğunu unutmayın):
// TODO: Make a collection of cards (102)
List<Card> _buildGridCards(int count) {
List<Card> cards = List.generate(
count,
(int index) {
return Card(
clipBehavior: Clip.antiAlias,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
AspectRatio(
aspectRatio: 18.0 / 11.0,
child: Image.asset('assets/diamond.png'),
),
Padding(
padding: const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const <Widget>[
Text('Title'),
SizedBox(height: 8.0),
Text('Secondary Text'),
],
),
),
],
),
);
},
);
return cards;
}
Oluşturulan kartları GridView'un children
alanına atayın. GridView'da yer alan her şeyi bu yeni kodla değiştirmeyi unutmayın:
// TODO: Add a grid view (102)
body: GridView.count(
crossAxisCount: 2,
padding: const EdgeInsets.all(16.0),
childAspectRatio: 8.0 / 9.0,
children: _buildGridCards(10) // Replace
),
Projenizi kaydedin.
Android | iOS |
Kartlar gösteriliyor ancak henüz hiçbir şey gösterilmiyor. Şimdi ürün verilerini ekleme zamanı geldi.
Ürün verileri ekleme
Uygulamada resimler, adlar ve fiyatlar içeren bazı ürünler var. Bunu kartta bulunan widget'lara ekleyelim.
Ardından home.dart
aracında, yeni bir paketi ve bir veri modeli için sağladığımız bazı dosyaları içe aktarın:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'model/product.dart';
import 'model/products_repository.dart';
Son olarak, ürün bilgilerini getirmek için _buildGridCards()
değerini değiştirin ve bu verileri kartlarda kullanın:
// TODO: Make a collection of cards (102)
// Replace this entire method
List<Card> _buildGridCards(BuildContext context) {
List<Product> products = ProductsRepository.loadProducts(Category.all);
if (products.isEmpty) {
return const <Card>[];
}
final ThemeData theme = Theme.of(context);
final NumberFormat formatter = NumberFormat.simpleCurrency(
locale: Localizations.localeOf(context).toString());
return products.map((product) {
return Card(
clipBehavior: Clip.antiAlias,
// TODO: Adjust card heights (103)
child: Column(
// TODO: Center items on the card (103)
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
AspectRatio(
aspectRatio: 18 / 11,
child: Image.asset(
product.assetName,
package: product.assetPackage,
// TODO: Adjust the box size (102)
),
),
Expanded(
child: Padding(
padding: const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0),
child: Column(
// TODO: Align labels to the bottom and center (103)
crossAxisAlignment: CrossAxisAlignment.start,
// TODO: Change innermost Column (103)
children: <Widget>[
// TODO: Handle overflowing labels (103)
Text(
product.name,
style: theme.textTheme.titleLarge,
maxLines: 1,
),
const SizedBox(height: 8.0),
Text(
formatter.format(product.price),
style: theme.textTheme.titleSmall,
),
],
),
),
),
],
),
);
}).toList();
}
NOT: Henüz derleme ve çalıştırılamaz. Bir değişikliğimiz daha var.
Ayrıca, derlemeyi denemeden önce build()
işlevini, BuildContext değerini _buildGridCards()
olarak iletecek şekilde değiştirin:
// TODO: Add a grid view (102)
body: GridView.count(
crossAxisCount: 2,
padding: const EdgeInsets.all(16.0),
childAspectRatio: 8.0 / 9.0,
children: _buildGridCards(context) // Changed code
),
Uygulamayı çalışırken yeniden başlatın.
Android | iOS |
Kartlar arasına dikey boşluk eklemediğimizi fark edebilirsiniz. Bunun nedeni, reklamların üst ve alt kısımlarında varsayılan olarak 4 kenar boşluğunun olmasıdır.
Projenizi kaydedin.
Ürün verileri gösteriliyor ancak resimlerin etrafında fazladan boşluk var. Resimler varsayılan olarak .scaleDown
değerine sahip bir BoxFit ile çizilir (bu örnekte). Bunu biraz yakınlaştırması ve fazla boşlukları kaldırması için .fitWidth
olarak değiştirelim.
Resme BoxFit.fitWidth
değerine sahip bir fit:
alanı ekleyin:
// TODO: Adjust the box size (102)
fit: BoxFit.fitWidth,
Android | iOS |
Ürünlerimiz artık uygulamada mükemmel bir şekilde görünüyor.
7. Tebrikler!
Uygulamamız, kullanıcıyı giriş ekranından ürünlerin görüntülenebileceği bir ana ekrana yönlendiren temel bir akışa sahip. Sadece birkaç satır kodla üst uygulama çubuğu (bir başlık ve üç düğmeli) ve kartlar (uygulamamızın içeriğini sunmak için) ekledik. Artık basit ve işlevsel olan ana ekranımız, temel bir yapı ve üzerinde işlem yapılabilir içerik içeriyor.
Sonraki adımlar
Üst uygulama çubuğu, kart, metin alanı ve düğmeyle birlikte Material Flutter kitaplığından dört temel bileşeni kullanıyoruz. Malzeme bileşenleri widget kataloğunu ziyaret ederek daha fazlasını keşfedebilirsiniz.
Uygulamamız tam olarak işlevsel olsa da henüz belirli bir markayı veya bakış açısını yansıtmıyor. MDC-103: Renk, Şekil, Yükseklik ve Tür ile Materyal Tasarım Teması bölümünde canlı ve modern bir markayı ifade etmek için bu bileşenlerin stilini özelleştireceğiz.