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!") } } }
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!") }
İş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") }
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.
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!") } } }
// ... 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!") }
// ... import androidx.compose.ui.tooling.preview.Preview @Composable fun MessageCard(name: String) { Text(text = "Hello $name!") } @Preview @Composable fun PreviewMessageCard() { MessageCard("Android") }
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!") ) }
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) } }
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) } } }
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) } } }
// ... 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!") ) }
// ... import androidx.compose.foundation.layout.Column @Composable fun MessageCard(msg: Message) { Column { Text(text = msg.author) Text(text = msg.body) } }
// ... 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) } } }
// ... 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) } } }
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!") ) } } }
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) } } }
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 ) } } }
Ş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 ) } } } }
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!") ) } } }
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!") ) } } }
// ... 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!") ) } } }
// ... 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) } } }
// ... @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 ) } } }
// ... 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 ) } } } }
// ... 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!") ) } } }
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) } }
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 ) } } } }
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 ) } } } }
// ... 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) } }
// ... 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 ) } } } }
// ... 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 ) } } } }
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.