Eğitim

Jetpack Compose Eğiticisi

Jetpack Compose yerel Android kullanıcı arayüzü oluşturmak için modern bir araç setidir. Jetpack Compose daha az kod, güçlü araçlar ve sezgisel Kotlin API'leri ile Android'de kullanıcı arayüzü geliştirmeyi basitleştirip hızlandırır.

Bu eğiticide, bildirim temelli işlevlere sahip basit bir kullanıcı arayüzü bileşeni derleyeceksiniz. Herhangi bir XML düzenini düzenlemez veya Düzen Düzenleyici'yi kullanmaz. Bunun yerine, istediğiniz öğeleri tanımlamak için composable işlevleri çağırırsınız ve gerisini Compose derleyici halleder.

Tam Önizleme
Tam Önizleme

1. Ders: Oluşturulabilir işlevler

Jetpack Compose, composable işlevleri temel alınarak geliştirildi. Bu fonksiyonlar şirketinizin nasıl görünmesi gerektiğini açıklayıp veri bağımlılıklarını sağlayarak kullanıcı arayüzü oluşturma sürecine (bir öğeyi başlatma, (ör. bir ebeveyne ekleyerek) ekleyin. Bir composable işlev oluşturmak için @Composable ek açıklaması bulunuyor.

Metin öğesi ekle

Başlamak için uygulamasının en son sürümünü indirin Android Studio'ya gidin ve Yeni Proje'yi seçip Telefon ve Tablet kategorisinde, Boş Etkinlik'i seçin. Uygulamanıza ComposeEğitici adını verin ve Son'u tıklayın. Varsayılan şablonunda zaten bazı Compose öğeleri vardır, ancak bu eğiticide öğeyi oluşturma adımında adım adım.

Öncelikle, izleyicilerinize "Hello world!" bir metin öğesi ekleyerek onCreate yöntemini çağırın. Bunu, uygulamanızın engelleniyor ve Text composable işlev. İlgili içeriği oluşturmak için kullanılan setContent bloğu, etkinlik düzenini nerede tanımlar? composable işlevler çağrılır. Özelleştirilebilir işlevler yalnızca diğer composable'lardan çağrılabilir işlevlerine dahildir.

Jetpack Compose, bu composable işlevlerini kullanıcı arayüzü öğeleri. Örneğin, Text composable işlevi, ekranda bir metin etiketi görüntüler.

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hello world!")
        }
    }
}
  
önizlemeyi göster
önizlemeyi gizle

Bir composable fonksiyon tanımlayın

Bir işlevi composable yapmak için @Composable ek açıklamasını ekleyin. Bunu denemek için, şöyle bir MessageCard fonksiyonu tanımlayın: bir ad iletir ve metin öğesini yapılandırmak için kullanır.

// ...
import androidx.compose.runtime.Composable

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard("Android")
        }
    }
}

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

  
önizlemeyi göster
önizlemeyi gizle

İşlevinizi Android Studio'da önizleme

@Preview ek açıklaması, Android'de composable işlevlerinizi önizlemenize olanak tanır Studio'yu kullanarak uygulamayı bir Android cihaza veya emülatöre oluşturup yüklemenize gerek kalmaz. İlgili içeriği oluşturmak için kullanılan ek açıklama, parametre almayan bir composable işlevde kullanılmalıdır. Bunun için Bu nedenle, MessageCard işlevi önizlenemiyor doğrudan ekleyebilirsiniz. Bunun yerine, PreviewMessageCard, şunu çağırır: Uygun bir parametre ile MessageCard. URL'yi Öncesinde @Preview ek açıklama @Composable.

// ...
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard("Android")
}
  
önizlemeyi göster
önizlemeyi gizle

Projenizi yeniden derleyin. Uygulamanın kendisi değişmedi, çünkü yeni PreviewMessageCard işlevi hiçbir yerde çağrılmaz Ancak Android Studio, bölmeyi tıklayarak genişletebileceğiniz bir önizleme penceresi ekler. (tasarım/kod) görünümüne gidin. Bu pencerede, composable tarafından oluşturulan kullanıcı arayüzü öğelerinin @Preview ek açıklamasıyla işaretlenen işlevler. Güncellemek için görüntülemek için önizleme penceresinin üst kısmındaki yenile düğmesini tıklayın.

Android Studio'da composable işlevin önizlemesi
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.material3.Text

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text("Hello world!")
        }
    }
}
  
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.runtime.Composable

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard("Android")
        }
    }
}

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

  
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun MessageCard(name: String) {
    Text(text = "Hello $name!")
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard("Android")
}
  
önizlemeyi göster
önizlemeyi gizle
Android Studio'da composable işlevin önizlemesi

2. Ders: Düzenler

Kullanıcı arayüzü öğeleri hiyerarşiktir, öğeler diğer öğelerde bulunur. Compose'da diğer composable işlevlerden composable işlevleri çağırarak kullanıcı arayüzü hiyerarşisi oluşturun.

Birden çok metin ekleme

Şu ana kadar ilk composable işlevinizi ve önizlemenizi oluşturdunuz. Jetpack Compose'u keşfetmek için bir mesaj ekleyerek, e-posta ve sohbet mesajı gönderen kullanıcıların bazı animasyonlarla genişletilebilir.

İlk olarak, iletinin yazarının adını ve mesaj içeriği. Önce composable parametresini, bir Message nesnesi yerine String ve başka bir kullanıcı ekleyin Text composable, MessageCard composable. Önizlemeyi güncellediğinizden emin olun de faydalı olabilir.

// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard(Message("Android", "Jetpack Compose"))
        }
    }
}

data class Message(val author: String, val body: String)

@Composable
fun MessageCard(msg: Message) {
    Text(text = msg.author)
    Text(text = msg.body)
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
    )
}

  
önizlemeyi göster
önizlemeyi gizle

Bu kod, içerik görünümü içinde iki metin öğesi oluşturur. Ancak, proje yönetiminde metin öğeleri birbirinin üzerine çizildiğinde, bunların nasıl düzenleneceğiyle ilgili herhangi bir bilgi metni okunmaz hale getirir.

Sütun Kullanma

Column işlevi, öğeleri dikey olarak düzenlemenizi sağlar. Şuna Column ekle: MessageCard işlevi.
. Öğeleri yatay olarak düzenlemek için Row Öğeleri gruplandırmak için Box.

// ...
import androidx.compose.foundation.layout.Column

@Composable
fun MessageCard(msg: Message) {
    Column {
        Text(text = msg.author)
        Text(text = msg.body)
    }
}
önizlemeyi göster
önizlemeyi gizle

Resim öğesi ekleyin

Gönderenin profil resmini ekleyerek mesaj kartınızı zenginleştirin. Şunu kullanın: Kaynak Yöneticisi fotoğraf kitaplığınızdan bir resim içe aktarın veya bunu kullanın. Bir Row iyi yapılandırılmış bir tasarıma ve Image composable,

// ...
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.ui.res.painterResource

@Composable
fun MessageCard(msg: Message) {
    Row {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
        )
    
       Column {
            Text(text = msg.author)
            Text(text = msg.body)
        }
  
    }
  
}
  
önizlemeyi göster
önizlemeyi gizle

Düzeninizi yapılandırma

Mesaj düzeniniz doğru yapıya sahip ancak öğeleri iyi aralıklı değil ve resim de çok büyük! Compose, bir composable'ı süslemek veya yapılandırmak için değiştiricileri kullanır. Onlar composable'ın boyutunu, düzenini ve görünümünü değiştirmenizi veya üst düzey etkileşimler eklemenizi sağlar. bir öğeyi tıklanabilir hale getirmek gibi. Daha zengin composable'lar oluşturmak için bunları zincir şeklinde düzenleyebilirsiniz. Şunu kullanacağınız: bazılarını düzenleyebilirsiniz.

// ...
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp

@Composable
fun MessageCard(msg: Message) {
    // Add padding around our message
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
            modifier = Modifier
                // Set image size to 40 dp
                .size(40.dp)
                // Clip image to be shaped as a circle
                .clip(CircleShape)
        )

        // Add a horizontal space between the image and the column
        Spacer(modifier = Modifier.width(8.dp))

        Column {
            Text(text = msg.author)
            // Add a vertical space between the author and message texts
            Spacer(modifier = Modifier.height(4.dp))
            Text(text = msg.body)
        }
    }
}
  
önizlemeyi göster
önizlemeyi gizle
// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MessageCard(Message("Android", "Jetpack Compose"))
        }
    }
}

data class Message(val author: String, val body: String)

@Composable
fun MessageCard(msg: Message) {
    Text(text = msg.author)
    Text(text = msg.body)
}

@Preview
@Composable
fun PreviewMessageCard() {
    MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
    )
}

  
önizlemeyi göster
önizlemeyi gizle
Çakışan iki Metin composable'ın önizlemesi
// ...
import androidx.compose.foundation.layout.Column

@Composable
fun MessageCard(msg: Message) {
    Column {
        Text(text = msg.author)
        Text(text = msg.body)
    }
}
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Row
import androidx.compose.ui.res.painterResource

@Composable
fun MessageCard(msg: Message) {
    Row {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
        )
    
       Column {
            Text(text = msg.author)
            Text(text = msg.body)
        }
  
    }
  
}
  
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp

@Composable
fun MessageCard(msg: Message) {
    // Add padding around our message
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = "Contact profile picture",
            modifier = Modifier
                // Set image size to 40 dp
                .size(40.dp)
                // Clip image to be shaped as a circle
                .clip(CircleShape)
        )

        // Add a horizontal space between the image and the column
        Spacer(modifier = Modifier.width(8.dp))

        Column {
            Text(text = msg.author)
            // Add a vertical space between the author and message texts
            Spacer(modifier = Modifier.height(4.dp))
            Text(text = msg.body)
        }
    }
}
  
önizlemeyi göster
önizlemeyi gizle

3. Ders: Materyal Tasarım

Compose, Materyal Tasarım ilkelerini destekleyecek şekilde geliştirildi. Kullanıcı arayüzü öğelerinin çoğu Kullanıma hazır Materyal Tasarım. Bu derste, uygulamanızı Materyal Tasarım ile widget'lar.

Materyal Tasarım'ı kullanma

Mesaj tasarımınızın artık bir düzeni var ancak henüz iyi görünmüyor.

Jetpack Compose, Materyal Tasarım 3'ün ve kullanıcı arayüzü öğelerinin seçin. MessageCard aracımızın görünümünü iyileştireceksiniz composable'dan derleyebilirsiniz.

Başlamak için MessageCard işlevini ComposeTutorialTheme adlı projenizde oluşturuldu. ve Surface. Bunu hem @Preview hem de içinde yapın setContent işlevi. Bu işlem, composable'ların Stilleri uygulamanızın temasında tanımlandığı şekilde devralmak için uygulamanız genelinde tutarlılık sağlar.

Materyal Tasarım üç temel üzerine kurulmuştur: Color, Typography ve Shape. Bu sütunları tek tek ekleyeceksiniz.

Not: Boş Yazma Etkinliği şablonu, projeniz için varsayılan tema oluşturur: özelleştirerek MaterialTheme. Projenize farklı bir ad verdiyseniz ComposeTeach'i kullanıyorsanız özel temanızı Theme.kt dosyasını ui.theme alt paket.

// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTutorialTheme {
                Surface(modifier = Modifier.fillMaxSize()) {
                    MessageCard(Message("Android", "Jetpack Compose"))
                }
            }
        }
    }
}

@Preview
@Composable
fun PreviewMessageCard() {
    ComposeTutorialTheme {
        Surface {
            MessageCard(
                msg = Message("Lexi", "Take a look at Jetpack Compose, it's great!")
            )
        }
    }
}


  
önizlemeyi göster
önizlemeyi gizle

Renk

Şuradaki renklerle stil vermek için MaterialTheme.colorScheme kullanın: sarmalanmış tema. Temadaki bu değerleri, renk gereken her yerde kullanabilirsiniz. Bu örnekte, dinamik tema renkleri kullanılmaktadır (cihaz tercihleri tarafından tanımlanır). Bunu değiştirmek için MaterialTheme.kt dosyasında dynamicColor öğesini false olarak ayarlayabilirsiniz.

Başlığın stilini ayarlayın ve resme kenarlık ekleyin.

// ...
import androidx.compose.foundation.border
import androidx.compose.material3.MaterialTheme

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )

       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary
           )

           Spacer(modifier = Modifier.height(4.dp))
           Text(text = msg.body)
       }
   }
}

  
önizlemeyi göster
önizlemeyi gizle

Yazı biçimi

Malzeme Tipografi stilleri MaterialTheme, bunları Text composable'lara eklemeniz yeterli.

// ...

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )
       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary,
               style = MaterialTheme.typography.titleSmall
           )

           Spacer(modifier = Modifier.height(4.dp))

           Text(
               text = msg.body,
               style = MaterialTheme.typography.bodyMedium
           )
       }
   }
}

  
önizlemeyi göster
önizlemeyi gizle

Şekil

Shape ile son rötuşları yapabilirsiniz. İlk olarak, bir Surface composable. Bu, ileti gövdesinin şeklini ve yüksekliğini değiştirebilirsiniz. Daha iyi bir düzen için iletiye dolgu da eklenir.

// ...
import androidx.compose.material3.Surface

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )
       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary,
               style = MaterialTheme.typography.titleSmall
           )

           Spacer(modifier = Modifier.height(4.dp))

           Surface(shape = MaterialTheme.shapes.medium, shadowElevation = 1.dp) {
               Text(
                   text = msg.body,
                   modifier = Modifier.padding(all = 4.dp),
                   style = MaterialTheme.typography.bodyMedium
               )
           }
       }
   }
}

  
önizlemeyi göster
önizlemeyi gizle

Koyu temayı etkinleştir

Koyu tema (veya gece modu) özellikle geceleri parlak bir ekrandan kaçınmak veya yalnızca geceleri cihaz piline bağlıdır. Materyal Tasarım desteği sayesinde Jetpack Compose, karanlıkta rahatça gezinebilir. varsayılan temadır. Materyal Tasarım renklerini, metinlerini ve arka planlarını kullandıktan sonra, koyu arka plana uyum sağlayabilirsiniz.

Dosyanızda ayrı işlevler olarak birden çok önizleme oluşturabilir veya birden çok önizleme ekleyebilirsiniz. ek açıklamaları içerir.

Yeni önizleme ek açıklaması ekleyin ve gece modunu etkinleştirin.

// ...
import android.content.res.Configuration

@Preview(name = "Light Mode")
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)
@Composable
fun PreviewMessageCard() {
   ComposeTutorialTheme {
    Surface {
      MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
      )
    }
   }
}
  
önizlemeyi göster
önizlemeyi gizle

Açık ve koyu temalar için renk seçenekleri, IDE tarafından oluşturulan IDE'de tanımlanır Theme.kt dosyası yükleyin.

Şimdiye kadar bir resim ve farklı metin içeren iki metin gösteren bir mesaj kullanıcı arayüzü öğesi oluşturdunuz. hem açık hem koyu temalarda iyi görünüyor.

// ...
import android.content.res.Configuration

@Preview(name = "Light Mode")
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)
@Composable
fun PreviewMessageCard() {
   ComposeTutorialTheme {
    Surface {
      MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
      )
    }
   }
}
  
önizlemeyi göster
önizlemeyi gizle
// ...

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTutorialTheme {
                Surface(modifier = Modifier.fillMaxSize()) {
                    MessageCard(Message("Android", "Jetpack Compose"))
                }
            }
        }
    }
}

@Preview
@Composable
fun PreviewMessageCard() {
    ComposeTutorialTheme {
        Surface {
            MessageCard(
                msg = Message("Lexi", "Take a look at Jetpack Compose, it's great!")
            )
        }
    }
}


  
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.foundation.border
import androidx.compose.material3.MaterialTheme

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )

       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary
           )

           Spacer(modifier = Modifier.height(4.dp))
           Text(text = msg.body)
       }
   }
}

  
önizlemeyi göster
önizlemeyi gizle
// ...

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )
       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary,
               style = MaterialTheme.typography.titleSmall
           )

           Spacer(modifier = Modifier.height(4.dp))

           Text(
               text = msg.body,
               style = MaterialTheme.typography.bodyMedium
           )
       }
   }
}

  
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.material3.Surface

@Composable
fun MessageCard(msg: Message) {
   Row(modifier = Modifier.padding(all = 8.dp)) {
       Image(
           painter = painterResource(R.drawable.profile_picture),
           contentDescription = null,
           modifier = Modifier
               .size(40.dp)
               .clip(CircleShape)
               .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
       )
       Spacer(modifier = Modifier.width(8.dp))

       Column {
           Text(
               text = msg.author,
               color = MaterialTheme.colorScheme.secondary,
               style = MaterialTheme.typography.titleSmall
           )

           Spacer(modifier = Modifier.height(4.dp))

           Surface(shape = MaterialTheme.shapes.medium, shadowElevation = 1.dp) {
               Text(
                   text = msg.body,
                   modifier = Modifier.padding(all = 4.dp),
                   style = MaterialTheme.typography.bodyMedium
               )
           }
       }
   }
}

  
önizlemeyi göster
önizlemeyi gizle
// ...
import android.content.res.Configuration

@Preview(name = "Light Mode")
@Preview(
    uiMode = Configuration.UI_MODE_NIGHT_YES,
    showBackground = true,
    name = "Dark Mode"
)
@Composable
fun PreviewMessageCard() {
   ComposeTutorialTheme {
    Surface {
      MessageCard(
        msg = Message("Lexi", "Hey, take a look at Jetpack Compose, it's great!")
      )
    }
   }
}
  
önizlemeyi göster
önizlemeyi gizle
.
Hem açık hem de koyu temalı composable'ları gösteren önizleme.

4. Ders: Listeler ve animasyonlar

Listeler ve animasyonlar uygulamaların her yerindedir. Bu derste, Oluşturma ve liste oluşturmayı kolaylaştırır ve animasyon eklemeyi eğlenceli hale getirir.

Mesaj listesi oluşturma

Tek bir mesaj içeren sohbetler biraz yalnızlık hissi veriyor. Bu nedenle sohbeti, daha çok sohbet mesajı içerecek şekilde değiştireceğiz. bir mesaj alırsınız. Conversation işlevi oluşturmanız gerekir birkaç mesaj görürsünüz. Bu kullanım alanı için Compose'un LazyColumn ve LazyRow) Bu composable'lar yalnızca öğeleri oluşturur ve uzun listeler için çok verimli olacak şekilde tasarlanmıştır.

Bu kod snippet'inde, LazyColumn için bir items çocuk. Bir Parametre olarak List ve lambda'sı , message adını verdiğimiz bir parametre alır ( (istediğimiz gibi adlandırabiliriz) ekleyebilirsiniz. Bu, Message örneğidir. Kısaca, bu lambda sağlanan List Kopyala örnek veri kümesi konuşmayı hızlıca başlatmanıza yardımcı olması için projenize ekleyebilirsiniz.

// ...
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items

@Composable
fun Conversation(messages: List<Message>) {
    LazyColumn {
        items(messages) { message ->
            MessageCard(message)
        }
    }
}

@Preview
@Composable
fun PreviewConversation() {
    ComposeTutorialTheme {
        Conversation(SampleData.conversationSample)
    }
}

  
önizlemeyi göster
önizlemeyi gizle

Genişletirken mesajları animasyonla göster

Sohbet daha ilginç hale geliyor. Animasyonlarla oynama zamanı geldi. Şunları ekleyeceksiniz: daha uzun bir mesajı gösterecek şekilde genişletilmesi sayesinde hem içerik boyutunu hem de arka plan rengi. Bu yerel kullanıcı arayüzü durumunu depolamak için bir iletinin genişletilip genişletilmediğini gösterir. Bu durum değişikliğini takip etmek için remember ve mutableStateOf.

Oluşturulabilir işlevler, aşağıdakileri kullanarak yerel durumu bellekte saklayabilir: remember ve mutableStateOf. Oluşturulabilir öğeler (ve alt öğeleri) değer güncellendiğinde bu durum otomatik olarak yeniden çizilir. Buna recomposition gibi bazı örneklerdir.

Compose'un remember ve mutableStateOf, durumda yapılan herhangi bir değişiklik kullanıcı arayüzünü otomatik olarak günceller.

Not: Kotlin'in doğru kullanımı için aşağıdaki içe aktarmaları eklemeniz gerekir: yetki verilmiş özellik söz dizimi (by anahtar kelimesi). Alt+Enter veya Option+Enter bunları ekler sizin için.
import androidx.compose.runtime.getValue import androidx.compose.runtime.setValue

// ...
import androidx.compose.foundation.clickable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue

class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           ComposeTutorialTheme {
               Conversation(SampleData.conversationSample)
           }
       }
   }
}

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colorScheme.secondary,
                style = MaterialTheme.typography.titleSmall
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                shadowElevation = 1.dp,
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}

  
önizlemeyi göster
önizlemeyi gizle

Artık ileti içeriğinin arka planını isExpanded. Şunu kullanacaksınız: Şurada tıklama etkinliklerini işlemek için clickable değiştiricisi: composable'dan bahsetmek istiyorum. Sadece düğmenin arka plan rengini değiştirmek yerine, Surface, arka plan rengini değerini kademeli olarak MaterialTheme.colorScheme.surface - MaterialTheme.colorScheme.primary ve tersi. Bunun için, animateColorAsState işlevini kullanacaksınız. Son olarak, şu öğeyi canlandırmak için animateContentSize değiştiricisini kullanacak: sorunsuz bir şekilde ayarlayabilirsiniz:

// ...
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colorScheme.secondary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }
        // surfaceColor will be updated gradually from one color to the other
        val surfaceColor by animateColorAsState(
            if (isExpanded) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surface,
        )

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colorScheme.secondary,
                style = MaterialTheme.typography.titleSmall
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                shadowElevation = 1.dp,
                // surfaceColor color will be changing gradually from primary to surface
                color = surfaceColor,
                // animateContentSize will change the Surface size gradually
                modifier = Modifier.animateContentSize().padding(1.dp)
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}

  
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items

@Composable
fun Conversation(messages: List<Message>) {
    LazyColumn {
        items(messages) { message ->
            MessageCard(message)
        }
    }
}

@Preview
@Composable
fun PreviewConversation() {
    ComposeTutorialTheme {
        Conversation(SampleData.conversationSample)
    }
}

  
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.foundation.clickable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue

class MainActivity : ComponentActivity() {
   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContent {
           ComposeTutorialTheme {
               Conversation(SampleData.conversationSample)
           }
       }
   }
}

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colorScheme.primary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colorScheme.secondary,
                style = MaterialTheme.typography.titleSmall
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                shadowElevation = 1.dp,
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}

  
önizlemeyi göster
önizlemeyi gizle
// ...
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize

@Composable
fun MessageCard(msg: Message) {
    Row(modifier = Modifier.padding(all = 8.dp)) {
        Image(
            painter = painterResource(R.drawable.profile_picture),
            contentDescription = null,
            modifier = Modifier
                .size(40.dp)
                .clip(CircleShape)
                .border(1.5.dp, MaterialTheme.colorScheme.secondary, CircleShape)
        )
        Spacer(modifier = Modifier.width(8.dp))

        // We keep track if the message is expanded or not in this
        // variable
        var isExpanded by remember { mutableStateOf(false) }
        // surfaceColor will be updated gradually from one color to the other
        val surfaceColor by animateColorAsState(
            if (isExpanded) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.surface,
        )

        // We toggle the isExpanded variable when we click on this Column
        Column(modifier = Modifier.clickable { isExpanded = !isExpanded }) {
            Text(
                text = msg.author,
                color = MaterialTheme.colorScheme.secondary,
                style = MaterialTheme.typography.titleSmall
            )

            Spacer(modifier = Modifier.height(4.dp))

            Surface(
                shape = MaterialTheme.shapes.medium,
                shadowElevation = 1.dp,
                // surfaceColor color will be changing gradually from primary to surface
                color = surfaceColor,
                // animateContentSize will change the Surface size gradually
                modifier = Modifier.animateContentSize().padding(1.dp)
            ) {
                Text(
                    text = msg.body,
                    modifier = Modifier.padding(all = 4.dp),
                    // If the message is expanded, we display all its content
                    // otherwise we only display the first line
                    maxLines = if (isExpanded) Int.MAX_VALUE else 1,
                    style = MaterialTheme.typography.bodyMedium
                )
            }
        }
    }
}

  
önizlemeyi göster
önizlemeyi gizle

Sonraki adımlar

Tebrikler, Oluşturma eğiticisini tamamladınız. Materyal Tasarım ilkeleri kullanılarak tasarlanmış koyu tema ve önizlemeler kullanılarak tasarlanan, resim ve metin içeren genişletilebilir ve animasyonlu mesajların bir listesini verimli bir şekilde gösteren basit bir sohbet ekranı oluşturdunuz ve bunların hepsi 100 satırdan kısa kodda yer alıyor.

Şimdiye kadar öğrendikleriniz:

  • Birleştirilebilir işlevleri tanımlama
  • Oluşturulabilir öğenize farklı öğeler ekleme
  • Oluşturulan düzen öğelerini kullanarak kullanıcı arayüzü bileşeninizi yapılandırma
  • Değiştirici kullanarak kompozisyonları genişletme
  • Verimli bir liste oluşturma
  • Durumu takip etme ve değiştirme
  • Oluşturulabilir bir dosyaya kullanıcı etkileşimi ekleme
  • İletileri genişletirken canlandırma

Bu adımlardan bazılarını daha ayrıntılı şekilde incelemek isterseniz aşağıdaki kaynaklara göz atabilirsiniz.

Sonraki adımlar

Kurulum
Oluşturma eğitimini tamamladığınıza göre, artık Oluştur ile derleme yapmaya hazırsınız.
Yol
Jetpack Compose'u öğrenmenize ve ustalaşmanıza yardımcı olacak codelab'ler ve videolardan oluşan özel seçkimize göz atın.