Skip to content
Open

-_- #24

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion Lize/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Lize/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
}

android {
Expand Down Expand Up @@ -46,4 +47,9 @@ dependencies {
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

//RoomDB 라이브러리
implementation 'androidx.room:room-ktx:2.4.2'
implementation 'androidx.room:room-runtime:2.4.2'
kapt 'androidx.room:room-compiler:2.4.2'
}
8 changes: 8 additions & 0 deletions Lize/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@
android:name=".SongActivity"
android:exported="true"></activity>

<activity
android:name=".LoginActivity"
android:exported="true"></activity>

<activity
android:name=".SignUpActivity"
android:exported="true"></activity>

<activity
android:name=".MainActivity"
android:exported="true"
Expand Down
10 changes: 8 additions & 2 deletions Lize/app/src/main/java/com/example/flo/Album.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package com.example.flo

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "AlbumTable")
data class Album(
@PrimaryKey(autoGenerate = false) var id:Int =0,
var title: String? = "",
var singer: String? = "",
var coverImg: Int? = null,
var songs: ArrayList<Song>? = null //수록곡
var coverImg: Int? = null
//,
//var songs: ArrayList<Song>? = null //수록곡
)
35 changes: 35 additions & 0 deletions Lize/app/src/main/java/com/example/flo/AlbumDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.flo

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query

@Dao
interface AlbumDao {

@Insert
fun insert(album:Album)

@Query("SELECT * FROM AlbumTable")
fun getAlbums():List<Album>

//사용자가 좋아요를 누른 앨범 추가
@Insert
fun likeAlbum(like:Like)

@Query("SELECT id FROM LikeTable WHERE userId = :userId AND albumId = :albumId")
//AlbumFragment에 들어갈 때, 사용자가 좋아요를 눌렀는 지 누르지 않았는 지 확인
fun isLikedAlbum(userId: Int, albumId : Int) : Int?
//정보가 없다면 null을 반환하므로 "?"처리

@Query("DELETE FROM LikeTable WHERE userId = :userId AND albumId = :albumId")
//AlbumFragment에 들어갈 때, 사용자가 좋아요를 취소할 경우
fun disLikedAlbum(userId: Int, albumId : Int)

//LikeTable as LT : LikeTable=LT
//LikeTable as LT LEFT JOIN AlbumTable as AT : 왼쪽의 LT를 기준으로 오른쪽의 AT를 join
//on LT.albumId = AT.id : albumId가 같은 것끼리 join
@Query("SELECT AT.* FROM LikeTable as LT LEFT JOIN AlbumTable as AT on LT.albumId = AT.id WHERE LT.userId = :userId")
//좋아요한 앨범을 가져오기
fun getLikedAlbums(userId:Int):List<Album>
}
63 changes: 63 additions & 0 deletions Lize/app/src/main/java/com/example/flo/AlbumFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.example.flo.databinding.FragmentAlbumBinding
import com.google.android.material.tabs.TabLayoutMediator
Expand All @@ -16,6 +17,8 @@ class AlbumFragment : Fragment() {

private val information = arrayListOf("수록곡", "상세정보", "영상")

private var isLiked : Boolean = false

private var gson: Gson = Gson()

//activity : onCreate vs fragment : onCreateView
Expand All @@ -29,7 +32,12 @@ class AlbumFragment : Fragment() {
//argument에서 데이터를 꺼내와서 binding
val albumJson = arguments?.getString("album")
val album = gson.fromJson(albumJson, Album::class.java)

//isLiked 초기설정
isLiked = isLikedAlbum(album.id)

setInit(album) //binding작업 수행
setOnClickListeners(album)

//fragment_album에서 back누르면 다시 HomeFragment로 이동
binding.albumBackIv.setOnClickListener{
Expand All @@ -54,6 +62,61 @@ class AlbumFragment : Fragment() {
binding.albumImgIv.setImageResource(album.coverImg!!)
binding.albumTitleMainTv.text = album.title.toString()
binding.albumSingerMainTv.text = album.singer.toString()

//좋아요가 눌리면 하트 색 변경
if(isLiked){
binding.albumLikeOffIv.setImageResource(R.drawable.ic_my_like_on)
}else{
binding.albumLikeOffIv.setImageResource(R.drawable.ic_my_like_off)
}
}

//현재 로그인된 유저정보 가져오기
private fun getJwt():Int{
val spf = activity?.getSharedPreferences("auth", AppCompatActivity.MODE_PRIVATE)
return spf!!.getInt("jwt", 0) //shardPreferences에서 가져온 값이 없다면 0반환
}

//좋아요를 눌렀을 때 DB에 저장
private fun likeAlbum(userId:Int, albumId:Int){
val songDB = SongDatabase.getInstance(requireContext())!!
val like = Like(userId, albumId)
//좋아요 눌렀을 때, LikeTable에 정보 추가
songDB.albumDao().likeAlbum(like)
}

//Album에서 사용자의 좋아요여부를 알기위함
private fun isLikedAlbum(albumId:Int):Boolean{
val songDB = SongDatabase.getInstance(requireContext())!!
val userId = getJwt()
val likeId : Int? = songDB.albumDao().isLikedAlbum(userId, albumId) //어떤 유저가 해당 앨범을 좋아요 눌렀는가

return likeId != null //유저가 좋아요 눌렀다면 true / 좋아요X면 false
}

//사용자가 좋아요를 취소하면, LikeTable에서 해당 앨범 지우기
private fun disLikedAlbum(albumId:Int){
val songDB = SongDatabase.getInstance(requireContext())!!
val userId = getJwt()

songDB.albumDao().disLikedAlbum(userId, albumId) //어떤 유저가 해당 앨범을 좋아요 눌렀는가

}

//좋아요를 눌렀을 때, 클릭이벤트 처리
private fun setOnClickListeners(album: Album){
val userId = getJwt()
binding.albumLikeOffIv.setOnClickListener{
if(isLiked){ //좋아요눌려있는 상태
//좋아요 취소
binding.albumLikeOffIv.setImageResource(R.drawable.ic_my_like_off)
disLikedAlbum(album.id)
}else{ //좋아요가 눌려있지 않은 상태
//좋아요
binding.albumLikeOffIv.setImageResource(R.drawable.ic_my_like_on)
likeAlbum(userId, album.id)
}
}
}


Expand Down
59 changes: 59 additions & 0 deletions Lize/app/src/main/java/com/example/flo/AlbumLockerRVAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.example.flo

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.flo.databinding.ItemLockerAlbumBinding

class AlbumLockerRVAdapter (): RecyclerView.Adapter<AlbumLockerRVAdapter.ViewHolder>() {
private val albums = ArrayList<Album>()

interface MyItemClickListener{
fun onRemoveSong(songId: Int)
}

private lateinit var mItemClickListener: MyItemClickListener

fun setMyItemClickListener(itemClickListener: MyItemClickListener){
mItemClickListener = itemClickListener
}

override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): AlbumLockerRVAdapter.ViewHolder {
val binding: ItemLockerAlbumBinding = ItemLockerAlbumBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false)

return ViewHolder(binding)
}

override fun onBindViewHolder(holder: AlbumLockerRVAdapter.ViewHolder, position: Int) {
holder.bind(albums[position])
holder.binding.itemAlbumMoreIv.setOnClickListener {
mItemClickListener.onRemoveSong(albums[position].id)
removeSong(position)
}
}

override fun getItemCount(): Int = albums.size

@SuppressLint("NotifyDataSetChanged")
fun addAlbums(albums: ArrayList<Album>) {
this.albums.clear()
this.albums.addAll(albums)

notifyDataSetChanged()
}

fun removeSong(position: Int){
albums.removeAt(position)
notifyDataSetChanged()
}

inner class ViewHolder(val binding: ItemLockerAlbumBinding) : RecyclerView.ViewHolder(binding.root){
fun bind(album: Album){
binding.itemAlbumImgIv.setImageResource(album.coverImg!!)
binding.itemAlbumTitleTv.text = album.title
binding.itemAlbumSingerTv.text = album.singer
}
}

}
21 changes: 13 additions & 8 deletions Lize/app/src/main/java/com/example/flo/HomeFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class HomeFragment : Fragment() {

private var albumDatas = ArrayList<Album>()

private lateinit var songDB : SongDatabase

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
Expand All @@ -31,14 +33,17 @@ class HomeFragment : Fragment() {
// }

//ArrayList에 데이터 추가 : 데이터 리스트 생성 더미 데이터
albumDatas.apply {
add(Album("Butter", "방탄소년단 (BTS)", R.drawable.img_album_exp))
add(Album("Lilac", "아이유 (IU)", R.drawable.img_album_exp2))
add(Album("Next Level", "에스파 (AESPA)", R.drawable.img_album_exp3))
add(Album("Boy with Luv", "방탄소년단 (BTS)", R.drawable.img_album_exp4))
add(Album("BBoom BBoom", "모모랜드 (MOMOLAND)", R.drawable.img_album_exp5))
add(Album("Weekend", "태연 (Tae Yeon)", R.drawable.img_album_exp6))
}
// albumDatas.apply {
// add(Album("Butter", "방탄소년단 (BTS)", R.drawable.img_album_exp))
// add(Album("Lilac", "아이유 (IU)", R.drawable.img_album_exp2))
// add(Album("Next Level", "에스파 (AESPA)", R.drawable.img_album_exp3))
// add(Album("Boy with Luv", "방탄소년단 (BTS)", R.drawable.img_album_exp4))
// add(Album("BBoom BBoom", "모모랜드 (MOMOLAND)", R.drawable.img_album_exp5))
// add(Album("Weekend", "태연 (Tae Yeon)", R.drawable.img_album_exp6))
// }
//songDB에 추가
songDB = SongDatabase.getInstance(requireContext())!! //songDB초기화
albumDatas.addAll(songDB.albumDao().getAlbums())

//Adapter-datalist를 연결
val albumRVAdapter = AlbumRVAdapter(albumDatas)
Expand Down
12 changes: 12 additions & 0 deletions Lize/app/src/main/java/com/example/flo/Like.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.flo

import androidx.room.Entity
import androidx.room.PrimaryKey

@Entity(tableName = "LikeTable")
data class Like(
var userId : Int,
var albumId : Int
){
@PrimaryKey(autoGenerate = true) var id:Int = 0
}
51 changes: 51 additions & 0 deletions Lize/app/src/main/java/com/example/flo/LockerFragment.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package com.example.flo

import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import com.example.flo.databinding.FragmentLockerBinding
import com.google.android.material.tabs.TabLayoutMediator

class LockerFragment : Fragment() {

lateinit var binding: FragmentLockerBinding
private var information = arrayListOf("저장한 곡", "음악파일", "저장앨범")

override fun onCreateView(
inflater: LayoutInflater,
Expand All @@ -18,6 +22,53 @@ class LockerFragment : Fragment() {
): View? {
binding = FragmentLockerBinding.inflate(inflater, container, false)

val lockerAdapter = LockerVPAdapter(this)
binding.lockerContentVp.adapter = lockerAdapter
TabLayoutMediator(binding.lockerContentTb, binding.lockerContentVp){
tab, position -> tab.text = information[position]
}.attach()

//fragment_locker.xml의 로그인버튼을 누르면 -> activity_login.xml로 이동
binding.lockerLoginTv.setOnClickListener{
startActivity(Intent(activity, LoginActivity::class.java))
}

return binding.root
}

override fun onStart() {
super.onStart()
initViews()
}

//로그인 상태일 경우 : 로그아웃 텍스트뜨기
//로그아웃 상태일 경우 : 로그인 텍스트뜨기
private fun getJwt():Int{
val spf = activity?.getSharedPreferences("auth", AppCompatActivity.MODE_PRIVATE)
return spf!!.getInt("jwt", 0) //shardPreferences에서 가져온 값이 없다면 0반환
}

private fun initViews(){
val jwt : Int = getJwt()
if(jwt == 0){
binding.lockerLoginTv.text = "로그인"
binding.lockerLoginTv.setOnClickListener{
startActivity(Intent(activity, LoginActivity::class.java))
}
}else{
binding.lockerLoginTv.text = "로그아웃"
binding.lockerLoginTv.setOnClickListener{
//로그아웃 진행
logout()
startActivity(Intent(activity, MainActivity::class.java))
}
}
}

private fun logout(){ //jwt=0으로 만들기 : 저장된 값X
val spf = activity?.getSharedPreferences("auth", AppCompatActivity.MODE_PRIVATE)
val editor = spf!!.edit()
editor.remove("jwt")
editor.apply()
}
}
Loading