최근들어 각 플랫폼에서 디자인 기반의 선언형 언어를 강조하고 있어 Flutter 및 Siwft UI 외에 Compose UI 의 중요성을 인지, 이를 공부 하고 실무에 적용 가능 하게까지 하기 위함.
Stable한 버전의 Material Design 3 기반의 Compose 가 Release 됨.
package com.example.testapplication
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.RequiresApi
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.testapplication.ui.theme.TestApplicationTheme
class MainActivity : ComponentActivity() {
@RequiresApi(Build.VERSION_CODES.Q)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TestApplicationTheme {
Conversation(GetData())
}
}
}
}
@Composable
fun GetData() :List<Message> {
var list = arrayListOf<Message>()
for (index in 0 until 20) {
list.add(Message(author = "author $index", body = "body text, this is cody text $index"))
}
return list
}
@RequiresApi(Build.VERSION_CODES.Q)
@Composable
fun Conversation(messages: List<Message>) {
LazyColumn(modifier = Modifier.background(color = MaterialTheme.colorScheme.background)) {
items(messages) { message ->
MessageCard(message)
}
}
}
@Composable
fun Greeting(name: String) {
Text(text = "Hello $name!")
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
TestApplicationTheme {
Greeting("Android")
}
}
data class Message(val author: String, val body: String)
@RequiresApi(Build.VERSION_CODES.Q)
@Composable
fun MessageCard(msg: Message) {
Row(modifier = Modifier.padding(all = 8.dp).background(color = MaterialTheme.colorScheme.background).fillMaxWidth()) {
Image(painter = painterResource(id = R.drawable.ic_launcher_foreground),
contentDescription = null,
modifier = Modifier
.size(40.dp)
.clip(CircleShape)
.border(1.5.dp, MaterialTheme.colorScheme.secondary, CircleShape)
)
Spacer(modifier = Modifier.width(8.dp))
Column {
Text(text = msg.author,
color = MaterialTheme.colorScheme.primary,
style = MaterialTheme.typography.bodyMedium
)
Spacer(modifier = Modifier.height(4.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,
)
Surface(
// shape = MaterialTheme.shapes.medium,
tonalElevation = 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
)
}
}
}
}