React Native Instagram — Story Listesi

Zafer Ayan
4 min readJan 25, 2020

--

Aslen 8 yazılık bu serinin diğer yazılarına aşağıdaki linklerden ulaşabilirsiniz:

  1. Proje mimarisi
  2. Projenin oluşturulması ve React Native Navigation
  3. BottomBar’ın oluşturulması
  4. FlatList kullanımı (Post’ların görüntülenmesi)
  5. Story Listesi
  6. RNCamera kullanımı
  7. React Navigation Drawer kullanımı
  8. Redux kullanımı

Önceki yazımda Post bileşenini kodlamıştık. Şimdi bu yazıda story kısmını kodlayabiliriz. Projede kaldığımız yerden devam etmek için aşağıdaki 3-adding-post-component branch’ine gidebilirsiniz:

Öncelikle HomeScreen.js içerisinde aşağıdaki gibi story özelliklerini barındıran bir stories dizisi oluşturalım:

Story’lerin görüntülenmesi için FlatList’in ListHeaderComponent özelliğini kullanabiliriz. ListHeaderComponent, aynı bir appBar gibi liste için bir başlık eklemeye yarıyor. Searchbar gibi elementler yapmak istediğinizde de kullanabilirsiniz:

Burada ek olarak story’e tıklanıldığında bir ekran açılmasını istiyoruz. O event’i burada oluşturalım ve child bileşenlere aktaralım. Daha sonra story fotoğrafını görüntüleyecek olan StoryScreen’i oluşturacağız.

Şimdi ListHeaderComponent’in render edeceği StoryContainer bileşenini yapalım. home dizini içerisinde story adında yeni bir dizin oluşturalım ve içerisine StoryContainer.js dosyasını ekleyelim:

Kodu açıklayacak olursak <React.Fragment> ekstra bir view bileşeni oluşturmadan iki bileşeni sarmalamaya yarıyor. FlatList’in horizontal=true özelliği ile yatay olarak scroll’lanabilir bir liste oluşturuyoruz. styles.seperator olan view bileşeni ise ince gri bir çizgi yardımıyla story’ler ve post’lar arasında bir ayrım yapmayı sağlıyor. StoryListItem ile hem kullanıcı fotoğrafı hem de altında kullanıcı adını ekrana basacağız. Bunun için story dizini altında StoryListItem.js oluşturalım ve aşağıdaki gibi dolduralım:

Buradaki kodda yer alan ProfilePicture bileşeni ile yuvarlak bir profil fotoğrafı ve çevresinde gradient’li bir halka görüntülemiş olacağız. Profil fotoğrafı, uygulamanın her yerinde paylaşımlı olarak kullanılabileceği için bunu components dizini altında oluşturmakta fayda var. src/components dizinini oluşturalım ve container dizini altındaki package.json dosyasını kopyalayıp bu dizin içerisine yapıştırmak suretiyle name kısmına “components” yazalım ve bir modül haline getirelim.

Öncelikle profil fotoğrafının etrafında gradient’li bir halka olacağı için react-native-linear-gradient kütüphanesini eklememiz ve sonrasında pod’u yüklememiz gerekiyor:

npm i react-native-linear-gradient --save
cd ios
pod install
cd ..

Linear Gradient kütüphanesi de indiğine göre artık ProfilePicture.js dosyasını oluşturabiliriz:

Buradaki kodu açıklayacak olursak, const params değişkeninde yer alan size ile ProfileImage component’inin büyüklüğünü belirliyoruz. Eğer props’tan bu değer gelmediyse, varsayılan olarak ana ekranda story listesinde kullanacağımız 64 değerini atayacağız. Diğer değişkenler de bu size değeri sayesinde responsive bir arayüz oluşturmak için kullanacaklar:

Story görseli için stil değerlerinin hesaplanabilir olması sayesinde, size değişkenini sırasıyla 64px ve 200px atayarak story profil fotoğrafları responsive hale gelebiliyor. Not: Tüm özelliklerin bir arada görüntülenebilmesi için kodu harici olarak değiştirerek bu görseli oluşturdum.

borderSize kısmındaki hesaplama ise story’si olan profil fotoğraflarının etrafında yer alan renkli halkanın boyutunu veriyor. Örneğin size 64 olsun, bu durumda borderSize 64*6/100 = 3.84 çıkacaktır. Yani 3–4 piksellik bir incelikte halka oluşturulacaktır. innerBorderSize ise, halka ile profil fotoğrafı arasında kalan siyah boşluk için kullanılacak. innerCircleSize ise profil fotoğrafının boyutunu hesaplayacak, profileImgBorderSize ise profil fotoğrafı için bir border ekleyecektir. notification ile ilgili kısımlar ise bildirimler ekranı için kullanılacak. Kırmızı renkte bir daire ve bu dairenin nerede duracağı ile ilgili hesaplamalar var. insertStory ile başlayan değerler ise, mevcut kullanıcının bir story’si yoksa + işaretli mavi renkte daire eklemek için kullanılacak.

return kısmında yer alan LinearGradient bileşeni renkli halkayı oluşturmayı sağlıyor. Eğer story yoksa colors.background yani siyah renkte oluşturulacak ki bu durum ilgili kullanıcının story’sinin bulunmaması demektir. start ve end değerleri gradient’in nerede başlayıp nerede biteceğini, useAngle ve angle parametreleri ise gradient’in açısını belirtecektir. style kısmında yer alan styles(params).storyRing ise halkanın görünümünü belirleyecektir. Profil fotoğrafının büyüklüğünü parametrik olarak atamak için styles() adında bir fonksiyon oluşturup, stilleri dinamik olarak kullandım.

Projeyi çalıştırdığınızda aşağıdaki gibi bir ekranla karşılacaşaksınız:

Listedeki story’e tıkladığımızda aşağıdaki gibi bir hata verecektir:

Error: There is no route defined for key Story.
Must be one of: ‘Home’

Story için herhangi bir route tanımlanmadığını söylüyor. Çünkü zaten bir story ekranımız yok. Bunun için story dizininde StoryScreen.js dosyasını oluşturalım:

Şimdi HomeNavigator.js içerisinde bu ekranı route olarak gösterelim:

Profil fotoğraflarından birine tıklandığında aşağıdaki gibi bir story ekranı ortaya çıkacaktır.

Bu story ekranının aynı instagram’daki gibi olması için çeşitli çalışmalar yapılabilir. Buradaki youtube videosundan benzer bir çalışmanın nasıl kodlandığına bakabilirsiniz. Zaman almaması ve sade olması açısından şimdilik bu kadarı yeterli olacaktır.

Projenin son halini 4-adding-story-list branch’ine giderek edinebilirsiniz.

git checkout 4-adding-story-list

Sonuç olarak

React Native’de ListHeaderComponent özelliği sayesinde story’leri yatay olarak listelemiş olduk. Ayrıca LinearGradient sayesinde story profil fotoğrafına renkli bir halka ekledik. Bu da yetmedi profil fotoğrafını parametrik hale getirerek, her yerde çalışabilecek responsive bir component oluşturduk :)

Sonraki yazımda Story eklemek için RNCamera bileşeninin nasıl kullanılacağına değineceğim. Soru ve görüşlerinizi aşağıdaki yorum kısmından belirtebilirsiniz. Sonraki yazı >

--

--

No responses yet