Jetpack Compose, Android için Google'ın modern, declarative UI toolkit'idir. XML layout'ların yerini alan Compose, Kotlin'in gücünü kullanarak UI geliştirmeyi basitleştirir ve hızlandırır. 2021'de stable olan Compose, artık Android UI geliştirmenin standart yoludur.
Neden Jetpack Compose?
- Declarative: UI'ı "ne" olması gerektiğiyle tanımlayın
- Daha Az Kod: XML + Kotlin yerine sadece Kotlin
- Güçlü Araçlar: Preview, interactive mode
- Kolay State Yönetimi: Reactive UI
- Material Design 3: Native destek
Temel Composable
@Composable
fun Greeting(name: String) {
Text(
text = "Hello $name!",
style = MaterialTheme.typography.headlineMedium,
modifier = Modifier.padding(16.dp)
)
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
Greeting("Android")
}
Layout'lar
@Composable
fun LayoutExample() {
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(Icons.Default.Star, contentDescription = null)
Text("Rating: 4.5")
}
Spacer(modifier = Modifier.height(16.dp))
Box(
modifier = Modifier
.size(100.dp)
.background(Color.Blue),
contentAlignment = Alignment.Center
) {
Text("Centered", color = Color.White)
}
}
}
State Management
@Composable
fun Counter() {
var count by remember { mutableStateOf(0) }
Column(horizontalAlignment = Alignment.CenterHorizontally) {
Text("Count: $count", style = MaterialTheme.typography.displayMedium)
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Button(onClick = { count-- }) {
Text("-")
}
Button(onClick = { count++ }) {
Text("+")
}
}
}
}
// ViewModel ile
@Composable
fun CounterScreen(viewModel: CounterViewModel = viewModel()) {
val count by viewModel.count.collectAsState()
Counter(
count = count,
onIncrement = viewModel::increment,
onDecrement = viewModel::decrement
)
}
LazyList (RecyclerView Alternatifi)
@Composable
fun UserList(users: List<User>) {
LazyColumn(
contentPadding = PaddingValues(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(users, key = { it.id }) { user ->
UserCard(user)
}
}
}
@Composable
fun UserCard(user: User) {
Card(
modifier = Modifier.fillMaxWidth(),
elevation = CardDefaults.cardElevation(4.dp)
) {
Row(modifier = Modifier.padding(16.dp)) {
AsyncImage(
model = user.avatarUrl,
contentDescription = null,
modifier = Modifier.size(48.dp).clip(CircleShape)
)
Spacer(Modifier.width(16.dp))
Column {
Text(user.name, style = MaterialTheme.typography.titleMedium)
Text(user.email, style = MaterialTheme.typography.bodySmall)
}
}
}
}
Navigation
@Composable
fun AppNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
composable("home") {
HomeScreen(
onNavigateToDetails = { id ->
navController.navigate("details/$id")
}
)
}
composable(
route = "details/{id}",
arguments = listOf(navArgument("id") { type = NavType.IntType })
) { backStackEntry ->
val id = backStackEntry.arguments?.getInt("id") ?: 0
DetailsScreen(id = id)
}
}
}
Theming
@Composable
fun MyAppTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: @Composable () -> Unit
) {
val colorScheme = if (darkTheme) {
darkColorScheme(
primary = Purple80,
secondary = PurpleGrey80
)
} else {
lightColorScheme(
primary = Purple40,
secondary = PurpleGrey40
)
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
Animasyonlar
@Composable
fun AnimatedVisibilityExample() {
var visible by remember { mutableStateOf(true) }
Column {
Button(onClick = { visible = !visible }) {
Text("Toggle")
}
AnimatedVisibility(
visible = visible,
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
Card(Modifier.padding(16.dp)) {
Text("Animated Content")
}
}
}
}
Testing
@Test
fun counterTest() {
composeTestRule.setContent {
Counter()
}
composeTestRule.onNodeWithText("Count: 0").assertIsDisplayed()
composeTestRule.onNodeWithText("+").performClick()
composeTestRule.onNodeWithText("Count: 1").assertIsDisplayed()
}
Jetpack Compose, Android UI geliştirmenin geleceğidir. Modern, reactive ve Kotlin-native yaklaşımıyla daha hızlı ve keyifli geliştirme deneyimi sunar.