TEZ BİTİRELİM 2 | Login Ekranı ve Ana Ekran

TEZ BİTİRELİM 2 | Login Ekranı ve Ana Ekran

Herkese merhaba.
Uzun süren bir aradan sonra sonunda ikinci yazıyı yazabilecek zamanı bulabildim. Her ne kadar serinin adı Tez Bitirelim olsa da ne yazık ki yeterince verimli değilim ancak yine de elimden geleni en iyi şekilde yapmaya çalışıyorum. Bu içerikte ise bir önceki yazımda bahsettiğim projemin şu ana kadar geldiğim durumundan bahsedeceğim. Dilerseniz lafı çok uzatmadan konumuza geçelim.

Öncelikle oluşturduğum Sign In ve Sign Up ekranlarından bahsetmek istiyorum. Daha önce de söylediğim gibi bu ekranı açık kaynak bir UI projesinden aldım ve şimdilik ufak tefek değişiklikler dışında direkt olarak kullanıyorum. Ancak burada bahsetmek istediğim şey aslında kodları incelerken fark ettiğim şeyler. Bunun için öncelikle bahsi geçen UI tasarımına bakalım isterseniz.

Yukarıdaki görselde de gördüğünüz üzere giriş ekranı iki sekmeden oluşmakta ve sağa sola sürükleme ile sekmeler arasında geçiş yapılmakta. Burada tasarımın kalitesinden ya da UX odaklı bir tasarım olup olmadığından bahsedemeyeceğim zira ben bu konuda (ne yazık ki) yetkin birisi değilim ancak kod tarafından bahsedecek olursam dikkatimi çeken bazı konular var. Öncelikle text fieldlerın kod tarafında nasıl oluşturulduğunu görelim.

TextEditingController loginEmailController = new TextEditingController();
TextEditingController loginPasswordController = new TextEditingController();

child: TextField(
  controller: loginEmailController,
  keyboardType: TextInputType.emailAddress,
  style: TextStyle(
    fontFamily: "WorkSansSemiBold",
    fontSize: 16.0,
    color: Colors.black),
  decoration: InputDecoration(
    icon: Icon(
      FontAwesomeIcons.envelope,
      color: Colors.black,
      size: 22.0,
  ),
  hintText: "Email Address",
  hintStyle: TextStyle(
  fontFamily: "WorkSansSemiBold", fontSize: 17.0),
  ),
)

Gördüğünüz üzere öncelikle bir TextEditingController() nesnesi oluşturuluyor ve bu nesne controller olarak text fielde veriliyor ve bu sayede two way binding sağlanıyor. Aslında bakacak olursanız burada onChanged() eventi de kullanılabilirdi ancak öyle olsaydı tek yönlü bir bind oluşmuş olurdu ve biz text field içindeki texti set etmek istediğimizde tekrardan kod yazmak zorunda kalırdık.

Sonraki satırlara bakacak olursak girilecek inputun tipi için keyboardType değişkenine emailAddress adında ön tanımlı bir değişken set ediyoruz ve artık o text field bir email inputu olarak kullanılabilir hale geliyor. Geri kalan tüm style kodlarını da yine yukarıdan inceleyebilir ve anlayabilirsiniz çünkü gerçekten yeterince anlaşılır. Aslında burada bunları yazarak yazıyı uzatmaya değil Flutter’ın bugüne kadar kullanılmış/kullanılan diğer UI araçlarından ne kadar farklı olduğunu göstermeye çalışıyorum (aslında biraz da yazı uzun olsun istiyorum). Çünkü diğer frameworkler ya da SDK’lar genel geçer yapılar kurup geriye kalan her şeyi bu yapıları kullanarak yapmamızı beklerken Flutter’da aklınıza gelebilecek hemen her şeyin kolay yolu düşünülmüş durumda ve bu gerçekten ciddi bir zaman tasarrufu sağlıyor (en azından ben öyle umuyorum).

Login ekranında yeterince bahsettiğimi düşünerek bir sonraki ekrana, yani alışkanlıkların listeleneceği ve hızlıca tamamlanıp tamamlanmadığı inputunun alınacağı ekrana geçmek istiyorum. Aşağıda bahsettiğim ana ekranın görselini bulabilirsiniz.

Yukarıdaki görselde de göründüğü üzere sol tarafta login olduktan sonraki ilk ekran, sağ tarafta ise sağ alttaki FAB butonuna tıkladıktan sonra yeni bir alışkanlık eklemek için kullanılacak olan popup bulunmakta. Şu anda sol taraftaki alışkanlıklar demo data olarak girilmiş durumda ve bu datalar bir model classı üzerinden sağlanmakta. Aşağıda bahsi geçen model classının içeriğini görebilirsiniz.

class HabitItem {
  String id;
  String name;
  String question;
  ColorEnum color;
  RepeatEnum repeatType;
  DateTime reminderTime;
  bool doneForToday;

  HabitItem(this.name, this.question, this.color, this.repeatType, this.reminderTime, this.doneForToday);
}

Fark ettiğiniz üzere yukarıdaki classta bilinen tipler dışında iki farklı tip var. Bunlar; ColorEnum ve RepeatEnum. Adlarından da anlaşılacağı üzere bu tanımlar enum olarak tanımlılar, ve içlerinde projenin bazı presetlerini barındırıyorlar. Aşağıda bu presetleri görebilirsiniz.

enum ColorEnum {
  red,
  pink,
  purple,
  blue,
  cyan,
  teal,
  green,
  lime,
  amber,
  deepOrange,
  brown,
  grey
}
enum RepeatEnum {
  daily,
  every2Days,
  every3Days,
  every4Days,
  every5Days,
  every6Days,
  every7Days
}

Bu tanımlamaları şimdilik bu şekilde oluşturdum ancak elbette daha sonra duruma göre tanımlamalar değişebilir. Genel yapıyı az buçuk kafanızda oturttuğunuzu düşünüyorum, o yüzden şimdi de sol taraftaki alışkanlık satırlarının dizaynına bakalım isterseniz.

return ListTile(
  title: Text(
    item.name,
    style:
        TextStyle(color: ColorUtils.getPrimaryColor(item.color)),
  ),
  subtitle: Text(item.question,
      style: TextStyle(
          color: ColorUtils.getSecondaryColor(item.color))),
  trailing: IconButton(
    icon: Icon(
      item.doneForToday ? Icons.check : Icons.clear,
      color: item.doneForToday
          ? ColorUtils.getPrimaryColor(item.color)
          : ColorUtils.getSecondaryColor(item.color),
    ),
    onPressed: () {
      Scaffold.of(context).showSnackBar(SnackBar(
        content: Text(item.question),
      ));
    },
  ),
);

Burada kodları anlatmayacağım ancak bahsetmek istediğim önemli bir konu var. Yukarıda gördüğünüz dizayn yapısında hiçbir UI elementi özel bir tasarım aşamasından geçmedi. Yani diğer bir deyişle hiçbir elementi sağa yasla ortala gibi işlemlere tabi tutmadım. Bu yapının tamamı Flutter içerisinde daha önceden tanımlı bir dizayn içerisine oturtuldu ve bu hale geldi. Yani aslında neredeyse tamamen hazır bir tasarımı kullandım diyebilirim. Ve bu da bize Flutter içerisinde ne kadar kolay dizayn yapılabileceğini tekrardan göstermekte.

Son ekran olarak popup tarafı var ancak bu tarafta anlatılacak pek bir şey yok aslında. Zira burası zaten her tasarım dilinde kolayca dizayn edilebilen bir UI olduğu için anlatmaya değer pek bir şey olduğunu düşünmüyorum.

Kısacası Flutter maceram bu şekilde devam etmekte, serinin ikinci yazısında anlatacaklarım bu kadar. Bir önceki yazımın sonunda da söylediğim gibi belirsiz bir zaman sonra görüşmek üzere...