Android | Epoxy Kullanarak Karmaşık Arayüzler Tasarlamak

Modern, modüler, esnek ve dinamik arayüzleri nasıl tasarlayabiliriz?

Gökhan Öncü
mobilist_labs
4 min readNov 15, 2020

--

Mobil uygulama geliştirenler bilir doğru bileşeni doğru zamanda ve doğru şekilde kullanmak, mobil yazılım geliştirme sürecinin en önemli ve de en çok tecrübe gerektiren konularının başında gelir. RecylerView de Android geliştirenler için çok dikkatli kullanılması gereken, bir arayüz bileşenidir. Neredeyse kaydırılabilir her ekranda onu kullanıyoruz.

Bazı durumlarda farklı tip verileri farklı görünümlerde ekranda göstermek durumunda kalabiliyoruz, bu senaryoya sayfalama gibi özelliklerin de dahil olduğunu düşünürsek RecyclerView kullanmak “karmaşık ve hataya açık” hale gelebiliyor.

Bir haber detay sayfası düşünelim, bu ekranda “Başlık, alt başlık, kapak görseli, haber metni, ilgili haberler, interaktif reklamlar” gibi bir çok farklı tipte veriyi farklı şekillerde göstermemiz gerekiyor. Android ekibinizin de aynı ekranda çalışacağını düşünürsek, ekip için işler biraz zorlaşacaktır. Benzer bir senaryoya bu blog yazısından göz atabilirsiniz.

Bu yazıda bu tarz karmaşık ekranları geliştirmeyi basitleştiren, Airbnb Epoxy’nin temellerini ve çalıştığım projelerde hangi alanlarda kolaylık sağladığına dair önemli noktalara değineceğiz.

Epoxy Nedir

Epoxy, Airbnb tarafından karmaşık ekranlar için tasarlanmış bir arayüz Mimarisidir. RecylerView ile çalışırken karmaşık arayüzler geliştirmeyi basitleştirir ve hızlandırır. Epoxy hakkında daha genel bir bakış açısına sahip olabilmek adına Airbnb mühendislerinin yazdığı aşağıdaki yazıya ve şu videoya göz atmanızı tavsiye ederim.

Harika, ama bunu nasıl yapıyor?

Bildiğimiz gibi RecylerView 3 nesneye ihtiyaç duyar:

  1. RecylerView Nesnesi — Bu, genel bir kapsayıcıdır. Ekranda göstereceğimiz öğelerin yerleşimini yapacağımız Layout Manager ve bu öğelere verilerin aktarılmasını sağlayan Adapter hakkında bilgiler içerir. Bu kısım Epoxy’den az ya da çok etkilenmez, eskisi gibi aynı şekilde ele alınabilir.
  2. Recycler.ViewHolder — Bu, RecyclerView içerisinde tek bir öğeyi görüntülemekten sorumlu nesnedir. Elimizdeki veriler için Re-usable öğeler oluşturur ve içlerine verilerin gösterilmesini sağlar. Burası Epoxy’nin büyük ölçüde basitleştirdiği ve tüm bu soyutlamaları ele aldığı yerdir. EpoxyModel olarak işleyeceğiz.
  3. RecyclerView.Adapter — Bu, gerektiği kadar ViewHolder oluşturur ve View Injection işlemi yapar. Burası Epoxy’nin işimizi en çok kolaylaştırdığı ve farklı tipteki öğeleri komponent şeklinde kullanabilmeyi sağladığı yerdir. Epoxy Controllers olarak işleyeceğiz.

Epoxy arayüz mimarisi temelinde RecyclerView nesnelerinin son ikisine odaklanır, bunları kendi soyutlamalarıyla işler.

  1. Epoxy Models — Bu, RecyclerView.ViewHolder nesnesini oluşturan bir model sınıfıdır. RecyclerView içerisinde gösterilecek tek bir ögenin arayüzde nasıl görüntüleneceğini, içerisine verilerin bağlanmasını gibi konuları kontrol eder. Kendi oluşturduğumuz layout’ları bu modellere bağlayabildiğimiz gibi Custom View’larda tasarlayabiliriz.
  2. Epoxy Controllers — Bu, RecyclerView’da gösterilecek tüm modellerin kontrol edilmesini sağlar. Epoxy Annotation Processing kullanır, evet bunun build süresini arttıran bir durum olduğunu biliyorum, farklı bir yaklaşıma geçene kadar buna değeceğini düşünüyorum.

Epoxy modellerinizi ve kontrollerinizi yazdınız, Build düğmesine basıp, projeyi derlediniz. Arka planda olanlar kabaca şu şekilde:

Derleyici, Epoxy’nin annotation processor’unun process() metodunu çağırır. Bu metod içinde, projenizdeki tüm Java sınıflarınız taranır ve Epoxy annotation’ları nerelerde kullanılmış, tespit edilir. Annotation kullanılmış bir sınıf bulunduğu zaman, yeni bir Java dosyası üretilir. Bu yeni sınıf içindeki annotation’lar, bizim bildiğimiz eski stil kodlarla yer değiştirilir. Kısacası Epoxy Model’ler ViewHolder’lara, EpoxyController’lar Adapter’lara dönüştürülüp projeye eklenir. Son olarak da Epoxy tarafından üretilen tüm Java sınıfları çağırılır ve bu dosyalar derlenmeye başlanır.

Hadi biraz örnek yapalım

Banabi, Getir, Trendyol, Bisu gibi online market platformlarının uygulamasını tasarladığımızı düşünelim. Bu uygulamaların genel yapısına baktığımızda farklı tiplerde ürünlere sahip olduğunu ve bunları kullanıcılarına farklı şekillerde ve ekranlarda gösterdiklerini görebiliriz.

Bu ölçekte bir uygulama üzerinde çalışıyorsak arayüz mimarimizi bu karmaşık yapılara çözüm oluşturabilecek şekilde tasarlamalıyız. Yukarıda resimde görüldüğü gibi bütün ekranlarımızda kullanacağımız arayüz bileşenlerini birer komponent’e çevirerek başlayabiliriz. Böyleyece “re-usable” bileşenlerle çalışmak kodun minimum seviyelerde ve esnek kalmasını sağlayacaktır.

Yukarıdaki arayüz için 4 farklı tipte bileşene ihtiyacımız olduğunu görüyoruz:

1- (PromotedFood Model) Öne çıkarılmış ürünleri listelediğimiz, yatayda kayabilir “Carousel” tipinde bir liste için tekil bir bileşen.

2-(Header Model) Gruplara ayrılmış alanların grup sınırlarını belirlemek için kullanacağımız başlık bileşeni.

3-(Category Model) Ürün kategorilerini listelediğimiz, “Carousel” tipinde bir liste için tekil bir bileşen.

4-(PopularPlace Model) En çok satılan ürünleri listelediğimiz, liste için tekil bir bileşen.

Epoxy Model’lerimizi oluşturalım 🛠

HeaderItemModel.kt
CategoryItemModel.kt
FoodItemModel.kt

Epoxy kullanımı gereği bizi bazı kalıpların içerisine alıyor, bu durum size rahatsız edici gelebilir tabi ki ama artılarını düşündüğümüz zaman göz ardı edilebilir diye düşünüyorum.

Epoxy Controller’ımızı oluşturalım 🛠

HomeController.kt

Controller yapısını incelediğimizde bütün modellerimizi birer komponent olarak kullanabildiğimizi görmekteyiz. Epoxy’nin Annotation Processing kullandığından bahsetmiştik. Model kullanımıda Carousel içerisinde görebilirsiniz.

Epoxy kendi içerisinde ön-tanımlı bazı arayüz bileşenleri ile gelmekte. Bunlardan belki en önemlisi “carousel” bileşenidir. Dikey bir listenin içerisinde yatayda bir listeleme yapmak istediğimizde “tak-çalıştır” gibi bir kullanım ile içerisine yatayda listelemek istediğimiz veri için Epoxy Model’leri oluşturup vermemiz yeterli.

Gördüğünüz gibi tüm modeller birbirinden bağımsız çalışmakta ve karmaşık bir ekranın yapı taşlarını oluşturmaktadır. Ayrı modellere sahip olmak, paralel olarak çalışabilmemize ve kullanıcı arayüzünü bloklar halinde oluşturmamıza yardımcı olmaktadır. Bununla birlikte gerektiğinde gerekli parçaya güncelleme yapmayı kolaylaştırarak bakımı daha az eforla yapmamızı sağlamaktadır.

Üstteki resimde görüldüğü gibi, bileşenlerimiz birbirinden bağımsız olduğu için farklı bileşenleri farklı grupların içerisinde rahatlıkla kullanıp, esnek bir şekilde dinamik arayüzler oluşturabiliyoruz.

Sonuç

Epoxy, Jetpack Compose gibi gelişmekte olan arayüz mimarilerinin bir bütünü küçük parçalara ayırarak yönetmelerini gün geçtikçe benimsiyor olacağımızı düşünüyorum. Umarım Epoxy’nin neye benzediği hakkında bir fikir sahibi olmanıza yardımcı olmuşumdur.

--

--