diff --git a/app/build.gradle b/app/build.gradle index 75677b5..4a99d36 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,12 +5,12 @@ plugins { android { namespace 'com.lahsuak.apps.jetpackcomposebasic' - compileSdk 33 + compileSdk 34 defaultConfig { applicationId "com.lahsuak.apps.jetpackcomposebasic" minSdk 23 - targetSdk 33 + targetSdk 34 versionCode 1 versionName "1.0" @@ -27,17 +27,17 @@ android { } } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = '1.8' + jvmTarget = '17' } buildFeatures { compose true } composeOptions { - kotlinCompilerExtensionVersion '1.1.1' + kotlinCompilerExtensionVersion '1.4.3' } packagingOptions { resources { @@ -48,16 +48,17 @@ android { dependencies { - implementation 'androidx.core:core-ktx:1.9.0' - implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1' - implementation 'androidx.activity:activity-compose:1.6.1' + implementation 'androidx.core:core-ktx:1.10.1' + implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1' + implementation 'androidx.activity:activity-compose:1.7.2' implementation "androidx.compose.ui:ui:$compose_version" implementation "androidx.compose.ui:ui-tooling-preview:$compose_version" - implementation 'androidx.compose.material3:material3:1.1.0-alpha03' + implementation 'androidx.compose.material3:material3:1.2.0-alpha03' testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.4' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version" debugImplementation "androidx.compose.ui:ui-tooling:$compose_version" debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version" + implementation 'androidx.compose.foundation:foundation:1.6.0-alpha02' } \ No newline at end of file diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt index 187ee32..bb99104 100644 --- a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/MainActivity.kt @@ -10,6 +10,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import com.lahsuak.apps.jetpackcomposebasic.ui.screen.TabLayoutScreen import com.lahsuak.apps.jetpackcomposebasic.ui.theme.JetPackComposeBasicTheme class MainActivity : ComponentActivity() { @@ -22,29 +23,16 @@ class MainActivity : ComponentActivity() { modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { - Greeting("Android") + TabLayoutScreen() } } } } } -/*** -Composable functions : -A composable function is a regular function annotated with @Composable. -This enables your function to call other @Composable functions within it. -You can see how the Greeting function is marked as @Composable. -This function will produce a piece of UI hierarchy displaying the given input, -String. Text is a composable function provided by the library. -***/ -@Composable -fun Greeting(name: String) { - Text(text = "Hello $name!") -} - @Preview(showBackground = true) @Composable fun DefaultPreview() { JetPackComposeBasicTheme { - Greeting("Android") + TabLayoutScreen() } } \ No newline at end of file diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/model/TabItem.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/model/TabItem.kt new file mode 100644 index 0000000..d7ae835 --- /dev/null +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/model/TabItem.kt @@ -0,0 +1,10 @@ +package com.lahsuak.apps.jetpackcomposebasic.model + +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.vector.ImageVector + +data class TabItem ( + val title: String, + val icon: ImageVector, + val screen: @Composable () -> Unit +) \ No newline at end of file diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/screen/TabLayoutScreen.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/screen/TabLayoutScreen.kt new file mode 100644 index 0000000..73100ab --- /dev/null +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/screen/TabLayoutScreen.kt @@ -0,0 +1,110 @@ +package com.lahsuak.apps.jetpackcomposebasic.ui.screen + +import androidx.compose.animation.animateColorAsState +import androidx.compose.animation.animateContentSize +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.animateDp +import androidx.compose.animation.core.animateIntAsState +import androidx.compose.animation.core.spring +import androidx.compose.animation.core.tween +import androidx.compose.animation.core.updateTransition +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.pager.HorizontalPager +import androidx.compose.foundation.pager.rememberPagerState +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Tab +import androidx.compose.material3.TabRow +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import com.lahsuak.apps.jetpackcomposebasic.model.TabItem +import kotlinx.coroutines.launch + +@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class) +@Composable +fun TabLayoutScreen() { + val pagerState = rememberPagerState( + initialPage = 0, + initialPageOffsetFraction = 0f + ) { + tabs.size + } + val selectedIndex = animateIntAsState( + targetValue = pagerState.currentPage, label = "selection", + ) + val coroutineScope = rememberCoroutineScope() + val backgroundColor by animateColorAsState(if (tabs[pagerState.currentPage] == tabs[0]) + Color.Yellow else if (tabs[pagerState.currentPage] == tabs[1]) Color.Red else Color.Green, + label = "color" + ) + Scaffold( + topBar = { + CenterAlignedTopAppBar( + title = { Text(text = "Jetpack Compose TabLayout") }, + colors = TopAppBarDefaults.centerAlignedTopAppBarColors( + containerColor = MaterialTheme.colorScheme.primary, + titleContentColor = MaterialTheme.colorScheme.onPrimary + ) + ) + } + ) { paddingValues -> + Column( + modifier = Modifier.padding(paddingValues) + ) { + TabRow( + selectedTabIndex = selectedIndex.value, + + ) { + tabs.forEachIndexed { index, item -> + Tab( + selected = index == pagerState.currentPage, + text = { Text(text = item.title) }, + icon = { Icon(item.icon, "") }, + onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } }, + ) + } + } + HorizontalPager( + state = pagerState, + modifier = Modifier.background(backgroundColor) + ) { + tabs[pagerState.currentPage].screen() + } + } + } + +} + + +val tabs = listOf( + TabItem( + title = "Home", + icon = Icons.Filled.Home, + screen = { TabScreen("Home") } + ), + TabItem( + title = "Favorite", + icon = Icons.Filled.Favorite, + screen = { TabScreen("Favorite") } + ), + TabItem( + title = "Settings", + icon = Icons.Filled.Settings, + screen = { TabScreen(content = "Settings") } + ) +) \ No newline at end of file diff --git a/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/screen/TabScreen.kt b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/screen/TabScreen.kt new file mode 100644 index 0000000..c39d75a --- /dev/null +++ b/app/src/main/java/com/lahsuak/apps/jetpackcomposebasic/ui/screen/TabScreen.kt @@ -0,0 +1,22 @@ +package com.lahsuak.apps.jetpackcomposebasic.ui.screen + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +@Composable +fun TabScreen( + content: String +) { + Column( + modifier = Modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text(text = content ) + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index e868fc8..b0f2f02 100644 --- a/build.gradle +++ b/build.gradle @@ -1,10 +1,10 @@ buildscript { ext { - compose_version = '1.3.2' + compose_version = '1.4.3' } }// Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id 'com.android.application' version '7.3.0' apply false - id 'com.android.library' version '7.3.0' apply false - id 'org.jetbrains.kotlin.android' version '1.6.10' apply false + id 'com.android.application' version '8.0.2' apply false + id 'com.android.library' version '8.0.2' apply false + id 'org.jetbrains.kotlin.android' version '1.8.10' apply false } \ No newline at end of file