diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 0000000..a3ee486
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..6806f5a
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/migrations.xml b/.idea/migrations.xml
new file mode 100644
index 0000000..f8051a6
--- /dev/null
+++ b/.idea/migrations.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index f188970..874cba3 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -1,10 +1,13 @@
+// app 모듈의 build.gradle.kts 파일
plugins {
- alias(libs.plugins.android.application)
- alias(libs.plugins.jetbrains.kotlin.android)
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+ id("kotlin-kapt")
id("com.google.devtools.ksp")
id("dagger.hilt.android.plugin")
id("androidx.navigation.safeargs.kotlin")
- id("org.jetbrains.kotlin.kapt")
+ id("kotlin-android")
+ id("kotlin-parcelize")
}
android {
@@ -17,7 +20,6 @@ android {
targetSdk = 34
versionCode = 1
versionName = "1.0"
-
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
@@ -33,19 +35,24 @@ android {
)
}
}
+
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
+
kotlinOptions {
jvmTarget = "1.8"
}
+
buildFeatures {
compose = true
}
+
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
+
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
@@ -61,8 +68,9 @@ dependencies {
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
- implementation(libs.androidx.material3) // 이미 추가됨
- implementation("androidx.compose.material3:material3:1.0.0") // 추가된 부분
+ implementation(libs.androidx.material3)
+ implementation(libs.androidx.navigation.compose)
+ implementation(libs.androidx.runtime.livedata)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
@@ -76,12 +84,7 @@ dependencies {
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.constraintlayout.compose)
implementation(libs.androidx.lifecycle.livedata.ktx)
- implementation(libs.androidx.lifecycle.viewmodel.ktx) // 추가된 부분
- implementation(libs.androidx.navigation.fragment.ktx)
- implementation(libs.androidx.navigation.ui.ktx)
-
- // Paging 라이브러리 추가
- implementation("androidx.paging:paging-runtime:3.1.1")
+ implementation(libs.androidx.lifecycle.viewmodel.ktx)
// Hilt Dependency Injection
implementation("com.google.dagger:hilt-android:2.49")
@@ -99,10 +102,7 @@ dependencies {
implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.2")
implementation("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2")
- // Lifecycle
- implementation("androidx.lifecycle:lifecycle-extensions:2.2.0")
-
- // ViewModel
+ // ViewModel and Lifecycle
implementation("androidx.activity:activity-ktx:1.9.0")
implementation("androidx.fragment:fragment-ktx:1.6.2")
@@ -117,13 +117,35 @@ dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
- // Safe Args
+ // Safe args
implementation("androidx.navigation:navigation-fragment-ktx:2.7.3")
implementation("androidx.navigation:navigation-ui-ktx:2.7.3")
// ROOM Database
implementation("androidx.room:room-runtime:2.6.1")
- annotationProcessor("androidx.room:room-compiler:2.6.1")
kapt("androidx.room:room-compiler:2.6.1")
implementation("androidx.room:room-ktx:2.6.1")
-}
\ No newline at end of file
+
+ // Navigation Compose
+ implementation("androidx.navigation:navigation-compose:2.8.1")
+
+ // Parcelize
+ implementation("androidx.core:core-ktx:1.13.1")
+
+ // ViewPager implementation
+ implementation("com.google.accompanist:accompanist-pager:0.30.0")
+ implementation("com.google.accompanist:accompanist-pager-indicators:0.30.0")
+
+ implementation("com.google.accompanist:accompanist-pager:")
+ implementation("com.google.accompanist:accompanist-pager-indicators:")
+
+ implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
+ implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.2")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2")
+
+}
+
+
+
+
+
diff --git a/app/src/androidTest/java/umc/study/umc_7th/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/umc_7th/ExampleInstrumentedTest.kt
similarity index 85%
rename from app/src/androidTest/java/umc/study/umc_7th/ExampleInstrumentedTest.kt
rename to app/src/androidTest/java/com/example/umc_7th/ExampleInstrumentedTest.kt
index 8315371..c890911 100644
--- a/app/src/androidTest/java/umc/study/umc_7th/ExampleInstrumentedTest.kt
+++ b/app/src/androidTest/java/com/example/umc_7th/ExampleInstrumentedTest.kt
@@ -1,4 +1,4 @@
-package umc.study.umc_7th
+package com.example.umc_7th
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -19,6 +19,6 @@ class ExampleInstrumentedTest {
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
- assertEquals("umc.study.umc_7th", appContext.packageName)
+ assertEquals("com.example.umc_7th", appContext.packageName)
}
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index b099ba3..ac36b0b 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,9 +1,6 @@
\
-
-
-
+ xmlns:tools="http://schemas.android.com/tools">
diff --git a/app/src/main/java/com/example/umc_7th/album1/AlbumFragment.kt b/app/src/main/java/com/example/umc_7th/album1/AlbumFragment.kt
new file mode 100644
index 0000000..c43d57f
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/album1/AlbumFragment.kt
@@ -0,0 +1,91 @@
+package com.example.umc_7th.album1
+
+import android.annotation.SuppressLint
+import androidx.compose.foundation.layout.Column
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.navigation.NavController
+import java.time.LocalDate
+
+// AlbumData 데이터 클래스 정의
+data class AlbumData(
+ val albumTitle: String,
+ val date: LocalDate,
+ val author: String,
+ val albumImage: Int,
+ val trackList: List,
+ val titleTrackList: List
+)
+
+@Composable
+fun AlbumInfo() {
+ Text(text = "앨범 정보")
+}
+
+@Composable
+fun AlbumVideo() {
+ Text(text = "앨범 영상")
+}
+
+@SuppressLint("NewApi")
+@Composable
+fun albumFragment(
+ navController: NavController,
+ albumTitle: String,
+ albumImage: Int,
+ author: String,
+ date: LocalDate,
+ trackList: List,
+ titleTrackList: List
+) {
+ // AlbumData 객체 생성
+ val album = AlbumData(
+ albumTitle = albumTitle,
+ date = date,
+ author = author,
+ albumImage = albumImage,
+ trackList = trackList,
+ titleTrackList = titleTrackList
+ )
+
+ Column {
+ // AlbumFragmentTop 호출
+ AlbumFragmentTop(
+ album = album,
+ albumFgtoMain = { navController.navigate("homeFragment") },
+ likeButtonClick = { /* TODO: 좋아요 버튼 기능 추가 */ },
+ playerMoreButtonClick = { /* TODO: 더보기 버튼 기능 추가 */ }
+ )
+
+ // TabLayout 호출
+ TabLayout(album = album)
+ }
+}
+
+// AlbumFragmentTop 함수 정의
+@Composable
+fun AlbumFragmentTop(
+ album: AlbumData,
+ albumFgtoMain: () -> Unit,
+ likeButtonClick: () -> Unit,
+ playerMoreButtonClick: () -> Unit
+) {
+ Column {
+ Text(text = "Album Title: ${album.albumTitle}")
+ Text(text = "Author: ${album.author}")
+ Text(text = "Date: ${album.date}")
+ // 버튼 클릭 이벤트 추가
+ }
+}
+
+// TabLayout 함수 정의
+@Composable
+fun TabLayout(album: AlbumData) {
+ Column {
+ Text(text = "TabLayout for ${album.albumTitle}")
+ // Tab 항목 구성
+ }
+}
+
+
+
diff --git a/app/src/main/java/com/example/umc_7th/album1/AlbumFragmentTop.kt b/app/src/main/java/com/example/umc_7th/album1/AlbumFragmentTop.kt
new file mode 100644
index 0000000..0a07421
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/album1/AlbumFragmentTop.kt
@@ -0,0 +1,157 @@
+// AlbumFragmentTop.kt 파일
+package com.example.umc_7th.album1
+
+import android.annotation.SuppressLint
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ImageBitmap
+import androidx.compose.ui.res.imageResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.example.umc_7th.R
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+@SuppressLint("NewApi")
+@Composable
+fun AlbumFragmentTop(
+ album: Album,
+ albumFgtoMain: () -> Unit,
+ likeButtonClick: () -> Unit,
+ playerMoreButtonClick: () -> Unit,
+ playAlbumButtonClick: () -> Unit
+) {
+ Column(
+ verticalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = Modifier.padding(10.dp)
+ ) {
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ IconButton(onClick = albumFgtoMain) {
+ Icon(
+ bitmap = ImageBitmap.imageResource(id = R.drawable.btn_arrow_black),
+ contentDescription = null,
+ modifier = Modifier.size(50.dp)
+ )
+ }
+ Row(
+ horizontalArrangement = Arrangement.End,
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ var like by remember { mutableStateOf(false) }
+ IconButton(onClick = likeButtonClick) {
+ Icon(
+ bitmap = if (like) ImageBitmap.imageResource(id = R.drawable.ic_my_like_on)
+ else ImageBitmap.imageResource(id = R.drawable.ic_my_like_off),
+ contentDescription = null,
+ modifier = Modifier
+ .size(50.dp)
+ .clickable { like = !like },
+ tint = Color.Unspecified
+ )
+ }
+
+ Icon(
+ bitmap = ImageBitmap.imageResource(id = R.drawable.btn_player_more),
+ contentDescription = null,
+ modifier = Modifier.clickable { playerMoreButtonClick() }
+ )
+ }
+ }
+
+ Column(
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Text(
+ text = album.albumTitle,
+ fontWeight = FontWeight.Bold,
+ fontSize = 16.sp
+ )
+ Text(
+ text = album.author,
+ style = TextStyle(
+ color = Color.Black.copy(alpha = 0.5f)
+ ),
+ fontSize = 12.sp
+ )
+ val dateString = album.date.format(DateTimeFormatter.ofPattern("yyyy.MM.dd"))
+ val genre = "댄스 팝"
+ val regular = "정규"
+ Text(text = "$dateString | $regular | $genre")
+ }
+
+ Row(
+ modifier = Modifier.padding(start = 70.dp)
+ ) {
+ Box(
+ contentAlignment = Alignment.Center
+ ) {
+ Image(
+ bitmap = ImageBitmap.imageResource(id = album.albumImage),
+ contentDescription = null,
+ modifier = Modifier
+ .size(210.dp)
+ .align(Alignment.Center)
+ .clip(RoundedCornerShape(20.dp))
+ )
+ IconButton(onClick = playAlbumButtonClick, modifier = Modifier.align(Alignment.BottomEnd)) {
+ Icon(
+ bitmap = ImageBitmap.imageResource(id = R.drawable.widget_black_play),
+ contentDescription = null,
+ tint = Color.Unspecified
+ )
+ }
+ }
+ Image(
+ painter = painterResource(id = R.drawable.img_album_lp),
+ contentDescription = null
+ )
+ }
+ }
+}
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Composable
+@Preview(showBackground = true)
+fun previewAlbumFragmentTop() {
+ AlbumFragmentTop(
+ album = Album(
+ albumTitle = "IU 5th Album 'LILAC'",
+ date = LocalDate.parse("2023-03-27"),
+ author = "IU(아이유)",
+ albumImage = R.drawable.img_album_exp2,
+ trackList = listOf("LILAC", "Coin", "Flu", "Troll", "Lovesick"),
+ titleTrackList = listOf("LILAC", "Flu")
+ ),
+ albumFgtoMain = { /* TODO: 메인 화면으로 이동하는 함수 구현 */ },
+ likeButtonClick = { /* TODO: 좋아요 클릭 처리 함수 구현 */ },
+ playerMoreButtonClick = { /* TODO: 플레이어 더보기 클릭 처리 함수 구현 */ },
+ playAlbumButtonClick = { /* TODO: 앨범 재생 클릭 처리 함수 구현 */ }
+ )
+}
+
+
diff --git a/app/src/main/java/com/example/umc_7th/album1/AlbumItem.kt b/app/src/main/java/com/example/umc_7th/album1/AlbumItem.kt
new file mode 100644
index 0000000..0a2dd3b
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/album1/AlbumItem.kt
@@ -0,0 +1,110 @@
+package com.example.umc_7th.album1
+
+import android.os.Build
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.lazy.grid.GridCells
+import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
+import androidx.compose.foundation.lazy.grid.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ImageBitmap
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.imageResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import umc.study.umc_7th.R
+
+// Album 데이터 클래스 정의
+data class Album(
+ val albumTitle: String,
+ val author: String,
+ val albumImage: Int
+)
+
+// 샘플 albumData 리스트 생성
+val albumData = listOf(
+ com.example.umc_7th.etc.Album("Album 1", "Author 1", R.drawable.sample_image1),
+ com.example.umc_7th.etc.Album("Album 2", "Author 2", R.drawable.sample_image2),
+ // 필요한 만큼 Album 객체 추가
+)
+
+class AlbumItemActivity : ComponentActivity() {
+ @RequiresApi(Build.VERSION_CODES.P)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ AlbumItem()
+ }
+ }
+}
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Composable
+fun AlbumItem() {
+ LazyVerticalGrid(
+ columns = GridCells.Fixed(2),
+ modifier = Modifier.padding(horizontal = 8.dp)
+ ) {
+ items(albumData) { content ->
+ Column(modifier = Modifier.padding(vertical = 0.dp)) {
+ Box(
+ contentAlignment = Alignment.Center,
+ modifier = Modifier
+ .wrapContentSize()
+ .padding(vertical = 20.dp)
+ ) {
+ Image(
+ bitmap = ImageBitmap.imageResource(id = content.albumImage),
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = Modifier
+ .size(180.dp)
+ .clip(RoundedCornerShape(8.dp))
+ )
+
+ Icon(
+ painter = painterResource(id = R.drawable.btn_miniplayer_play),
+ contentDescription = null,
+ tint = Color.White,
+ modifier = Modifier
+ .size(48.dp)
+ .align(Alignment.BottomEnd)
+ )
+ }
+ Column(modifier = Modifier.padding(5.dp)) {
+ Text(
+ text = content.albumTitle,
+ fontSize = 20.sp,
+ fontWeight = FontWeight.Bold
+ )
+ Text(text = content.author)
+ }
+ }
+ }
+ }
+}
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Preview(showBackground = true)
+@Composable
+fun PreviewAlbumItem() {
+ AlbumItem()
+}
diff --git a/app/src/main/java/com/example/umc_7th/album1/AlbumMusicList.kt b/app/src/main/java/com/example/umc_7th/album1/AlbumMusicList.kt
new file mode 100644
index 0000000..d1f403c
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/album1/AlbumMusicList.kt
@@ -0,0 +1,240 @@
+package com.example.umc_7th.album1
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.itemsIndexed
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import umc.study.umc_7th.R
+import java.time.LocalDate
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Composable
+fun AlbumMusicList(
+ album : Album,
+ playButtonClick : () -> Unit,
+ playAllButtonClick : () -> Unit,
+ selectAllButtonClick : () -> Unit,
+ moreInfoButtonClick :() -> Unit,
+ mixButtonClick : () -> Unit,
+) {
+ LazyColumn(
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ modifier = Modifier.fillMaxHeight()
+ ) {
+ item {
+ Column(
+ verticalArrangement = Arrangement.spacedBy(4.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = Modifier.padding(10.dp)
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.background(Color.Black.copy(0.05f),
+ shape= RoundedCornerShape(percent= 50)
+ ).padding(vertical =6.dp, horizontal = 10.dp)
+ ) {
+//
+ Text(text = "내 취향 MIX", fontSize = 15.sp)
+
+ var checked by remember { mutableStateOf(false) }
+ Icon(painter = painterResource(
+ id = if (checked == false) R.drawable.btn_toggle_off
+ else R.drawable.btn_toggle_on
+ ), contentDescription = null,
+ modifier = Modifier
+ .clickable { checked = !checked }
+ .size(30.dp),
+ tint = Color.Unspecified)
+// }
+
+ }
+ Box(modifier = Modifier.fillMaxWidth()) {
+ var selected by remember { mutableStateOf(false) }
+ Row(
+ modifier = Modifier
+ .clickable { selectAllButtonClick() }
+ .align(Alignment.CenterStart)
+
+ ) {
+ Icon(
+ painter = painterResource(
+ id = if (selected == false) R.drawable.btn_playlist_select_off
+ else R.drawable.btn_playlist_select_on
+ ),
+ contentDescription = null,
+ modifier = Modifier.size(16.dp)
+ )
+ Text(
+ text = "전체 선택",
+ fontSize = 12.sp,
+ color = if (selected == false) Color.Black else Color.Blue
+ )
+ }
+ Row(
+ modifier = Modifier
+ .clickable { playAllButtonClick() }
+ .align(Alignment.CenterEnd),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.icon_browse_arrow_right),
+ contentDescription = null,
+ modifier = Modifier.size(16.dp)
+ )
+ Text(
+ text = "전체 듣기", color = Color.Black,
+ fontSize = 12.sp
+ )
+ }
+
+
+ }
+ }
+
+ }
+
+ itemsIndexed(album.trackList) { index, track ->
+ if(track in album.titleTrackList)
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(start = 10.dp),
+ verticalAlignment = Alignment.Top){
+ Text(
+ text = "${index + 1}", Modifier.padding(horizontal = 4.dp),
+ fontSize = 12.sp, fontWeight = FontWeight.Bold
+ )
+ Column {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ Text(text="title", fontSize= 10.sp, color = Color.White,
+ modifier= Modifier.background(Color.Blue, shape = RoundedCornerShape(percent=30))
+ .padding(horizontal =4.dp, vertical = 0.dp))
+
+ Spacer(modifier = Modifier.size(4.dp))
+ Text(text = track)
+
+ }
+
+ Text(
+ text = album.author,
+ color = Color.Black.copy(0.5f),
+ fontSize = 12.sp)
+ }
+ Row(
+ modifier = Modifier
+ .padding(4.dp)
+ .fillMaxSize(),
+ horizontalArrangement = Arrangement.End,
+ verticalAlignment = Alignment.Top
+ ) {
+ Icon(painter = painterResource(id = R.drawable.btn_player_play),
+ contentDescription = null,
+ modifier = Modifier
+ .size(24.dp)
+ .clickable { playButtonClick() })
+ Icon(painter = painterResource(id = R.drawable.btn_player_more),
+ contentDescription = null,
+ modifier = Modifier
+ .size(24.dp)
+ .clickable { moreInfoButtonClick() })
+ }
+
+ }
+ else
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(start = 10.dp),
+ verticalAlignment = Alignment.Top
+ ) {
+ Text(
+ text = "${index + 1}", Modifier.padding(horizontal = 4.dp),
+ fontSize = 12.sp, fontWeight = FontWeight.Bold
+ )
+ Column {
+ Text(text = track)
+ Text(
+ text = album.author,
+ color = Color.Black.copy(0.5f),
+ fontSize = 12.sp
+ )
+ }
+
+ Row(
+ modifier = Modifier
+ .padding(4.dp)
+ .fillMaxSize(),
+ horizontalArrangement = Arrangement.End,
+ verticalAlignment = Alignment.Top
+ ) {
+ Icon(painter = painterResource(id = R.drawable.btn_player_play),
+ contentDescription = null,
+ modifier = Modifier
+ .size(24.dp)
+ .clickable { playButtonClick() })
+ Icon(painter = painterResource(id = R.drawable.btn_player_more),
+ contentDescription = null,
+ modifier = Modifier
+ .size(24.dp)
+ .clickable { moreInfoButtonClick() })
+ }
+ }
+
+
+ }
+
+
+ }
+}
+
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Preview(showBackground = true)
+@Composable
+fun PreviewAlbumMusicList(){
+ AlbumMusicList(
+ album = Album(
+ albumTitle = "IU 5th Album 'LILAC'",
+ date = LocalDate.parse("2023-03-27"),
+ author = "IU(아이유)",
+ albumImage = R.drawable.img_album_exp2,
+ trackList = listOf("LILAC", "Coin", "Flu", "Troll", "Lovesick"),
+ titleTrackList = listOf("LILAC", "Flu")
+ ),
+ playButtonClick = { /*TODO*/ },
+ playAllButtonClick = { /*TODO*/ },
+ selectAllButtonClick = { /*TODO*/ },
+ mixButtonClick = {},
+ moreInfoButtonClick = {}
+ )
+}
diff --git a/app/src/main/java/com/example/umc_7th/etc/AroundFragment.kt b/app/src/main/java/com/example/umc_7th/etc/AroundFragment.kt
new file mode 100644
index 0000000..56522e8
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/etc/AroundFragment.kt
@@ -0,0 +1,16 @@
+package com.example.umc_7th.etc
+
+import android.annotation.SuppressLint
+import androidx.compose.foundation.content.MediaType.Companion.Text
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.navigation.NavController
+
+@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
+@Composable
+fun aroundFragment(navController: NavController){
+ Scaffold {
+ Text(text = "around")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/umc_7th/etc/Content.kt b/app/src/main/java/com/example/umc_7th/etc/Content.kt
new file mode 100644
index 0000000..207e244
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/etc/Content.kt
@@ -0,0 +1,154 @@
+// 파일 경로: com.example.umc_7th.etc
+
+package com.example.umc_7th.etc
+
+import android.os.Build
+import androidx.compose.ui.graphics.Color
+import androidx.annotation.RequiresApi
+import kotlinx.parcelize.Parcelize
+import android.os.Parcelable
+import java.time.LocalDate
+
+@Parcelize
+data class Content(
+ val title: String,
+ val author: String,
+ val image: Int? = null,
+ val length: Int
+) : Parcelable
+
+@Parcelize
+data class Album(
+ val albumTitle: String,
+ val date: LocalDate,
+ val author: String,
+ val albumImage: Int,
+ val trackList: List,
+ val titleTrackList: List
+) : Parcelable
+
+@Parcelize
+data class BannerData(
+ val title1: String,
+ val date: LocalDate,
+ val contentList: List,
+ val backgroundImage: Int,
+ val textColor: Long
+) : Parcelable
+
+@RequiresApi(Build.VERSION_CODES.P)
+val bannerDataList = listOf(
+ BannerData(
+ title1 = "포근하게 덮어주는 꿈의 목소리2",
+ date = LocalDate.parse("2024-03-06"),
+ contentList = listOf(
+ Content(
+ title = "Butter",
+ author = "BTS",
+ image = R.drawable.img_album_exp,
+ length = 245
+ ),
+ Content(
+ title = "Next Level",
+ author = "aespa",
+ image = R.drawable.img_album_exp3,
+ length = 199
+ )
+ ),
+ backgroundImage = R.drawable.img_default_4_x_1,
+ textColor = 0xFFFFFFFF
+ ),
+ BannerData(
+ title1 = "포근하게 덮어주는 꿈의 목소리 3",
+ date = LocalDate.parse("2024-03-06"),
+ contentList = List(15) {
+ Content(
+ title = "작은 것들을 위한 시",
+ author = "BTS",
+ image = R.drawable.img_album_exp4,
+ length = 220
+ )
+ },
+ backgroundImage = R.drawable.img_default_4_x_1,
+ textColor = 0xFFFFFFFF
+ ),
+ BannerData(
+ title1 = "포근하게 덮어주는 꿈의 목소리 4",
+ date = LocalDate.parse("2024-03-06"),
+ contentList = List(15) {
+ Content(
+ title = "해야",
+ author = "IVE(아이브)",
+ image = R.drawable.img_album_heya,
+ length = 200
+ )
+ },
+ backgroundImage = R.drawable.img_default_4_x_1,
+ textColor = 0xFFFFFFFF
+ )
+)
+
+@RequiresApi(Build.VERSION_CODES.P)
+val albumData = listOf(
+ Album(
+ albumTitle = "IU 5th Album 'LILAC'",
+ date = LocalDate.parse("2023-03-27"),
+ author = "IU(아이유)",
+ albumImage = R.drawable.img_album_exp2,
+ trackList = listOf("LILAC", "Coin", "Flu", "Troll", "Lovesick"),
+ titleTrackList = listOf("LILAC", "Flu")
+ ),
+ Album(
+ albumTitle = "BTS 'Map of the Soul: Persona'",
+ date = LocalDate.parse("2019-04-12"),
+ author = "BTS(방탄소년단)",
+ albumImage = R.drawable.img_album_exp4,
+ trackList = listOf("Intro: Persona", "Boy With Luv", "Mikrokosmos", "Make It Right", "Home"),
+ titleTrackList = listOf("Boy With Luv")
+ ),
+ Album(
+ albumTitle = "Next Level",
+ date = LocalDate.parse("2019-04-12"),
+ author = "aespa",
+ albumImage = R.drawable.img_album_exp3,
+ trackList = listOf("Next Level"),
+ titleTrackList = listOf("Next Level")
+ ),
+ Album(
+ albumTitle = "MOMOLAND 'BAAM'",
+ date = LocalDate.parse("2018-06-26"),
+ author = "MOMOLAND",
+ albumImage = R.drawable.img_album_exp5,
+ trackList = listOf("BAAM", "Veryvery", "Bingo Game", "Only one you", "Falling U"),
+ titleTrackList = listOf("BAAM")
+ ),
+ Album(
+ albumTitle = "Taeyeon 'Weekend'",
+ date = LocalDate.parse("2021-07-06"),
+ author = "Taeyeon(태연)",
+ albumImage = R.drawable.img_album_exp6,
+ trackList = listOf("Weekend"),
+ titleTrackList = listOf("Weekend")
+ ),
+ Album(
+ albumTitle = "aespa 'Next Level: Drama'",
+ date = LocalDate.parse("2023-06-15"),
+ author = "aespa(에스파)",
+ albumImage = R.drawable.img_album_drama,
+ trackList = listOf("Next Level", "Drama", "Black Mamba", "Forever", "Savage"),
+ titleTrackList = listOf("Drama", "Next Level")
+ ),
+ Album(
+ albumTitle = "IVE 'I've HAEYA'",
+ date = LocalDate.parse("2023-08-10"),
+ author = "IVE(아이브)",
+ albumImage = R.drawable.img_album_heya,
+ trackList = listOf("HAEYA", "After LIKE", "ELEVEN", "LOVE DIVE", "ROYAL"),
+ titleTrackList = listOf("HAEYA", "After LIKE")
+ )
+)
+
+
+
+
+
diff --git a/app/src/main/java/com/example/umc_7th/etc/SearchFragment.kt b/app/src/main/java/com/example/umc_7th/etc/SearchFragment.kt
new file mode 100644
index 0000000..3a84dc3
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/etc/SearchFragment.kt
@@ -0,0 +1,16 @@
+package com.example.umc_7th.etc
+
+import android.annotation.SuppressLint
+import androidx.compose.foundation.content.MediaType.Companion.Text
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.navigation.NavController
+
+@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
+@Composable
+fun searchFragment(navController: NavController){
+ Scaffold {
+ Text(text = "search")
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/umc_7th/etc/Service.kt b/app/src/main/java/com/example/umc_7th/etc/Service.kt
new file mode 100644
index 0000000..706ca69
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/etc/Service.kt
@@ -0,0 +1,75 @@
+package com.example.umc_7th.etc
+
+import android.app.Service
+import android.content.Intent
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.app.PendingIntent
+import android.content.Context
+import android.os.IBinder
+import android.os.Build
+import androidx.core.app.NotificationCompat
+import android.graphics.BitmapFactory
+
+import com.example.umc_7th.home.MainActivity
+
+class MusicPlayerService : Service() {
+ override fun onCreate() {
+ super.onCreate()
+ }
+
+ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
+ startForeground(1, createNotification())
+ return START_STICKY
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ }
+
+ override fun onBind(intent: Intent?): IBinder? {
+ return null
+ }
+
+ private fun createNotification(): Notification {
+ val notificationChannelId = "MUSIC_PLAYER_CHANNEL"
+ val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ val channel = NotificationChannel(
+ notificationChannelId,
+ "Music Player",
+ NotificationManager.IMPORTANCE_LOW
+ )
+ notificationManager.createNotificationChannel(channel)
+ }
+
+ // 알림 클릭 시 앱의 MainActivity를 여는 Intent와 PendingIntent
+ val notificationIntent = Intent(this, MainActivity::class.java)
+ val pendingIntent = PendingIntent.getActivity(
+ this,
+ 0,
+ notificationIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE // FLAG_IMMUTABLE은 API 23 이상 필요
+ )
+
+ return NotificationCompat.Builder(this, notificationChannelId)
+ .setContentTitle("Now Playing")
+ .setContentText("Your favorite song is playing")
+ .setSmallIcon(R.drawable.icon_browse_arrow_right) // 작은 아이콘
+ .setLargeIcon(BitmapFactory.decodeResource(resources, R.drawable.img_album_exp)) // 큰 아이콘
+ .setContentIntent(pendingIntent) // 클릭 시 MainActivity로 이동
+ .setPriority(NotificationCompat.PRIORITY_LOW)
+ .setOngoing(true) // 사용자가 수동으로만 제거할 수 있도록 설정
+ .build()
+ }
+}
+fun startMusicService(context: Context) {
+ val intent = Intent(context, MusicPlayerService::class.java)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ context.startForegroundService(intent)
+ } else {
+ context.startService(intent)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/umc_7th/etc/TabLayout.kt b/app/src/main/java/com/example/umc_7th/etc/TabLayout.kt
new file mode 100644
index 0000000..36779f3
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/etc/TabLayout.kt
@@ -0,0 +1,98 @@
+package com.example.umc_7th.etc
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.rememberPagerState
+import androidx.compose.material3.Tab
+import androidx.compose.material3.TabRow
+import androidx.compose.material3.TabRowDefaults
+import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.rememberCoroutineScope
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import kotlinx.coroutines.launch
+import umc.study.umc_7th.album.AlbumMusicList
+import java.time.LocalDate
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Composable
+fun TabLayout(
+ album : Album,
+) {
+ val tabs = listOf("수록곡", "상세정보", "영상")
+ val pagerState = rememberPagerState{ tabs.size }
+ val coroutineScope = rememberCoroutineScope()
+
+ Column {
+ TabRow(
+ selectedTabIndex = pagerState.currentPage,
+ indicator = { tabPositions ->
+ TabRowDefaults.Indicator(
+ Modifier
+ .tabIndicatorOffset(tabPositions[pagerState.currentPage])
+ .padding(horizontal = tabPositions[pagerState.currentPage].width / 4),
+ color = Color.Blue,
+ height = 4.dp,
+
+ )
+ }
+ ) {
+ tabs.forEachIndexed { index, title ->
+ Tab(
+ text = { Text(text = title, fontSize = 16.sp,
+ color = if(pagerState.currentPage ==index) Color.Blue
+ else Color.Black)
+ },
+ selected = pagerState.currentPage == index,
+ onClick = {
+ coroutineScope.launch {
+ pagerState.animateScrollToPage(index)
+ }
+ }
+ )
+ }
+ }
+ HorizontalPager(
+ state = pagerState,
+ modifier = Modifier.fillMaxSize()
+ ) { page ->
+ when (page) {
+ 0 -> AlbumMusicList(
+ album = album,
+ playButtonClick = { /*TODO*/ },
+ playAllButtonClick = { /*TODO*/ },
+ selectAllButtonClick = { /*TODO*/ },
+ mixButtonClick = {},
+ moreInfoButtonClick = {})
+ 1 -> Text("상세정보 내용", modifier = Modifier.padding(16.dp))
+ 2 -> Text("영상 내용", modifier = Modifier.padding(16.dp))
+ }
+ }
+ }
+}
+
+
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Preview(showBackground = true)
+@Composable
+fun PreviewTabLayout(){
+ TabLayout(album =Album(
+ albumTitle = "IU 5th Album 'LILAC'",
+ date = LocalDate.parse("2023-03-27"),
+ author = "IU(아이유)",
+ albumImage = R.drawable.img_album_exp2,
+ trackList = listOf("LILAC", "Coin", "Flu", "Troll", "Lovesick"),
+ titleTrackList = listOf("LILAC", "Flu")
+ )
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/umc_7th/etc/ViewModel.kt b/app/src/main/java/com/example/umc_7th/etc/ViewModel.kt
new file mode 100644
index 0000000..c63d061
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/etc/ViewModel.kt
@@ -0,0 +1,126 @@
+package com.example.umc_7th.etc
+
+import android.app.Application
+import androidx.lifecycle.AndroidViewModel
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+
+open class SongViewModel(application: Application) : AndroidViewModel(application) {
+
+ private val _like = MutableLiveData(false)
+ open val like : LiveData = _like
+
+ private val _unLike = MutableLiveData(false)
+ open val unLike : LiveData = _unLike
+
+ fun toggleLike(){
+ _like.value = _like.value != true
+ }
+
+ fun toggleUnLike(){
+ _unLike.value = _unLike.value != true
+ }
+
+
+
+ private val _replay = MutableLiveData(false)
+ open val replay : LiveData = _replay
+
+ private val _played = MutableLiveData(false)
+ open val played : LiveData = _played
+
+ private val _duration = MutableLiveData(200f)
+ open val duration : LiveData = _duration
+
+ private val _currentPosition = MutableLiveData(0f)
+ open val currentPosition : LiveData = _currentPosition
+
+ private val _shuffle = MutableLiveData(false)
+ open val shuffle : LiveData = _shuffle
+
+ private var playbackJob : Job? = null
+
+ open fun toggleReplay() {
+ _replay.value = _replay.value != true
+ }
+ open fun togglePlayed() {
+ _played.value = _played.value != true
+
+ if (_played.value == true) {
+ startPlayback()
+ }else {
+ stopPlayedback()
+ }
+ }
+
+ private fun startPlayback(){
+ playbackJob?.cancel()
+ playbackJob = viewModelScope.launch {
+ while (_played.value == true && _currentPosition.value!! < _duration.value!!){
+ delay(1000L)
+ _currentPosition.value = _currentPosition.value!! + 1f
+ }
+ }
+ }
+ private fun stopPlayedback(){
+ playbackJob?.cancel()
+ }
+
+ open fun toggleShuffle() {
+ _shuffle.value = _shuffle.value != true
+ }
+ open fun updatePosition(position: Float){
+ _currentPosition.value = position
+ }
+ fun setDuration(duration: Float){
+ _duration.value = duration
+ }
+ fun resetProgress(){ // 그 .. beforeSongPlayClick() 에 넣어줄 것
+ _currentPosition.value = 0f
+ }
+
+ private val _currentSong = MutableLiveData(null)
+ open val currentSong : LiveData = _currentSong
+
+ fun setCurrentSong(content:Content){
+ _currentSong.value = content
+ resetProgress()
+ togglePlayed()
+ }
+
+}
+
+class MyApplication : Application() {
+ val songViewModel : SongViewModel by lazy { SongViewModel(this) }
+
+}
+
+//가짜 뷰 모델
+class FakeSongViewModel(application: Application) : SongViewModel(application) {
+ override val replay = MutableLiveData(false)
+ override val played = MutableLiveData(true)
+ override val shuffle = MutableLiveData(false)
+ override val currentPosition = MutableLiveData(0f)
+ override val duration = MutableLiveData(200f)
+
+ override fun updatePosition(newPosition: Float) {
+ currentPosition.value = newPosition
+ }
+
+ override fun toggleReplay() {
+ replay.value = replay.value?.not()
+ }
+
+ override fun togglePlayed() {
+ played.value = played.value?.not()
+ }
+
+ override fun toggleShuffle() {
+ shuffle.value = shuffle.value?.not()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/umc/study/umc_7th/BottomBar.kt b/app/src/main/java/com/example/umc_7th/home/BottomNavigationBar.kt
similarity index 79%
rename from app/src/main/java/umc/study/umc_7th/BottomBar.kt
rename to app/src/main/java/com/example/umc_7th/home/BottomNavigationBar.kt
index 58fa583..e5da6b7 100644
--- a/app/src/main/java/umc/study/umc_7th/BottomBar.kt
+++ b/app/src/main/java/com/example/umc_7th/home/BottomNavigationBar.kt
@@ -1,23 +1,17 @@
-package umc.study.umc_7th
+package com.example.umc_7th.home
import android.os.Build
+import androidx.activity.ComponentActivity
import androidx.annotation.RequiresApi
-import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
//import androidx.compose.foundation.layout.FlowRowScopeInstance.weight
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
-import androidx.compose.material3.NavigationBarItemDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -26,15 +20,12 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.style.LineBreak
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.res.imageResource
+import com.example.umc_7th.R
enum class DestinationClass(
val mean : String,
@@ -86,13 +77,15 @@ fun BottomNavigationBar(
}
}
}
-
-@RequiresApi(Build.VERSION_CODES.P)
-@Preview(showBackground = true)
-@Composable
-fun PreiviewBottomNavigationBar(){
- BottomNavigationBar(
- onClick = { }
- )
+class BottomNavigationBar : ComponentActivity() {
+ @RequiresApi(Build.VERSION_CODES.P)
+ @Preview(showBackground = true)
+ @Composable
+ fun PreiviewBottomNavigationBar() {
+ BottomNavigationBar(
+ onClick = { }
+ )
+ }
}
+
diff --git a/app/src/main/java/com/example/umc_7th/home/Horizontal.kt b/app/src/main/java/com/example/umc_7th/home/Horizontal.kt
new file mode 100644
index 0000000..39bcceb
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/home/Horizontal.kt
@@ -0,0 +1,229 @@
+package com.example.umc_7th.home
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.text.ClickableText
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.AnnotatedString
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.compose.foundation.lazy.LazyRow
+import androidx.compose.foundation.lazy.items
+
+enum class BaseLocationCategory(val mean: String) {
+ GLOBAL(mean = "종합"),
+ DOMESTIC(mean = "국내"),
+ FOREIGN(mean = "해외"),
+}
+
+@Composable
+fun horizontalScrollContentView(
+ contentList: List,
+ titleBar: @Composable () -> Unit,
+ thumbnail: @Composable (Content) -> Unit,
+ contentClick: (Content) -> Unit
+) {
+ Column {
+ titleBar()
+ LazyRow {
+ items(contentList) { content ->
+ Box(
+ modifier = Modifier
+ .padding(8.dp)
+ .clickable { contentClick(content) }
+ ) {
+ thumbnail(content)
+ }
+ }
+ }
+ }
+}
+
+@Composable
+fun LocationMusicContentView(
+ title: String,
+ contentList: List,
+ baseLocationCategory: BaseLocationCategory,
+ viewTitleClick: () -> Unit,
+ contentClick: (Content) -> Unit,
+ categoryClick: (BaseLocationCategory) -> Unit,
+) {
+ horizontalScrollContentView(
+ contentList = contentList,
+ titleBar = {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .padding(horizontal = 16.dp, vertical = 5.dp)
+ .fillMaxWidth()
+ ) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(4.dp),
+ modifier = Modifier.clickable { viewTitleClick() }
+ ) {
+ Text(
+ text = title,
+ style = TextStyle(
+ fontSize = 18.sp,
+ fontWeight = FontWeight.Bold,
+ )
+ )
+ Icon(
+ painter = painterResource(id = R.drawable.btn_main_arrow_more),
+ contentDescription = null,
+ modifier = Modifier.size(16.dp)
+ )
+ }
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(16.dp)
+ ) {
+ BaseLocationCategory.entries.forEach { category ->
+ ClickableText(
+ text = AnnotatedString(category.mean),
+ onClick = { categoryClick(category) },
+ style = TextStyle(
+ color = if (category == baseLocationCategory) Color.Blue else Color.Unspecified
+ )
+ )
+ }
+ }
+ }
+ },
+ thumbnail = { content ->
+ Box(contentAlignment = Alignment.BottomEnd) {
+ content.image?.let {
+ Image(
+ painter = painterResource(id = it),
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = Modifier
+ .size(128.dp)
+ .clip(RoundedCornerShape(8.dp))
+ )
+ }
+ Icon(
+ painter = painterResource(id = R.drawable.btn_miniplayer_play),
+ contentDescription = null,
+ tint = Color.White,
+ modifier = Modifier.size(48.dp)
+ )
+ }
+ },
+ contentClick = contentClick,
+ )
+}
+
+@Composable
+fun PodcastCollectionView(
+ title: String,
+ contentList: List,
+ contentClick: (Content) -> Unit,
+) {
+ horizontalScrollContentView(
+ contentList = contentList,
+ titleBar = {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.padding(horizontal = 16.dp)
+ ) {
+ Text(
+ text = title,
+ style = TextStyle(
+ fontSize = 18.sp,
+ fontWeight = FontWeight.Bold,
+ )
+ )
+ }
+ },
+ thumbnail = { content ->
+ content.image?.let {
+ Image(
+ painter = painterResource(id = it),
+ contentScale = ContentScale.Crop,
+ contentDescription = null,
+ modifier = Modifier
+ .size(128.dp)
+ .clip(RoundedCornerShape(8.dp))
+ )
+ }
+ },
+ contentClick = contentClick,
+ )
+}
+
+@Composable
+fun VideoCollectionView(
+ title: String,
+ contentList: List,
+ contentClick: (Content) -> Unit,
+) {
+ horizontalScrollContentView(
+ contentList = contentList,
+ titleBar = {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier.padding(horizontal = 16.dp)
+ ) {
+ Text(
+ text = title,
+ style = TextStyle(
+ fontSize = 18.sp,
+ fontWeight = FontWeight.Bold,
+ )
+ )
+ }
+ },
+ thumbnail = { content ->
+ Box(contentAlignment = Alignment.BottomEnd) {
+ content.image?.let {
+ Image(
+ painter = painterResource(id = it),
+ contentDescription = null,
+ contentScale = ContentScale.FillHeight,
+ modifier = Modifier
+ .width(228.dp)
+ .height(128.dp)
+ .clip(RoundedCornerShape(8.dp))
+ )
+ }
+ Box(
+ modifier = Modifier
+ .padding(8.dp)
+ .background(color = Color.Black.copy(alpha = 0.5f))
+ ) {
+ Text(
+ text = "${"%02d".format(content.length / 60)}:${content.length % 60}",
+ style = TextStyle(
+ fontSize = 10.sp,
+ color = Color.White,
+ ),
+ modifier = Modifier.padding(4.dp),
+ )
+ }
+ }
+ },
+ contentClick = contentClick
+ )
+}
+
+
+
+
+
diff --git a/app/src/main/java/umc/study/umc_7th/MainActivity.kt b/app/src/main/java/com/example/umc_7th/home/MainActivity.kt
similarity index 69%
rename from app/src/main/java/umc/study/umc_7th/MainActivity.kt
rename to app/src/main/java/com/example/umc_7th/home/MainActivity.kt
index dd57dae..8f1197f 100644
--- a/app/src/main/java/umc/study/umc_7th/MainActivity.kt
+++ b/app/src/main/java/com/example/umc_7th/home/MainActivity.kt
@@ -1,6 +1,9 @@
-package umc.study.umc_7th
+package com.example.umc_7th.home
import android.os.Build
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
import androidx.annotation.RequiresApi
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
@@ -8,14 +11,12 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxHeight
-import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.verticalScroll
+import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
@@ -23,39 +24,38 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.LineBreak
-import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import com.example.umc_7th.R
import java.time.LocalDate
import java.time.format.DateTimeFormatter
-
@RequiresApi(Build.VERSION_CODES.P)
@Composable
fun MainBanner(
- title1 : String,
- title2 : String,
- date : LocalDate,
- contentList : List,
- backgroundImage: ImageBitmap,
- textColor : Color,
- MikeButtonClick : ()-> Unit,
- TicketButtonClick : ()-> Unit,
- SettingButtonClick : ()-> Unit,
- PlayButtonClick : () -> Unit
-){
- Box{
- Image(bitmap = backgroundImage,
- contentDescription =null,
+ title1: String,
+ title2: String,
+ date: LocalDate,
+ contentList: List,
+ backgroundImage: Int,
+ textColor: Color,
+ MikeButtonClick: () -> Unit,
+ TicketButtonClick: () -> Unit,
+ SettingButtonClick: () -> Unit,
+ PlayButtonClick: () -> Unit
+) {
+ Box {
+ Image(
+ painter = painterResource(id = backgroundImage),
+ contentDescription = null,
contentScale = ContentScale.Crop,
- modifier = Modifier.matchParentSize())
+ modifier = Modifier.matchParentSize()
+ )
Column(
modifier = Modifier.padding(14.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
@@ -63,7 +63,7 @@ fun MainBanner(
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.End
- ){
+ ) {
listOf(
MikeButtonClick to R.drawable.btn_main_mike,
TicketButtonClick to R.drawable.btn_main_ticket,
@@ -105,7 +105,7 @@ fun MainBanner(
.fillMaxWidth()
.padding(end = 16.dp),
horizontalArrangement = Arrangement.End
- ){
+ ) {
IconButton(onClick = PlayButtonClick,
modifier = Modifier.size(60.dp)
) {
@@ -119,9 +119,10 @@ fun MainBanner(
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(10.dp)
- ){
- Text(text = "총 ${contentList.size}곡",color =textColor)
- Text(text = date.format(DateTimeFormatter.ofPattern("yyyy.MM.dd")),
+ ) {
+ Text(text = "총 ${contentList.size}곡", color = textColor)
+ Text(
+ text = date.format(DateTimeFormatter.ofPattern("yyyy.MM.dd")),
color = textColor,
)
}
@@ -129,16 +130,15 @@ fun MainBanner(
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.height(100.dp)
) {
- items(count = contentList.size) {index ->
- val content = contentList[index]
+ items(contentList) { content ->
Row(
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.spacedBy(16.dp),
- modifier = Modifier.clickable { }
- ){
+ modifier = Modifier.clickable { /* Handle click */ }
+ ) {
content.image?.let {
Image(
- bitmap = it,
+ painter = painterResource(id = it),
contentDescription = null,
modifier = Modifier.size(40.dp)
)
@@ -148,42 +148,46 @@ fun MainBanner(
) {
Text(text = content.title, color = textColor)
Text(text = content.author, color = textColor)
-
}
}
}
}
}
}
-
-
}
-@RequiresApi(Build.VERSION_CODES.P)
-@Preview
-@Composable
-fun PreviewBanner(){
- MainBanner(
- title1 = "포근하게 덮어주는 꿈의",
- title2 = "목소리",
- date = LocalDate.parse("2019-11-11"),
- contentList = List(15){
- Content(
- title = "Butter",
- author = "BTS",
- image = ImageBitmap.imageResource(id = R.drawable.img_album_exp),
- length = 200,
+class MainActivity : ComponentActivity() {
+ @RequiresApi(Build.VERSION_CODES.P)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ MainBanner(
+ title1 = "포근하게 덮어주는 꿈의",
+ title2 = "목소리",
+ date = LocalDate.parse("2019-11-11"),
+ contentList = List(15) {
+ Content(
+ title = "Butter",
+ author = "BTS",
+ image = R.drawable.img_album_exp,
+ length = 200,
+ )
+ },
+ backgroundImage = R.drawable.img_default_4_x_1,
+ textColor = Color.White,
+ MikeButtonClick = { /*TODO*/ },
+ TicketButtonClick = { /*TODO*/ },
+ SettingButtonClick = { /*TODO*/ },
+ PlayButtonClick = { /*TODO*/ }
)
- },
- backgroundImage = ImageBitmap.imageResource(id = R.drawable.img_default_4_x_1) ,
- textColor =Color.White ,
- MikeButtonClick = { /*TODO*/ },
- TicketButtonClick = { /*TODO*/ },
- SettingButtonClick = { /*TODO*/ }) {
-
+ }
}
}
+
+
+
+
diff --git a/app/src/main/java/com/example/umc_7th/home/MainBanner.kt b/app/src/main/java/com/example/umc_7th/home/MainBanner.kt
new file mode 100644
index 0000000..30fcefb
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/home/MainBanner.kt
@@ -0,0 +1,175 @@
+package com.example.umc_7th.home
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.example.umc_7th.etc.Content
+import com.example.umc_7th.R
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+data class Content(
+ val title: String,
+ val author: String,
+ val image: Int,
+ val length: Int
+)
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Composable
+fun MainBanner(
+ title1: String,
+ date: LocalDate,
+ contentList: List,
+ backgroundImage: Painter,
+ textColor: Color,
+ MikeButtonClick: () -> Unit,
+ TicketButtonClick: () -> Unit,
+ SettingButtonClick: () -> Unit,
+ PlayButtonClick: () -> Unit
+) {
+ Box {
+ Image(
+ painter = backgroundImage,
+ contentDescription = null,
+ contentScale = ContentScale.Crop,
+ modifier = Modifier.fillMaxWidth()
+ )
+ Column(
+ modifier = Modifier.padding(14.dp),
+ verticalArrangement = Arrangement.spacedBy(16.dp)
+ ) {
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.End
+ ) {
+ listOf(
+ MikeButtonClick to R.drawable.btn_main_mike,
+ TicketButtonClick to R.drawable.btn_main_ticket,
+ SettingButtonClick to R.drawable.btn_main_setting
+ ).forEach { (onClick, icon) ->
+ Icon(
+ painter = painterResource(id = icon),
+ contentDescription = null,
+ tint = textColor,
+ modifier = Modifier
+ .size(40.dp)
+ .padding(end = 8.dp)
+ .clickable { onClick() }
+ )
+ }
+ }
+ Column {
+ Text(
+ text = title1,
+ style = TextStyle(
+ color = textColor,
+ fontSize = 29.sp,
+ fontWeight = FontWeight.Bold
+ )
+ )
+ }
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(end = 16.dp),
+ horizontalArrangement = Arrangement.End
+ ) {
+ IconButton(
+ onClick = PlayButtonClick,
+ modifier = Modifier.size(60.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.btn_panel_play_large),
+ contentDescription = null,
+ tint = textColor
+ )
+ }
+ }
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(10.dp)
+ ) {
+ Text(text = "총 ${contentList.size}곡", color = textColor)
+ Text(
+ text = date.format(DateTimeFormatter.ofPattern("yyyy.MM.dd")),
+ color = textColor
+ )
+ }
+ LazyColumn(
+ verticalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = Modifier.height(100.dp)
+ ) {
+ items(count = contentList.size) { index ->
+ val content = contentList[index]
+ Row(
+ verticalAlignment = Alignment.Top,
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = Modifier.clickable { }
+ ) {
+ Image(
+ painter = painterResource(id = content.image),
+ contentDescription = null,
+ modifier = Modifier.size(40.dp)
+ )
+ Column(
+ verticalArrangement = Arrangement.spacedBy(4.dp)
+ ) {
+ Text(text = content.title, color = textColor)
+ Text(text = content.author, color = textColor)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Preview
+@Composable
+fun PreviewBanner() {
+ MainBanner(
+ title1 = "포근하게 덮어주는 꿈의 목소리",
+ date = LocalDate.parse("2019-11-11"),
+ contentList = List(15) {
+ Content(
+ title = "Butter",
+ author = "BTS",
+ image = R.drawable.img_album_exp,
+ length = 200
+ )
+ },
+ backgroundImage = painterResource(id = R.drawable.img_default_4_x_1),
+ textColor = Color.White,
+ MikeButtonClick = { /* TODO */ },
+ TicketButtonClick = { /* TODO */ },
+ SettingButtonClick = { /* TODO */ },
+ PlayButtonClick = { /* TODO */ }
+ )
+}
diff --git a/app/src/main/java/com/example/umc_7th/home/Promotion.kt b/app/src/main/java/com/example/umc_7th/home/Promotion.kt
new file mode 100644
index 0000000..a36d6b0
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/home/Promotion.kt
@@ -0,0 +1,41 @@
+package com.example.umc_7th.home
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.painter.Painter
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.dp
+import com.example.umc_7th.R
+
+@Composable
+fun Promotion(
+ image: Painter,
+ padding: Dp = 0.dp,
+ onClicked: () -> Unit
+) {
+ Box(modifier = Modifier.padding(padding)) {
+ Image(
+ painter = image,
+ contentDescription = null,
+ modifier = Modifier.clickable { onClicked() }
+ )
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun PreviewPromotion() {
+ val image = painterResource(id = R.drawable.img_home_viewpager_exp2)
+ Promotion(
+ image = image,
+ padding = 8.dp,
+ onClicked = {}
+ )
+}
+
diff --git a/app/src/main/java/umc/study/umc_7th/sns.kt b/app/src/main/java/com/example/umc_7th/home/snsSharebar.kt
similarity index 65%
rename from app/src/main/java/umc/study/umc_7th/sns.kt
rename to app/src/main/java/com/example/umc_7th/home/snsSharebar.kt
index 39e9f31..1eecc4c 100644
--- a/app/src/main/java/umc/study/umc_7th/sns.kt
+++ b/app/src/main/java/com/example/umc_7th/home/snsSharebar.kt
@@ -1,40 +1,21 @@
-package umc.study.umc_7th
+package com.example.umc_7th.home
import android.os.Build
import androidx.annotation.RequiresApi
-import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
-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.lazy.LazyColumn
-import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
-import androidx.compose.material3.IconButton
-import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.style.LineBreak
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-import java.time.LocalDate
-import java.time.format.DateTimeFormatter
+import com.example.umc_7th.R
+
@RequiresApi(Build.VERSION_CODES.P)
@Composable
fun snsSharebar(
@@ -76,3 +57,5 @@ fun PreviewsnsSharebar(){
twitterClick = { /* */})
}
+
+
diff --git a/app/src/main/java/com/example/umc_7th/locker/LockerFragement.kt b/app/src/main/java/com/example/umc_7th/locker/LockerFragement.kt
new file mode 100644
index 0000000..33fd5c2
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/locker/LockerFragement.kt
@@ -0,0 +1,171 @@
+// 파일 경로: com.example.umc_7th.locker
+
+package com.example.umc_7th.locker
+
+import android.annotation.SuppressLint
+import androidx.compose.runtime.Composable
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.pager.HorizontalPager
+import androidx.compose.foundation.pager.rememberPagerState
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Tab
+import androidx.compose.material3.TabRowDefaults
+import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
+import androidx.compose.material3.Text
+import androidx.compose.material3.Scaffold
+import androidx.compose.material3.ScrollableTabRow
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.ImageBitmap
+import androidx.compose.ui.res.imageResource
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.navigation.NavController
+import kotlinx.coroutines.launch
+import com.example.umc_7th.etc.Content
+import com.example.umc_7th.R
+
+@Composable
+fun LockerFragment1(){
+ Column(
+ verticalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = Modifier
+ .padding(16.dp)
+ .background(color = Color.White)
+
+ ){
+ Box(
+ modifier = Modifier.fillMaxWidth()
+ ){
+ Row(
+ modifier = Modifier.align(Alignment.CenterStart)
+ ){
+ Text(text = "보관함", fontWeight = FontWeight.Bold, color = Color.Black, fontSize = 24.sp)
+ }
+ Row(
+ modifier = Modifier.align(Alignment.CenterEnd)
+ ){
+ Text(text = "로그인", color = Color.Blue)
+ }
+ }
+ }
+}
+
+@Composable
+fun LockerTab(){
+ val pages= listOf("저장한 곡", "음악파일")
+ val pagerState= rememberPagerState { pages.size }
+ val coroutineScope = rememberCoroutineScope()
+ Column {
+ ScrollableTabRow(
+ selectedTabIndex = pagerState.currentPage,
+ containerColor = Color.White,
+ edgePadding = 0.dp,
+ indicator = { tabPositions ->
+ TabRowDefaults.Indicator(
+ modifier = Modifier
+ .tabIndicatorOffset(tabPositions[pagerState.currentPage])
+ .padding(horizontal = tabPositions[pagerState.currentPage].width / 4),
+ color = Color.Blue,
+ height = 2.dp
+ )
+ }
+ ) {
+ pages.forEachIndexed { index, title ->
+ Tab(
+ text = { Text(text = title, fontSize = 16.sp, color = if (pagerState.currentPage == index) Color.Blue else Color.Black) },
+ selected = pagerState.currentPage == index,
+ onClick = {
+ coroutineScope.launch { pagerState.animateScrollToPage(index) }
+ }
+ )
+ }
+ }
+ HorizontalPager(state = pagerState, modifier = Modifier.fillMaxWidth()) { page ->
+ when (page) {
+ 0 -> LockerMusic(
+ selectAllButtonClick = {},
+ playAllButtonClick = {},
+ contentList = listOf(
+ Content("Butter", "BTS", R.drawable.img_album_exp, 200),
+ Content("Next Level", "aespa", R.drawable.img_album_exp3, 210),
+ )
+ )
+ 1 -> Text("음악 파일") // Placeholder for music files page
+ }
+ }
+ }
+}
+
+@Composable
+fun LockerMusic(
+ selectAllButtonClick: () -> Unit,
+ playAllButtonClick: () -> Unit,
+ contentList: List
+) {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(16.dp)
+ ) {
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ Text(
+ text = "저장한 곡",
+ fontWeight = FontWeight.Bold,
+ fontSize = 20.sp,
+ color = Color.Black
+ )
+ Row {
+ Text(
+ text = "전체 선택",
+ color = Color.Blue,
+ modifier = Modifier.clickable { selectAllButtonClick() }
+ )
+ Spacer(modifier = Modifier.width(8.dp))
+ Text(
+ text = "모두 재생",
+ color = Color.Blue,
+ modifier = Modifier.clickable { playAllButtonClick() }
+ )
+ }
+ }
+
+ LazyColumn {
+ items(contentList) { content ->
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = 8.dp)
+ ) {
+ content.image?.let {
+ Image(
+ painter = painterResource(id = it),
+ contentDescription = null,
+ modifier = Modifier.size(64.dp)
+ )
+ }
+ Spacer(modifier = Modifier.width(8.dp))
+ Column {
+ Text(text = content.title, fontWeight = FontWeight.Bold)
+ Text(text = content.author, color = Color.Gray)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/umc_7th/locker/LockerMusic.kt b/app/src/main/java/com/example/umc_7th/locker/LockerMusic.kt
new file mode 100644
index 0000000..2209470
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/locker/LockerMusic.kt
@@ -0,0 +1,178 @@
+package com.example.umc_7th.locker
+
+import android.annotation.SuppressLint
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateMapOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+
+import com.example.umc_7th.R
+
+// Content 클래스 정의
+data class Content(
+ val title: String,
+ val author: String,
+ val image: Int? // 이미지 리소스 ID (nullable)
+)
+
+@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
+@Composable
+fun LockerMusic(
+ selectAllButtonClick: () -> Unit,
+ playAllButtonClick: () -> Unit,
+ contentList: List,
+) {
+ var contentList by remember { mutableStateOf(contentList.toMutableList()) }
+
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ ) {
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(8.dp, vertical = 12.dp)
+ ) {
+ var selected by remember { mutableStateOf(false) }
+ Row {
+ Row(
+ modifier = Modifier
+ .clickable { selectAllButtonClick() }
+ ) {
+ Icon(
+ painter = painterResource(
+ id = if (!selected) R.drawable.btn_playlist_select_off
+ else R.drawable.btn_playlist_select_on
+ ),
+ contentDescription = null,
+ modifier = Modifier.size(23.dp)
+ )
+ Text(
+ text = "전체 선택",
+ fontSize = 16.sp,
+ color = if (!selected) Color.Black.copy(0.5f) else Color.Blue
+ )
+ }
+ Spacer(modifier = Modifier.width(16.dp))
+ Row(
+ modifier = Modifier.clickable { playAllButtonClick() },
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.icon_browse_arrow_right),
+ contentDescription = null,
+ modifier = Modifier.size(23.dp)
+ )
+ Text(
+ text = "전체 듣기",
+ color = Color.Black.copy(0.5f),
+ fontSize = 16.sp
+ )
+ }
+ }
+
+ Row(
+ modifier = Modifier.align(Alignment.CenterEnd),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(text = "편집", fontSize = 16.sp, color = Color.Black.copy(0.5f))
+ Spacer(modifier = Modifier.width(8.dp))
+ }
+ }
+
+ val itemStates = remember { mutableStateMapOf().apply { contentList.forEach { put(it, false) } } }
+
+ LazyColumn(
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ modifier = Modifier.fillMaxWidth()
+ ) {
+ items(contentList) { content ->
+ val isSelected = itemStates[content] ?: false
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .background(if (!isSelected) Color.Unspecified else Color.Blue.copy(0.05f))
+ .clickable { itemStates[content] = !isSelected }
+ ) {
+ Row(
+ modifier = Modifier.padding(horizontal = 8.dp)
+ ) {
+ content.image?.let {
+ Image(
+ painter = painterResource(id = it),
+ contentDescription = null,
+ modifier = Modifier
+ .size(50.dp)
+ .clip(RoundedCornerShape(3.dp))
+ )
+ }
+ Column(
+ modifier = Modifier
+ .align(Alignment.CenterVertically)
+ .padding(horizontal = 8.dp)
+ ) {
+ Text(
+ text = content.title,
+ modifier = Modifier.padding(bottom = 2.dp),
+ fontWeight = FontWeight.Bold,
+ fontSize = 16.sp
+ )
+ Text(
+ text = content.author,
+ color = Color.Black.copy(0.5f),
+ fontSize = 14.sp
+ )
+ }
+ }
+ Row(
+ modifier = Modifier.align(Alignment.CenterEnd).padding(8.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.btn_player_play),
+ contentDescription = null,
+ modifier = Modifier.size(30.dp)
+ )
+ Icon(
+ painter = painterResource(id = R.drawable.btn_player_more),
+ contentDescription = null,
+ modifier = Modifier.size(30.dp).clickable {
+ contentList = contentList.filter { it != content }.toMutableList()
+ }
+ )
+ }
+ }
+ Spacer(modifier = Modifier.padding(5.dp))
+ }
+ }
+ }
+}
+
+
diff --git a/app/src/main/java/com/example/umc_7th/song/ContentFrame.kt b/app/src/main/java/com/example/umc_7th/song/ContentFrame.kt
new file mode 100644
index 0000000..54b36ee
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/song/ContentFrame.kt
@@ -0,0 +1,108 @@
+package com.example.umc_7th.song
+
+import android.app.Application
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.painterResource
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.example.umc_7th.R
+import com.example.umc_7th.etc.FakeSongViewModel
+import com.example.umc_7th.etc.SongViewModel
+
+@Composable
+fun ContentFrame(
+ viewModel: SongViewModel,
+ toSingerinfoClick: () -> Unit,
+) {
+ // LiveData 관찰
+ val currentSong by viewModel.currentSong.observeAsState()
+ val like by viewModel.like.observeAsState(false)
+ val unLike by viewModel.unLike.observeAsState(false)
+
+ currentSong?.let { content ->
+ Column(horizontalAlignment = Alignment.CenterHorizontally) {
+ Text(
+ text = content.title,
+ fontSize = 24.sp,
+ fontWeight = FontWeight.Bold
+ )
+
+ Row {
+ Text(text = content.author, fontSize = 18.sp)
+ Icon(
+ painter = painterResource(id = R.drawable.btn_arrow_more),
+ contentDescription = null,
+ modifier = Modifier.clickable { toSingerinfoClick() }
+ )
+ }
+ Spacer(modifier = Modifier.height(18.dp))
+
+ content.image?.let { imageId ->
+ Image(
+ painter = painterResource(id = imageId), // 수정된 부분
+ contentDescription = null,
+ modifier = Modifier
+ .size(220.dp)
+ .clip(RoundedCornerShape(20.dp)),
+ contentScale = ContentScale.Crop
+ )
+ }
+ Spacer(modifier = Modifier.height(18.dp))
+
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .size(36.dp),
+ horizontalArrangement = Arrangement.Center
+ ) {
+ IconButton(onClick = { viewModel.toggleLike() }) {
+ Image(
+ painter = painterResource(id = if (like) R.drawable.ic_my_like_on else R.drawable.ic_my_like_off),
+ contentDescription = null,
+ contentScale = ContentScale.Crop
+ )
+ }
+ Spacer(modifier = Modifier.padding(10.dp))
+ IconButton(onClick = { viewModel.toggleUnLike() }) {
+ Icon(
+ painter = painterResource(id = if (unLike) R.drawable.btn_player_unlike_off else R.drawable.btn_player_unlike_on),
+ contentDescription = null
+ )
+ }
+ }
+ }
+ } ?: run {
+ Text(
+ text = "곡 정보가 없습니다.",
+ fontSize = 16.sp,
+ color = Color.Gray
+ )
+ }
+}
+
+@Composable
+@Preview(showBackground = true)
+fun PreviewContentFrame() {
+ // FakeSongViewModel을 사용하여 Preview에서 테스트
+ ContentFrame(
+ viewModel = FakeSongViewModel(Application()),
+ toSingerinfoClick = {},
+ )
+}
+
+
+
diff --git a/app/src/main/java/com/example/umc_7th/song/Lyric.kt b/app/src/main/java/com/example/umc_7th/song/Lyric.kt
new file mode 100644
index 0000000..2e252ed
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/song/Lyric.kt
@@ -0,0 +1,39 @@
+package com.example.umc_7th.song
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.text.style.TextAlign
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+
+@Composable
+fun Lyric(
+ lyric1 : String,
+ lyric2 : String,
+){
+ Column(
+ modifier = Modifier
+ .width(120.dp)
+ .height(50.dp),
+ verticalArrangement = Arrangement.Center,
+ horizontalAlignment = Alignment.CenterHorizontally
+
+
+ ) {
+ Text(text = lyric1, textAlign = TextAlign.Center)
+ Text(text = lyric2, textAlign =TextAlign.Center)
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun PreviewLyric(){
+ Lyric(lyric1 = "내리는 꽃가루에", lyric2 = "눈이 따끔해 아야")
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/umc_7th/song/MiniPlayer.kt b/app/src/main/java/com/example/umc_7th/song/MiniPlayer.kt
new file mode 100644
index 0000000..fc8fe25
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/song/MiniPlayer.kt
@@ -0,0 +1,154 @@
+package com.example.umc_7th.song
+
+import android.os.Build
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import androidx.compose.material3.Slider
+import umc.study.umc_7th.Content
+import umc.study.umc_7th.R
+import umc.study.umc_7th.SongViewModel
+
+
+@OptIn(ExperimentalMaterial3Api::class)
+@RequiresApi(Build.VERSION_CODES.P)
+@Composable
+fun MiniPlayer(
+ viewModel: SongViewModel,
+
+ beforeSongPlayButtonClick: () -> Unit,
+ playSongButtonClick: () -> Unit,
+ nextSongPlayButtonClick: () -> Unit,
+ musicQueueClick: () -> Unit,
+ toSongActivity: (Content) -> Unit,
+){
+ val currentSong by viewModel.currentSong.observeAsState()
+
+ currentSong?.let{ content ->
+ Column {
+ val currentPosition by viewModel.currentPosition.observeAsState(0f)
+ val duration by viewModel.duration.observeAsState(1f)
+
+ val progress = currentPosition / duration
+
+ Slider(
+ value = progress,
+ onValueChange = { newProgress ->
+ viewModel.updatePosition(newProgress * duration)
+ },
+ modifier = Modifier
+ .fillMaxWidth().height(3.dp),
+ thumb = {},
+ )
+ Box(modifier = Modifier.clickable {toSongActivity(content) }
+ )
+ {
+ Row(
+ modifier = Modifier
+ .background(color = Color.White)
+ .fillMaxWidth()
+ .padding(horizontal = 15.dp, vertical = 8.dp),
+ horizontalArrangement = Arrangement.spacedBy(120.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ){
+ Column(
+ verticalArrangement = Arrangement.spacedBy(1.dp)
+ ){
+ Text(text = content.title,
+ fontSize = 18.sp,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis)
+ Text(
+ text = content.author,
+ fontSize = 15.sp,
+ style = TextStyle(
+ color = TextStyle.Default.color.copy(alpha = 0.5f)
+ ),
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis
+ )
+ }
+ Row(
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically
+ ){ val played by viewModel.played.observeAsState(true)
+ Icon(painter = painterResource(id = R.drawable.btn_miniplayer_previous),
+ contentDescription = null,
+ modifier = Modifier
+ .size(50.dp)
+ .clickable { beforeSongPlayButtonClick() })
+ Icon(painter = painterResource(id = if(played) R.drawable.btn_miniplay_pause
+ else R.drawable.btn_miniplayer_play
+ ),
+ contentDescription = null,
+ modifier = Modifier
+ .size(40.dp)
+ .clickable {
+ viewModel.togglePlayed()
+ playSongButtonClick()
+ })
+ Icon(painter = painterResource(id = R.drawable.btn_miniplayer_next),
+ contentDescription = null,
+ modifier = Modifier
+ .size(50.dp)
+ .clickable { nextSongPlayButtonClick() })
+ Icon(painter = painterResource(id = R.drawable.btn_miniplayer_go_list),
+ contentDescription = null,
+ modifier = Modifier
+ .size(45.dp)
+ .clickable { musicQueueClick() })
+ }
+ }
+ }
+ }
+ }?:run {
+ Box(modifier = Modifier.fillMaxWidth()
+ .padding(16.dp).background(Color.LightGray)){
+ Text(text="현재 재생 중인 곡이 없습니다.",
+ fontSize = 18.sp,
+ color= Color.Gray,
+ modifier = Modifier.align(Alignment.Center))
+ }
+ }
+
+
+
+
+
+}
+
+//@RequiresApi(Build.VERSION_CODES.P)
+//@Preview(showBackground = true)
+//@Composable
+//fun PreviewMiniPlayer(){
+// val fakeSongViewModel = FakeSongViewModel(application = Application())
+// MiniPlayer(
+// viewModel = fakeSongViewModel,
+// beforeSongPlayButtonClick = { /*TODO*/ },
+// playSongButtonClick = { /*TODO*/ },
+// nextSongPlayButtonClick = { /*TODO*/ },
+// musicQueueClick = { /*TODO*/ },
+// toSongActivity = {})
+//}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/umc_7th/song/PlayProgreeBar.kt b/app/src/main/java/com/example/umc_7th/song/PlayProgreeBar.kt
new file mode 100644
index 0000000..3d38829
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/song/PlayProgreeBar.kt
@@ -0,0 +1,156 @@
+package com.example.umc_7th.song
+
+import android.app.Application
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Slider
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import umc.study.umc_7th.FakeSongViewModel
+import umc.study.umc_7th.R
+import umc.study.umc_7th.SongViewModel
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+fun PlayProgressBar(
+ viewModel : SongViewModel,
+ beforeSongPlayClick : () -> Unit,
+ songPlayButtonClick: () -> Unit,
+ nextSongPlayClick : ()-> Unit,
+
+ ){
+ val replay by viewModel.replay.observeAsState(false)
+ val shuffle by viewModel.shuffle.observeAsState(false)
+
+ val played by viewModel.played.observeAsState(false)
+ val currentPosition by viewModel.currentPosition.observeAsState(0f)
+ val duration by viewModel.duration.observeAsState(1f)
+
+ var progress by remember { mutableStateOf(0f) }
+
+// LaunchedEffect(played){
+// if(played){
+// while ( played && currentPosition < duration){
+// delay(1000L)
+// viewModel.updatePosition(currentPosition+1f)
+// }
+// }
+// }
+ progress = currentPosition / duration
+ Slider(
+ value = progress,
+ onValueChange = { newProgress ->
+ viewModel.updatePosition(newProgress * duration)
+ },
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(3.dp),
+ thumb = {
+
+ },
+ )
+ Row(
+
+ horizontalArrangement = Arrangement.SpaceBetween,
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(vertical = 5.dp, horizontal = 10.dp)
+ ){
+ Text(text = formatTime(currentPosition), fontSize = 12.sp, color= Color.Blue)
+ Text(text = formatTime(duration), fontSize = 12.sp)
+ }
+
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(top = 20.dp),
+ horizontalArrangement = Arrangement.Center,
+ ){
+
+ Icon(
+ painter = painterResource(id = R.drawable.nugu_btn_repeat_inactive),
+ contentDescription = null,
+ modifier = Modifier
+ .size(65.dp)
+ .padding(10.dp)
+ .clickable { viewModel.toggleReplay() }
+ , tint = if (replay) Color.Blue else Color.Black
+ )
+ Spacer(modifier = Modifier.padding(10.dp))
+ Icon(
+ painter = painterResource(id = R.drawable.nugu_btn_skip_previous_32),
+ contentDescription = null,
+ modifier = Modifier
+ .size(65.dp)
+ .padding(10.dp)
+ .clickable { beforeSongPlayClick()
+ }
+
+ )
+
+ Icon(
+ painter = painterResource(id = if(played) R.drawable.nugu_btn_pause_32
+ else R.drawable.nugu_btn_play_32
+ ),
+ contentDescription = null,
+ modifier = Modifier
+ .size(65.dp)
+ .padding(10.dp)
+ .clickable {
+ viewModel.togglePlayed()
+ songPlayButtonClick()
+ }
+ )
+
+ Icon(
+ painter = painterResource(id = R.drawable.nugu_btn_skip_next_32),
+ contentDescription = null,
+ modifier = Modifier
+ .size(65.dp)
+ .padding(10.dp)
+ .clickable { nextSongPlayClick() }
+ )
+ Spacer(modifier = Modifier.padding(10.dp))
+ Icon(
+ painter = painterResource(id = R.drawable.nugu_btn_random_inactive),
+ contentDescription = null,
+ modifier = Modifier
+ .size(65.dp)
+ .padding(10.dp)
+ .clickable { viewModel.toggleShuffle() },
+ tint = if (shuffle) Color.Blue else Color.Black
+ )
+
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun PreviewPlayProgressBar(){
+ val fakeSongViewModel = FakeSongViewModel(application = Application())
+ PlayProgressBar(
+ viewModel = fakeSongViewModel,
+ beforeSongPlayClick = { /*TODO*/ },
+ songPlayButtonClick = { /*TODO*/ },
+ nextSongPlayClick = {}
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/umc_7th/song/SongActivity.kt b/app/src/main/java/com/example/umc_7th/song/SongActivity.kt
new file mode 100644
index 0000000..da41e0b
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/song/SongActivity.kt
@@ -0,0 +1,120 @@
+package com.example.umc_7th.song
+
+import android.app.Application
+import android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import androidx.activity.compose.setContent
+import androidx.annotation.RequiresApi
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import umc.study.umc_7th.ui.theme.Umc_7thTheme
+import androidx.activity.ComponentActivity
+import androidx.compose.foundation.rememberScrollState
+import umc.study.umc_7th.FakeSongViewModel
+import umc.study.umc_7th.MyApplication
+import umc.study.umc_7th.SongViewModel
+import umc.study.umc_7th.main.home.MainActivity
+import umc.study.umc_7th.main.home.SongSnsBar
+
+class SongActivity : ComponentActivity() {
+
+ @RequiresApi(Build.VERSION_CODES.P)
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val viewModel = (application as MyApplication).songViewModel
+
+ setContent {
+
+ Umc_7thTheme {
+ Box(){
+ SongPlayerScreen(
+ viewModel= viewModel,
+ toMainActivity = {
+ val intent = Intent(this@SongActivity, MainActivity::class.java)
+ startActivity(intent)
+ finish()
+ },)
+ }
+
+
+
+
+ }
+
+ }
+ }
+}
+
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Composable
+fun SongPlayerScreen(
+ viewModel: SongViewModel,
+ toMainActivity : () -> Unit,
+){
+ Column (modifier = Modifier
+ .verticalScroll(rememberScrollState())
+ .fillMaxHeight()
+ .padding(8.dp)
+ ,
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.spacedBy(10.dp)
+ ){
+ SongTopButton(
+ SettingButtonClick = {},
+ eqButtonClick = {},
+ songActivityToMainActivity = { toMainActivity() }
+ )
+
+ ContentFrame(
+
+ toSingerinfoClick={},
+ likeClick ={},
+ unLikeButtonClick={},
+ viewModel = viewModel
+ )
+
+ Lyric(lyric1 = "내리는 꽃가루에", lyric2 = "눈이 따끔해 아야")
+
+ PlayProgressBar(
+ viewModel = viewModel,
+ beforeSongPlayClick = { /*TODO*/ },
+ songPlayButtonClick = { /*TODO*/ },
+ nextSongPlayClick = {}
+ )
+ SongSnsBar(
+ instagramShareClick = { /*TODO*/ },
+ similarSongButtonClick = { /*TODO*/ },
+ musicQueueClick ={}
+ )
+ }
+}
+
+
+fun formatTime(timeInSeconds:Float) : String{
+ val minutes = (timeInSeconds / 60).toInt()
+ val seconds = (timeInSeconds % 60).toInt()
+ return String.format("%02d:%02d", minutes, seconds)
+}
+
+
+@RequiresApi(Build.VERSION_CODES.P)
+@Preview(showBackground = true)
+@Composable
+fun PreviewSongPlayerScreen(){
+ val fakeviewModel = FakeSongViewModel(application = Application())
+ SongPlayerScreen(
+ viewModel = fakeviewModel,
+ toMainActivity = {},
+ )
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/umc_7th/song/SongTopButton.kt b/app/src/main/java/com/example/umc_7th/song/SongTopButton.kt
new file mode 100644
index 0000000..ef69a08
--- /dev/null
+++ b/app/src/main/java/com/example/umc_7th/song/SongTopButton.kt
@@ -0,0 +1,56 @@
+package com.example.umc_7th.song
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Icon
+import androidx.compose.material3.IconButton
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import umc.study.umc_7th.R
+
+@Composable
+fun SongTopButton(
+ SettingButtonClick: () -> Unit,
+ eqButtonClick: () -> Unit,
+ songActivityToMainActivity: () -> Unit
+){
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween
+ ){
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(16.dp)
+ ) {
+ IconButton(onClick = SettingButtonClick,
+ modifier = Modifier.size(36.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.btn_player_setting),
+ contentDescription = null,
+
+ )
+ }
+ IconButton(onClick = eqButtonClick,
+ modifier = Modifier.size(36.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.btn_player_eq_off),
+ contentDescription = null,
+ modifier = Modifier
+ )
+ }
+ }
+ IconButton(onClick = songActivityToMainActivity,
+ modifier = Modifier.size(36.dp)
+ ) {
+ Icon(
+ painter = painterResource(id = R.drawable.nugu_btn_down),
+ contentDescription = null,
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/umc/study/umc_7th/ui/theme/Color.kt b/app/src/main/java/com/example/umc_7th/ui/theme/Color.kt
similarity index 59%
rename from app/src/main/java/umc/study/umc_7th/ui/theme/Color.kt
rename to app/src/main/java/com/example/umc_7th/ui/theme/Color.kt
index 3f2460a..b7de884 100644
--- a/app/src/main/java/umc/study/umc_7th/ui/theme/Color.kt
+++ b/app/src/main/java/com/example/umc_7th/ui/theme/Color.kt
@@ -1,4 +1,4 @@
-package umc.study.umc_7th.ui.theme
+package com.example.umc_7th.ui.theme
import androidx.compose.ui.graphics.Color
@@ -8,4 +8,7 @@ val Pink80 = Color(0xFFEFB8C8)
val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
-val Pink40 = Color(0xFF7D5260)
\ No newline at end of file
+val Pink40 = Color(0xFF7D5260)
+
+// 추가할 파란색 정의
+val Flo = Color(0xFF004AD) // 색상 코드 추가
diff --git a/app/src/main/java/umc/study/umc_7th/ui/theme/Theme.kt b/app/src/main/java/com/example/umc_7th/ui/theme/Theme.kt
similarity index 97%
rename from app/src/main/java/umc/study/umc_7th/ui/theme/Theme.kt
rename to app/src/main/java/com/example/umc_7th/ui/theme/Theme.kt
index c62117a..106792a 100644
--- a/app/src/main/java/umc/study/umc_7th/ui/theme/Theme.kt
+++ b/app/src/main/java/com/example/umc_7th/ui/theme/Theme.kt
@@ -1,4 +1,4 @@
-package umc.study.umc_7th.ui.theme
+package com.example.umc_7th.ui.theme
import android.app.Activity
import android.os.Build
diff --git a/app/src/main/java/umc/study/umc_7th/ui/theme/Type.kt b/app/src/main/java/com/example/umc_7th/ui/theme/Type.kt
similarity index 96%
rename from app/src/main/java/umc/study/umc_7th/ui/theme/Type.kt
rename to app/src/main/java/com/example/umc_7th/ui/theme/Type.kt
index 0242850..1f4399a 100644
--- a/app/src/main/java/umc/study/umc_7th/ui/theme/Type.kt
+++ b/app/src/main/java/com/example/umc_7th/ui/theme/Type.kt
@@ -1,4 +1,4 @@
-package umc.study.umc_7th.ui.theme
+package com.example.umc_7th.ui.theme
import androidx.compose.material3.Typography
import androidx.compose.ui.text.TextStyle
diff --git a/app/src/main/java/umc/study/umc_7th/Content.kt b/app/src/main/java/umc/study/umc_7th/Content.kt
deleted file mode 100644
index ed4fa5a..0000000
--- a/app/src/main/java/umc/study/umc_7th/Content.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package umc.study.umc_7th
-
-import androidx.compose.ui.graphics.ImageBitmap
-import java.time.LocalDate
-import java.util.Date
-import java.util.Dictionary
-
-data class Content(
- val title: String,
- val author : String,
- val image: ImageBitmap?= null,
- val length: Int,
-)
-
-data class Album (
- val albumTitle : String,
- val date : LocalDate,
- val author : String,
- val albumImage: ImageBitmap,
- val trackList : List,
- val titleTrackList : List
-)
\ No newline at end of file
diff --git a/app/src/main/java/umc/study/umc_7th/HorizontalCollection.kt b/app/src/main/java/umc/study/umc_7th/HorizontalCollection.kt
deleted file mode 100644
index 490dbe9..0000000
--- a/app/src/main/java/umc/study/umc_7th/HorizontalCollection.kt
+++ /dev/null
@@ -1,341 +0,0 @@
-package umc.study.umc_7th
-
-import android.icu.text.UnicodeSetSpanner.CountMethod
-import android.os.Build
-import androidx.annotation.RequiresApi
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.background
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Arrangement
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.Spacer
-import androidx.compose.foundation.layout.fillMaxWidth
-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.lazy.LazyRow
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.foundation.text.ClickableText
-import androidx.compose.material3.Icon
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
-import androidx.compose.runtime.setValue
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.clip
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.layout.ContentScale
-import androidx.compose.ui.layout.onGloballyPositioned
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.res.imageResource
-import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.AnnotatedString
-import androidx.compose.ui.text.TextStyle
-import androidx.compose.ui.text.font.FontWeight
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
-
-
-enum class BaseLocationCategory(
- val mean : String
-){
- GLOABAL(mean = "종합"),
- DOMESTIC(mean = "국내"),
- FOREIGN(mean = "해외"),
-}
-@RequiresApi(Build.VERSION_CODES.P)
-@Composable
-fun LocationMusicContentView(
- title : String,
- contentList : List,
- baseLocationCategory: BaseLocationCategory,
- viewTitleClick : () -> Unit,
- contentClick : (Content) -> Unit,
- categoryClick : (BaseLocationCategory) -> Unit,
-){
- horizontalScrollContentView(
- contentList = contentList,
- titleBar = {
- Row (
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier
- .padding(horizontal = 16.dp, vertical = 5.dp)
- .fillMaxWidth()
- ){
- Row(
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.spacedBy(4.dp),
- modifier = Modifier.clickable { viewTitleClick() }
- ){
- Text(
- text = title,
- style = TextStyle(
- fontSize = 18.sp,
- fontWeight = FontWeight.Bold,
- )
- )
- Icon(
- painter = painterResource(id = R.drawable.btn_main_arrow_more),
- contentDescription = null,
- modifier = Modifier.size(16.dp)
- )
- }
- Row(
- horizontalArrangement = Arrangement.spacedBy(16.dp)
- ){
- BaseLocationCategory.entries.forEach{ category ->
- ClickableText(
- text = AnnotatedString(category.mean),
- onClick = { categoryClick(category)},
- style = TextStyle(
- color = if(category == baseLocationCategory) Color.Blue else Color.Unspecified
- )
- )
- }
- }
- }
- },
- thumbnail = { content ->
- Box(
- contentAlignment = Alignment.BottomEnd,
- ){
- content.image?.let {
- Image(bitmap = it,
- contentDescription = null,
- contentScale = ContentScale.Crop,
- modifier = Modifier
- .size(128.dp)
- .clip(RoundedCornerShape(8.dp))
- )
- }
- Icon(
- painter = painterResource(id = R.drawable.btn_miniplayer_play),
- contentDescription = null,
- tint = Color.White,
- modifier = Modifier.size(48.dp)
- )
- }
- },
- contentClick = contentClick,
- )
-}
-
-@RequiresApi(Build.VERSION_CODES.P)
-@Composable
-fun PodcastCollectionView(
- title : String,
- contentList: List,
- contentClick: (Content) -> Unit,
-){
- horizontalScrollContentView(contentList = contentList ,
- titleBar = {
- Row(
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier.padding(horizontal = 16.dp)
- ){
- Text(
- text = title,
- style = TextStyle(
- fontSize = 18.sp,
- fontWeight = FontWeight.Bold,
- )
- )
- }
- },
- thumbnail = { content ->
- content.image?.let {
- Image(bitmap = it,
- contentScale = ContentScale.Crop,
- contentDescription =null,
- modifier = Modifier
- .size(128.dp)
- .clip(RoundedCornerShape(8.dp))
- )
- }
- },
- contentClick = contentClick,
- )
-}
-
-@RequiresApi(Build.VERSION_CODES.P)
-@Composable
-fun VideoCollectionView(
- title : String,
- contentList : List,
- contentClick: (Content) -> Unit,
-){
- horizontalScrollContentView(contentList =contentList ,
- titleBar = {
- Row(
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier.padding(horizontal = 16.dp)
- ){
- Text(
- text = title,
- style = TextStyle(
- fontSize = 18.sp,
- fontWeight = FontWeight.Bold,
- )
- )
- }
- },
- thumbnail = { content ->
- Box(contentAlignment = Alignment.BottomEnd){
- content.image?.let {
- Image(bitmap = it,
- contentDescription = null,
- contentScale = ContentScale.FillHeight,
- modifier = Modifier
- .width(228.dp)
- .height(128.dp)
- .clip(RoundedCornerShape(8.dp))
- )
- }
- Box(
- modifier = Modifier
- .padding(8.dp)
- .background(color = Color.Black.copy(alpha = 0.5f))
- ){
- Text(
- text = "${"%02d".format(content.length/60)}:${content.length%60}",
- style = TextStyle(
- fontSize = 10.sp,
- color = Color.White,
- ),
- modifier = Modifier.padding(4.dp),
- )
- }
- }
- },
- contentClick= contentClick
- )
-}
-
-@RequiresApi(Build.VERSION_CODES.P)
-@Composable
-private fun horizontalScrollContentView(
- contentList: List,
- titleBar : @Composable () -> Unit,
- thumbnail : @Composable (Content) -> Unit,
- contentClick: (Content) -> Unit
-) {
- val density = LocalDensity.current
- var contentWidth by remember { mutableStateOf(0.dp) }
-
- Column(
- verticalArrangement = Arrangement.spacedBy(4.dp),
- modifier = Modifier.padding(vertical = 18.dp)
- ) {
- titleBar()
- LazyRow(
- horizontalArrangement = Arrangement.spacedBy(16.dp),
- ){
- item { Spacer(modifier = Modifier.width(0.dp))}
- items(count = contentList.size){ index ->
- val content = contentList[index]
- Column(
- verticalArrangement = Arrangement.spacedBy(8.dp),
- modifier = Modifier.clickable { contentClick(content) }
- ) {
- Box(
- modifier = Modifier.onGloballyPositioned {
- with(density) { contentWidth = it.size.width.toDp() }
- }
- ){
- thumbnail(content)
- }
- Column (verticalArrangement = Arrangement.spacedBy(4.dp),
- modifier = Modifier.width(contentWidth)
- ) {
- Text(
- text = content.title,
- style = TextStyle(
- fontSize = 18.sp,
- ),
- maxLines = 1,
- overflow = TextOverflow.Ellipsis
- )
- Text(
- text = content.author,
- style = TextStyle(
- color = TextStyle.Default.color.copy(alpha = 0.5f)
- ),
- maxLines = 1,
- overflow = TextOverflow.Ellipsis
- )
- }
- }
- }
- item { Spacer(modifier = Modifier.width(0.dp))}
- }
- }
-}
-
-@RequiresApi(Build.VERSION_CODES.P)
-@Preview(showBackground = true)
-@Composable
-fun PreviewLocationMusicContentView(){
- LocationMusicContentView(
- title = "오늘 발매 음악",
- contentList = List(15){
- Content(
- title = "LILAC",
- author = "아이유(IU)",
- image = ImageBitmap.imageResource(id = R.drawable.img_album_exp2),
- length = 200
- )
- },
- baseLocationCategory = BaseLocationCategory.GLOABAL ,
- viewTitleClick = { },
- contentClick ={},
- categoryClick = {}
- )
-}
-
-@RequiresApi(Build.VERSION_CODES.P)
-@Preview(showBackground = true)
-@Composable
-fun PreviewPodcastCollectionView(){
- PodcastCollectionView(
- title = "매일 들어도 좋은 팟캐스트" ,
- contentList = List(15){
- Content(
- title = "김시선의 귀책사유 FLO X 윌라",
- author= "김시선",
- image = ImageBitmap.imageResource(id = R.drawable.img_potcast_exp),
- length = 200,
- )
- },
- contentClick = {}
- )
-}
-@RequiresApi(Build.VERSION_CODES.P)
-@Preview(showBackground = true)
-@Composable
-fun PreviewVideoCollectionView(){
- VideoCollectionView(
- title ="비디오 콜렉션" ,
- contentList =List(15){
- Content(
- title = "제목",
- author = "가수",
- image = ImageBitmap.imageResource(id = R.drawable.img_video_exp),
- length = 200,
- )
- } ,
- contentClick = {}
- )
-}
-
diff --git a/app/src/main/java/umc/study/umc_7th/Promo.kt b/app/src/main/java/umc/study/umc_7th/Promo.kt
deleted file mode 100644
index 677443f..0000000
--- a/app/src/main/java/umc/study/umc_7th/Promo.kt
+++ /dev/null
@@ -1,41 +0,0 @@
-package umc.study.umc_7th
-
-import android.os.Build
-import android.provider.ContactsContract.CommonDataKinds.Im
-import androidx.annotation.RequiresApi
-import androidx.compose.foundation.Image
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.padding
-import androidx.compose.runtime.Composable
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.ImageBitmap
-import androidx.compose.ui.res.imageResource
-import androidx.compose.ui.tooling.preview.Preview
-import androidx.compose.ui.unit.Dp
-import androidx.compose.ui.unit.dp
-
-@RequiresApi(Build.VERSION_CODES.P)
-@Composable
-fun Promotion(
- image : ImageBitmap,
- padding: Dp = 0.dp,
- onClicked: ()-> Unit
-) {
- Box(modifier = Modifier
- )
- {
- Image(
- bitmap = image,
- contentDescription =null,
- modifier = Modifier.clickable { onClicked() }
- )
- }
-}
-@RequiresApi(Build.VERSION_CODES.P)
-@Preview(showBackground = true)
-@Composable
-fun PreviewPromotion(){
- Promotion(image = ImageBitmap.imageResource(id = R.drawable.img_home_viewpager_exp2),
- onClicked = {},)
-}
\ No newline at end of file
diff --git a/app/src/main/res/drawable/textview_background_select_color_radius.xml b/app/src/main/res/drawable/textview_background_select_color_radius.xml
index 70a0481..5f8e3d1 100644
--- a/app/src/main/res/drawable/textview_background_select_color_radius.xml
+++ b/app/src/main/res/drawable/textview_background_select_color_radius.xml
@@ -4,10 +4,10 @@
-
+
+
diff --git a/app/src/main/res/layout/_7th.xml b/app/src/main/res/layout/_7th.xml
deleted file mode 100644
index 77d9ef6..0000000
--- a/app/src/main/res/layout/_7th.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index d60b4b8..dbf9837 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -1,7 +1,5 @@
- #3f3fff
-
#FFBB86FC
#FF6200EE
#FF3700B3
@@ -9,17 +7,5 @@
#FF018786
#FF000000
#FFFFFFFF
-
- #9cbee2
- #062342
- #424242
- #6bb2ff
-
- #00ff0000
- #3f3fff
- #a8a8a8
- #3f3fff
- #a8a8a8
-
- #F11818
+ #004AAD
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9ac5010..42d1852 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,3 +1,3 @@
- FLO
+ umc_7th
\ No newline at end of file
diff --git a/app/src/test/java/umc/study/umc_7th/ExampleUnitTest.kt b/app/src/test/java/com/example/umc_7th/ExampleUnitTest.kt
similarity index 91%
rename from app/src/test/java/umc/study/umc_7th/ExampleUnitTest.kt
rename to app/src/test/java/com/example/umc_7th/ExampleUnitTest.kt
index 43256d8..e154618 100644
--- a/app/src/test/java/umc/study/umc_7th/ExampleUnitTest.kt
+++ b/app/src/test/java/com/example/umc_7th/ExampleUnitTest.kt
@@ -1,4 +1,4 @@
-package umc.study.umc_7th
+package com.example.umc_7th
import org.junit.Test
diff --git a/build.gradle.kts b/build.gradle.kts
index 8adda76..da307e6 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,7 +1,7 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
alias(libs.plugins.android.application) apply false
- alias(libs.plugins.jetbrains.kotlin.android) apply false
+ alias(libs.plugins.kotlin.android) apply false // 수정된 부분
id("com.google.dagger.hilt.android") version "2.49" apply false
id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false
}
@@ -9,11 +9,11 @@ plugins {
buildscript {
repositories {
google()
+ mavenCentral() // mavenCentral()도 추가하면 좋습니다.
}
dependencies {
val nav_version = "2.7.7"
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version")
- //
- classpath("androidx.navigation:navigation-safe-args-gradle-plugin:2.7.3")
}
-}
\ No newline at end of file
+}
+
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 823db7d..d84dca5 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,22 +1,24 @@
[versions]
-agp = "8.5.1"
+agp = "8.6.0"
kotlin = "1.9.0"
-coreKtx = "1.13.1"
+coreKtx = "1.10.1"
junit = "4.13.2"
-junitVersion = "1.2.1"
-espressoCore = "3.6.1"
-lifecycleRuntimeKtx = "2.8.6"
-activityCompose = "1.9.2"
+junitVersion = "1.1.5"
+espressoCore = "3.5.1"
+lifecycleRuntimeKtx = "2.6.1"
+activityCompose = "1.8.0"
composeBom = "2024.04.01"
-appcompat = "1.7.0"
-material = "1.12.0"
-constraintlayout = "2.1.4"
-lifecycleLivedataKtx = "2.8.3"
-lifecycleViewmodelKtx = "2.8.3"
-navigationFragmentKtx = "2.7.7"
-navigationUiKtx = "2.7.7"
-activity = "1.8.0"
-constraintlayoutCompose = "1.0.1"
+appcompat = "1.6.1" # 추가: appcompat 버전
+material = "1.9.0" # 추가: material 버전
+constraintlayout = "2.1.4" # 추가: constraintlayout 버전
+lifecycleLivedataKtx = "2.6.1" # 추가: lifecycle-livedata-ktx 버전
+lifecycleViewmodelKtx = "2.6.1" # 추가: lifecycle-viewmodel-ktx 버전
+navigationFragmentKtx = "2.7.2" # 추가: navigation-fragment-ktx 버전
+navigationUiKtx = "2.7.2" # 추가: navigation-ui-ktx 버전
+activity = "1.8.0" # 추가: activity 버전
+constraintlayoutCompose = "1.0.1" # 추가: constraintlayout-compose 버전
+navigationCompose = "2.7.2" # 추가: navigation-compose 버전
+runtimeLivedata = "2.6.1" # 추가: runtime-livedata 버전
[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@@ -42,8 +44,10 @@ androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navi
androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigationUiKtx" }
androidx-activity = { group = "androidx.activity", name = "activity", version.ref = "activity" }
androidx-constraintlayout-compose = { group = "androidx.constraintlayout", name = "constraintlayout-compose", version.ref = "constraintlayoutCompose" }
+androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
+androidx-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata", version.ref = "runtimeLivedata" }
[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
-
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
+kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index c10190b..cc83aaa 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,4 +1,4 @@
-#Tue Sep 24 20:15:58 KST 2024
+#Tue Oct 29 16:40:55 KST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
diff --git a/gradlew b/gradlew
old mode 100644
new mode 100755
diff --git a/gradlew.bat b/gradlew.bat
index 107acd3..ac1b06f 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -1,89 +1,89 @@
-@rem
-@rem Copyright 2015 the original author or authors.
-@rem
-@rem Licensed under the Apache License, Version 2.0 (the "License");
-@rem you may not use this file except in compliance with the License.
-@rem You may obtain a copy of the License at
-@rem
-@rem https://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing, software
-@rem distributed under the License is distributed on an "AS IS" BASIS,
-@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-@rem See the License for the specific language governing permissions and
-@rem limitations under the License.
-@rem
-
-@if "%DEBUG%" == "" @echo off
-@rem ##########################################################################
-@rem
-@rem Gradle startup script for Windows
-@rem
-@rem ##########################################################################
-
-@rem Set local scope for the variables with windows NT shell
-if "%OS%"=="Windows_NT" setlocal
-
-set DIRNAME=%~dp0
-if "%DIRNAME%" == "" set DIRNAME=.
-set APP_BASE_NAME=%~n0
-set APP_HOME=%DIRNAME%
-
-@rem Resolve any "." and ".." in APP_HOME to make it shorter.
-for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
-
-@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
-
-@rem Find java.exe
-if defined JAVA_HOME goto findJavaFromJavaHome
-
-set JAVA_EXE=java.exe
-%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:findJavaFromJavaHome
-set JAVA_HOME=%JAVA_HOME:"=%
-set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-
-if exist "%JAVA_EXE%" goto execute
-
-echo.
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
-echo.
-echo Please set the JAVA_HOME variable in your environment to match the
-echo location of your Java installation.
-
-goto fail
-
-:execute
-@rem Setup the command line
-
-set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
-
-
-@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
-
-:end
-@rem End local scope for the variables with windows NT shell
-if "%ERRORLEVEL%"=="0" goto mainEnd
-
-:fail
-rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
-rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
-exit /b 1
-
-:mainEnd
-if "%OS%"=="Windows_NT" endlocal
-
-:omega
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega