Jetpack Compose’ da CompositionLocal Kullanımı: Bileşenler Arası Veri Paylaşımı (Provider Pattern)

Kerim Bora
Appcent
Published in
5 min readSep 11, 2023

Geliştirici dünyası sürekli olarak gelişiyor ve Jetpack Compose, Android uygulama geliştirmenin yeni bir yolu olarak ön plana çıkıyor. Bu makalede, Jetpack Compose’ un güçlü bir özelliği olan CompositionLocal`ı ele alacağız ve bu özelliği kullanarak uygulamanızdaki verileri, bileşenler(component) arası nasıl paylaşabileceğinizi öğreneceksiniz.

CompositionLocal Nedir?

CompositionLocal, bileşenler arasında veri ve davranış paylaşımını mümkün kılarak geliştiricilere güçlü bir araç sunar. Bu bölümde, CompositionLocal’ı daha yakından tanıyacak ve neden bu kadar önemli olduğunu anlayacaksınız. CompositionLocal’ın temel işlevselliğini ve nasıl kullanıldığını öğrenerek, Jetpack Compose uygulamalarınızda daha dinamik ve esnek bir yapı oluşturmanızı sağlayacak bir araca sahip olacaksınız.

CompositionLocal Nasıl Çalışır?

CompositionLocal, aynı kompozisyon ağacı(component tree) içinde yer alan bileşenler arasında veriyi(state) geçirmek için kullanılır. Bu, verilerin hiyerarşik bir şekilde iletilmesini sağlar, böylece üst seviye bir bileşenden başlayarak alt seviyedeki bileşenlere kadar ulaşabilirsiniz. Bu, verilerin otomatik olarak güncellendiği ve senkronize olduğu anlamına gelir.

with-out CompositionLocal
with-out CompositionLocal

Yukarıda verilen görselde kompozisyon ağacında Composable A’dan diğer sayfalara bir veri(state) paylaşımı verilmiştir. Ancak bu yöntem, veri paylaşımını kontrolsüz hale getirerek uygulama mimarisi açısından risklidir ve tavsiye edilmez.

CompositionLocal kullanmadan, uygulamanızın farklı bileşenleri arasında veri iletmek için alternatif yöntemler kullanmanız gerekebilir. Bu alternatifler, kodunuzu karmaşıklaştırabilir ve bakımını zorlaştırabilir.

CompositionLocal kullanmadığınızda, her bileşenin kendi verilerini doğrudan yönetmesi gerekebilir. Bu, kodun tekrarlanmasına ve daha fazla karmaşıklığa yol açabilir.

with CompositionLocal

CompositionLocal kullanılarak, veri paylaşımı belirli bir bileşen hiyerarşisi içinde sınırlanabilir ve daha öngörülebilir hale getirilebilir. Bu, uygulamanızın farklı bileşenleri arasında verinin ne zaman ve nasıl iletilmesi gerektiğini daha iyi kontrol etmenizi sağlar.

CompositionLocal Oluşturmak

Örnek olarak, giriş yapmış bir kullanıcının verilerine uygulamanın çeşitli köşelerinden erişmek isteyebiliriz. Bu noktalar, kullanıcının profil sayfası, ana sayfa, profil fotoğrafı ve daha fazlası gibi bileşenler olabilir.

İlk adım olarak, giriş yapmış bir kullanıcının verilerini uygulamanın her köşesinden kolayca erişilebilir kılmak için bir kullanıcı nesnesini içeren bir CompositionLocal oluşturmayı düşünelim.

data class User(
val name: String,
val email: String,
val age: Int
)
val LocalCurrentUser = compositionLocalOf<User> {
error("No user found!") // Varsayılan değer veya hata mesajı
}

compositionLocalOf<T> Jetpack Compose kütüphanesinde kullanılan bir işlevdir ve bir CompositionLocal oluşturmak için kullanılır.

  • CompositionLocalProvider kullanımı: Değer sağlamak için CompositionLocalProvider bileşenini kullanmalısınız. Bu bileşen, CompositionLocal'ın altındaki bileşenlere bir değeri iletmek için kullanılır.
  • Değer sağlama: CompositionLocalProvider içinde CompositionLocal'a bir değer sağlamanız gerekir. Bu, CompositionLocal<T> provides T söz dizimini(syntax) kullanarak yapılır. Burada T, CompositionLocal'ın türünü temsil eder ve bu türde bir değer sağlamanız gerekir.

Örnek bir kod parçası ile bu adımı açıklayalım:


fun fetchCurrentUser(): User {
return User(
"Kerim",
"dev.kerimbora@gmail.com",
23
)
}

@Composable
private fun LoginScreen() {

...

CompositionLocalProvider(
LocalCurrentUser provides fetchCurrentUser()
) {
// CompositionLocal'a değer sağladık ve bu değeri altındaki bileşenlere iletebiliriz.
HomePage()
}

}

Yukarıdaki örnek, LocalCurrentUser CompositionLocal'ına bir kullanıcı değeri sağlar ve bu değeri HomePage() bileşenine ileterek alt bileşenlerde kullanılabilir hale getirir. Bu sayede CompositionLocal, veri paylaşımını kontrol altında tutmanıza ve veriyi farklı yerlerde kullanmanıza olanak tanır.

CompositionLocal Değerini Kullanma

CompositionLocal’da sağlanan değeri kullanmak için CompositionLocal’ın current özelliğini kullanırsınız. Bu özellik, CompositionLocal'ın içindeki mevcut değeri temsil eder. İşte bu adımın daha ayrıntılı açıklaması:

  • CompositionLocal değerine erişim: CompositionLocal’ın içindeki mevcut değere erişmek için CompositionLocal<T>.current sözdizimini kullanabilirsiniz. Burada T, CompositionLocal'ın içindeki verinin türünü temsil eder.

Örnek bir kod parçası ile bu adımı açıklayalım:

@Composable
fun ProfilePage() {

// CompositionLocal'daki mevcut kullanıcı değerine erişim
val currentUser: User = LocalCurrentUser.current

// Kullanıcı verilerini görüntüleme
Column {
Text("Name: " + currentUser.name)
Text("Email: " + currentUser.email)
Text("Age: " + currentUser.age)
}
}

Yukarıdaki örnek, CompositionLocal’daki mevcut kullanıcı değerini LocalCurrentUser.current kullanarak alır ve bu değeri daha sonra kullanarak kullanıcı verilerini görüntüler.

Bu adımda, CompositionLocal ile sağlanan veriyi herhangi bir @Composable içinde kullanabilir ve görüntüleyebilirsiniz. Bu, farklı bileşenler arasında veri paylaşımını kolaylaştırır ve uygulamanızın farklı parçaları arasında veri akışını sağlar.

Jetpack Compose’ da Ön tanımlı CompositionLocal’lar

Jetpack Compose, uygulamanın UI’ nı oluşturmak için kullanılan bir kompozisyon tabanlı UI framework’üdür. Compose, verileri composable’lar arasında geçirmek için çeşitli yöntemler sunar. Bu yöntemlerden biri de CompositionLocal’lardır.

CompositionLocal’lar, belirli bir aralıkta erişilebilen yerel değişkenlerdir. Bir CompositionLocal, bir composable’da oluşturulur ve bir CompositionLocalProvider ile sağlanır. Bu sağlayıcı, CompositionLocal’ın değerini diğer composable’lara sağlar.

Jetpack Compose, çeşitli öntanımlı CompositionLocal’lar sunar. Bu CompositionLocal’lar, uygulamanın UI’sını oluşturmak için yaygın olarak kullanılan verileri tutar. Örneğin, aşağıdakiler Jetpack Compose tarafından sağlanan öntanımlı CompositionLocal’lardır:

  • LocalDensity: Bu CompositionLocal, uygulamanın yoğunluğunu tutar.
  • LocalConfiguration: Bu CompositionLocal, uygulamanın yapılandırmasını tutar.
  • LocalLocale: Bu CompositionLocal, uygulamanın yerel ayarlarını tutar.
  • LocalTimeSource: Bu CompositionLocal, uygulamanın zaman kaynağını tutar.
  • LocalContext: Uygulamanın yerel bağlamını(context) tutar.
  • LocalClipboardManager: Uygulamanın panosunu tutar.

Ön tanımlı CompositionLocal’lar hakkında örnekleri inceleyelim:

  • LocalConfiguration: Bu CompositionLocal, uygulamanın yapılandırmasını tutar. Bu, bir composable’ın uygulamanın yönüne veya UI moduna göre davranışını değiştirmek için kullanılabilir.
// Ön tanımlı CompositionLocal (LocalConfiguration)
val configuration = LocalConfiguration.current

when (configuration.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
Text("Landscape")
}
else -> {
Text("Portrait")
}
}
  • LocalDensity: Bu CompositionLocal, uygulamanın yoğunluğunu(DPI) tutar. Bu, bir composable’ın boyutlarını dinamik olarak ayarlamak için kullanılabilir. Örneğin, aşağıdaki kod, bir metin bileşeninin boyutunu uygulamanın yoğunluğuna göre ayarlar:
@Composable
fun TextWithDensity() {
val density = LocalDensity.current
Text(
text = "Hello, world!",
fontSize = 16.dp * density
)
}
  • LocalContext: Bu CompositionLocal, uygulamanın yerel bağlamını(context) tutar. Bu, bir composable’ın uygulamanın depolama alanına, sistem servislerine veya diğer kaynaklara erişmek için kullanılabilir. Örneğin, aşağıdaki kod, uygulamanın depolama alanından bir dosya okur:
@Composable
fun ReadFile() {
val context = LocalContext.current
val file = File(context.filesDir, "my_file.txt")
val content = file.readText()
Text(
text = content,
)
}

Sonuç

Jetpack Compose, Android uygulama geliştirme dünyasına yeni bir yaklaşım sunuyor ve CompositionLocal gibi güçlü özelliklerle bu yaklaşım daha da etkili hale geliyor. Bu makalede, CompositionLocal’ı ele aldık ve bu özelliği kullanarak uygulamalarınızda bileşenler arasında veri paylaşımını nasıl gerçekleştirebileceğinizi öğrendiniz.

CompositionLocal, verilerinizi hiyerarşik bir yapı içinde iletmeyi ve güncellemeyi kolaylaştırır. Bu sayede, uygulamanızın farklı köşelerindeki bileşenler arasında veriyi aktarmak ve senkronize etmek daha basit hale gelir.

Ayrıca, Jetpack Compose’un kendi öntanımlı CompositionLocal’larını kullanarak, uygulamanızın yapılandırması, yoğunluğu ve diğer önemli verilerini daha kolay erişilebilir hale getirebilirsiniz.

CompositionLocal’ları anlamak ve kullanmak, Jetpack Compose ile daha dinamik ve esnek bir kullanıcı arayüzü oluşturmanıza yardımcı olacaktır. Bu güçlü araçla, uygulamanızın performansını ve bakımını artırabilir ve kullanıcı deneyimini geliştirebilirsiniz.

Jetpack Compose ve CompositionLocal hakkında daha fazla bilgi edinmek için resmi dokümantasyona göz atabilir ve kendi projelerinizde kullanmaya başlayabilirsiniz. Umarız bu makale, CompositionLocal’ın potansiyelini anlamanıza ve kullanmanıza yardımcı olmuştur. Başarılar dileriz!

Bana Ulaşın

Aşağıdaki bağlantılardan bana ulaşabilirsiniz.

Kerim Bora
Mobile Application Developer at
Appcent

Web https://kerimbr.com
Mail dev.kerimbora@gmail.com
LinkedIn https://www.linkedin.com/in/devkerimbr
Github https://github.com/kerimbr
Medium https://dev-kerimbora.medium.com

Cover Image

--

--