diff --git a/isoo/template/.idea/misc.xml b/isoo/template/.idea/misc.xml index 6d4e311..8594f9c 100644 --- a/isoo/template/.idea/misc.xml +++ b/isoo/template/.idea/misc.xml @@ -15,7 +15,7 @@ - + diff --git a/isoo/template/app/build.gradle b/isoo/template/app/build.gradle index 43b2f55..e90a30c 100644 --- a/isoo/template/app/build.gradle +++ b/isoo/template/app/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'kotlin-android' + id 'kotlin-kapt' } android { @@ -36,7 +37,7 @@ android { } dependencies { - + implementation 'com.google.code.gson:gson:2.8.7' implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.4.0' implementation 'com.google.android.material:material:1.4.0' @@ -44,4 +45,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.1' + implementation 'androidx.room:room-runtime:2.4.1' + kapt 'androidx.room:room-compiler:2.4.1' } \ No newline at end of file diff --git a/isoo/template/app/src/main/AndroidManifest.xml b/isoo/template/app/src/main/AndroidManifest.xml index f7880d4..0022548 100644 --- a/isoo/template/app/src/main/AndroidManifest.xml +++ b/isoo/template/app/src/main/AndroidManifest.xml @@ -11,7 +11,8 @@ android:theme="@style/Theme.FLO"> + android:exported="true" + android:theme="@style/SplashTheme"> diff --git a/isoo/template/app/src/main/java/com/example/flo/Album.kt b/isoo/template/app/src/main/java/com/example/flo/Album.kt new file mode 100644 index 0000000..e71105f --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/Album.kt @@ -0,0 +1,10 @@ +package com.example.flo + +import java.util.ArrayList + +data class Album( + var title: String? = "", + var singer: String? = "", + var coverImg: Int? = null, + var songs: ArrayList? = null +) diff --git a/isoo/template/app/src/main/java/com/example/flo/AlbumFragment.kt b/isoo/template/app/src/main/java/com/example/flo/AlbumFragment.kt index 1b273aa..2180b4b 100644 --- a/isoo/template/app/src/main/java/com/example/flo/AlbumFragment.kt +++ b/isoo/template/app/src/main/java/com/example/flo/AlbumFragment.kt @@ -8,9 +8,15 @@ import android.widget.Toast import androidx.fragment.app.Fragment import com.example.flo.databinding.ActivitySongBinding import com.example.flo.databinding.FragmentAlbumBinding +import com.google.android.material.tabs.TabLayoutMediator +import com.google.gson.Gson class AlbumFragment : Fragment() { + lateinit var binding : FragmentAlbumBinding + private var gson = Gson() + + private val info = arrayListOf("수록곡", "상세정보", "영상") override fun onCreateView( inflater: LayoutInflater, @@ -18,15 +24,29 @@ class AlbumFragment : Fragment() { savedInstanceState: Bundle? ): View? { binding = FragmentAlbumBinding.inflate(inflater,container,false) + + val albumJson = arguments?.getString("album") + val album = gson.fromJson(albumJson, Album::class.java) + setInit(album) + binding.albumBackIv.setOnClickListener { (context as MainActivity).supportFragmentManager.beginTransaction().replace(R.id.main_frm, HomeFragment()).commitAllowingStateLoss() } - binding.albumSongGroup1L.setOnClickListener { - Toast.makeText(this.context,binding.albumSongTitle1Tv.text.toString(),Toast.LENGTH_SHORT).show() - } - binding.albumSongGroup2L.setOnClickListener { - Toast.makeText(this.context,binding.albumSongTitle2Tv.text.toString(),Toast.LENGTH_SHORT).show() - } + + val albumAdapter = AlbumVPAdapter(this) + binding.albumContentVp.adapter = albumAdapter + TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) { + tab, position -> + tab.text = info[position] + }.attach() + return binding.root } + + private fun setInit(album: Album) { + binding.albumAlbumIv.setImageResource(album.coverImg!!) + binding.albumMusicTitleTv.text = album.title.toString() + binding.albumSingerNameTv.text = album.singer.toString() + } + } \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/AlbumRVAdapter.kt b/isoo/template/app/src/main/java/com/example/flo/AlbumRVAdapter.kt new file mode 100644 index 0000000..f3034bf --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/AlbumRVAdapter.kt @@ -0,0 +1,52 @@ +package com.example.flo + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.flo.databinding.ItemAlbumBinding +import java.util.* + +class AlbumRVAdapter(private val albumList: ArrayList) : RecyclerView.Adapter(){ + + interface MyItemClickListener{ + fun onItemClick(album: Album) + fun onRemoveAlbum(position: Int) + } + + private lateinit var mItemClickListener: MyItemClickListener + + fun setMyItemClickListener(itemClickListener: MyItemClickListener){ + mItemClickListener = itemClickListener + } + + fun addItem(album: Album){ + albumList.add(album) + notifyDataSetChanged() + } + + fun removeItem(position: Int){ + albumList.removeAt(position) + notifyDataSetChanged() + } + + override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): AlbumRVAdapter.ViewHolder { + val binding: ItemAlbumBinding = ItemAlbumBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: AlbumRVAdapter.ViewHolder, position: Int) { + holder.bind(albumList[position]) + holder.itemView.setOnClickListener { mItemClickListener.onItemClick(albumList[position]) } +// holder.binding.itemAlbumTitleTv.setOnClickListener { mItemClickListener.onRemoveAlbum(position) } + } + + override fun getItemCount(): Int = albumList.size + + inner class ViewHolder(val binding: ItemAlbumBinding): RecyclerView.ViewHolder(binding.root){ + fun bind(album: Album){ + binding.itemAlbumTitleTv.text = album.title + binding.itemAlbumSingerTv.text = album.singer + binding.itemAlbumCoverImgIv.setImageResource(album.coverImg!!) + } + } +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/AlbumVPAdapter.kt b/isoo/template/app/src/main/java/com/example/flo/AlbumVPAdapter.kt new file mode 100644 index 0000000..4f2a510 --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/AlbumVPAdapter.kt @@ -0,0 +1,16 @@ +package com.example.flo + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter + +class AlbumVPAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) { + override fun getItemCount(): Int = 3 + + override fun createFragment(position: Int): Fragment { + return when(position) { + 0 -> SongFragment() + 1 -> DetailFragment() + else -> VideoFragment() + } + } +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/BannerFragment.kt b/isoo/template/app/src/main/java/com/example/flo/BannerFragment.kt new file mode 100644 index 0000000..b49abd9 --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/BannerFragment.kt @@ -0,0 +1,23 @@ +package com.example.flo + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.flo.databinding.FragmentBannerBinding + +class BannerFragment(val imgRes : Int) : Fragment() { + lateinit var binding: FragmentBannerBinding + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentBannerBinding.inflate(inflater,container,false) + + binding.bannerImageIv.setImageResource(imgRes) + return binding.root + } +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/BannerVPAdapter.kt b/isoo/template/app/src/main/java/com/example/flo/BannerVPAdapter.kt new file mode 100644 index 0000000..da836a4 --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/BannerVPAdapter.kt @@ -0,0 +1,19 @@ +package com.example.flo + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter + +class BannerVPAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) { + + private val fragmentList : ArrayList = ArrayList() + + override fun getItemCount(): Int = fragmentList.size + + override fun createFragment(position: Int): Fragment = fragmentList[position] + + fun addFragment(fragment: Fragment) { + fragmentList.add(fragment) + notifyItemInserted(fragmentList.size-1) + } + +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/DetailFragment.kt b/isoo/template/app/src/main/java/com/example/flo/DetailFragment.kt new file mode 100644 index 0000000..6a0d918 --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/DetailFragment.kt @@ -0,0 +1,24 @@ +package com.example.flo + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.flo.databinding.FragmentDetailBinding + +class DetailFragment : Fragment() { + + lateinit var binding : FragmentDetailBinding + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentDetailBinding.inflate(inflater,container,false) + + return binding.root + } + +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/HomeFragment.kt b/isoo/template/app/src/main/java/com/example/flo/HomeFragment.kt index 05bb180..e243678 100644 --- a/isoo/template/app/src/main/java/com/example/flo/HomeFragment.kt +++ b/isoo/template/app/src/main/java/com/example/flo/HomeFragment.kt @@ -5,11 +5,16 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.viewpager2.widget.ViewPager2 import com.example.flo.databinding.FragmentHomeBinding +import com.google.gson.Gson +import java.util.ArrayList class HomeFragment : Fragment() { lateinit var binding: FragmentHomeBinding + private var albumDatas = ArrayList() override fun onCreateView( inflater: LayoutInflater, @@ -18,9 +23,49 @@ class HomeFragment : Fragment() { ): View? { binding = FragmentHomeBinding.inflate(inflater, container, false) - binding.homeAlbumImgIv1.setOnClickListener { - (context as MainActivity).supportFragmentManager.beginTransaction().replace(R.id.main_frm, AlbumFragment()).commitAllowingStateLoss() +// binding.homeAlbumImgIv1.setOnClickListener { +// (context as MainActivity).supportFragmentManager.beginTransaction().replace(R.id.main_frm, AlbumFragment()).commitAllowingStateLoss() +// } + 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)) } + + val albumRVAdapter = AlbumRVAdapter(albumDatas) + binding.homeTodayMusicAlbumRv.adapter = albumRVAdapter + binding.homeTodayMusicAlbumRv.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) + + albumRVAdapter.setMyItemClickListener(object: AlbumRVAdapter.MyItemClickListener { + override fun onItemClick(album: Album) { + changeAlbumFragment(album) + } + + override fun onRemoveAlbum(position: Int) { + albumRVAdapter.removeItem(position) + } + }) + + val bannerAdapter = BannerVPAdapter(this) + bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp)) + bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp2)) + binding.homeBannerVp.adapter = bannerAdapter + binding.homeBannerVp.orientation = ViewPager2.ORIENTATION_HORIZONTAL + return binding.root } + + private fun changeAlbumFragment(album: Album) { + (context as MainActivity).supportFragmentManager.beginTransaction() + .replace(R.id.main_frm, AlbumFragment().apply { + arguments = Bundle().apply { + val gson = Gson() + val albumJson = gson.toJson(album) + putString("album", albumJson) + } + }).commitAllowingStateLoss() + } } \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/LockerFragment.kt b/isoo/template/app/src/main/java/com/example/flo/LockerFragment.kt index c887e68..0d87f35 100644 --- a/isoo/template/app/src/main/java/com/example/flo/LockerFragment.kt +++ b/isoo/template/app/src/main/java/com/example/flo/LockerFragment.kt @@ -6,11 +6,14 @@ import android.view.View import android.view.ViewGroup 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 val info = arrayListOf("저장한 곡", "음악파일") + override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, @@ -18,6 +21,13 @@ 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 = info[position] + }.attach() + return binding.root } } \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/LockerVPAdapter.kt b/isoo/template/app/src/main/java/com/example/flo/LockerVPAdapter.kt new file mode 100644 index 0000000..049f350 --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/LockerVPAdapter.kt @@ -0,0 +1,15 @@ +package com.example.flo + +import androidx.fragment.app.Fragment +import androidx.viewpager2.adapter.FragmentStateAdapter + +class LockerVPAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) { + override fun getItemCount(): Int = 2 + + override fun createFragment(position: Int): Fragment { + return when(position) { + 0 -> SavedSongFragment() + else -> Fragment() + } + } +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/MainActivity.kt b/isoo/template/app/src/main/java/com/example/flo/MainActivity.kt index df19130..e5257dc 100644 --- a/isoo/template/app/src/main/java/com/example/flo/MainActivity.kt +++ b/isoo/template/app/src/main/java/com/example/flo/MainActivity.kt @@ -1,27 +1,39 @@ package com.example.flo import android.content.Intent -import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.util.Log +import androidx.appcompat.app.AppCompatActivity import com.example.flo.databinding.ActivityMainBinding +import com.google.gson.Gson class MainActivity : AppCompatActivity() { lateinit var binding: ActivityMainBinding + private var song : Song = Song() + private var gSon : Gson = Gson() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + setTheme(R.style.Theme_FLO) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) - val song = Song(binding.mainPlayerTitleTv.text.toString(), binding.mainPlayerSingerTv.text.toString()) + inputDummySongs() + //val song = Song(binding.mainPlayerTitleTv.text.toString(), binding.mainPlayerSingerTv.text.toString(), 0, 60, false, "music_lilac") Log.d("Song", song.title + song.singer) binding.mainPlayerCl.setOnClickListener { //startActivity(Intent(this,SongActivity::class.java)) - val intent = Intent(this,SongActivity::class.java) +/* val intent = Intent(this,SongActivity::class.java) intent.putExtra("song", song) + startActivity(intent)*/ + val editor = getSharedPreferences("song", MODE_PRIVATE).edit() + editor.putInt("songId", song.id) + editor.apply() + + val intent = Intent(this,SongActivity::class.java) startActivity(intent) } @@ -66,4 +78,81 @@ class MainActivity : AppCompatActivity() { false } } + + private fun setMiniPlayer(song:Song) { + binding.mainPlayerTitleTv.text = song.title + binding.mainPlayerSingerTv.text = song.singer + binding.mainMiniplayerProgressSb.progress = (song.second * 100000) / song.playTime + } + + override fun onStart() { + super.onStart() +/* val sharedPreferences = getSharedPreferences("song", MODE_PRIVATE) + val songJson = sharedPreferences.getString("songData",null) + + song = if(songJson == null) { + Song("라일락","아이유(IU)",0,60,false,"music_lilac") + } else { + gSon.fromJson(songJson, Song::class.java) + }*/ + val spf = getSharedPreferences("song", MODE_PRIVATE) + val songId = spf.getInt("songId",0) + + val songDB = SongDatabase.getInstance(this)!! + song = if(songId == 0) { + songDB.songDao().getSong(1) + } else { + songDB.songDao().getSong(songId) + } + + Log.d("song Id", song.id.toString()) + + setMiniPlayer(song) + } + + private fun inputDummySongs() { + val songDB = SongDatabase.getInstance(this)!! + val songs = songDB.songDao().getSongs() + + if(songs.isNotEmpty()) return + + songDB.songDao().insert( + Song( + "Butter", + "방탄소년단 (BTS)", + 0, + 240, + false, + "music_butter", + R.drawable.img_album_exp, + false + ) + ) + songDB.songDao().insert( + Song( + "Lilac", + "아이유 (IU)", + 1, + 240, + false, + "music_lilac", + R.drawable.img_album_exp2, + false + ) + ) + songDB.songDao().insert( + Song( + "Bboom Bboom", + "모모랜드 (MOMOLAND)", + 2, + 240, + false, + "music_bboom", + R.drawable.img_album_exp5, + false + ) + ) + val _songs = songDB.songDao().getSongs() + Log.d("inputDummySongs: ", _songs.toString()) + } } \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/SavedSongFragment.kt b/isoo/template/app/src/main/java/com/example/flo/SavedSongFragment.kt new file mode 100644 index 0000000..9c35d7e --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/SavedSongFragment.kt @@ -0,0 +1,40 @@ +package com.example.flo + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.flo.databinding.FragmentLockerSavedsongBinding +import java.util.ArrayList + +class SavedSongFragment : Fragment() { + lateinit var binding : FragmentLockerSavedsongBinding + lateinit var songDB : SongDatabase + private var songDatas = ArrayList() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentLockerSavedsongBinding.inflate(inflater,container,false) + songDB = SongDatabase.getInstance(requireContext())!! + + return binding.root + } + + override fun onStart() { + super.onStart() + val savedSongRVAdapter = SavedSongRVAdapter(songDatas) + savedSongRVAdapter.setMyItemClickListener(object : SavedSongRVAdapter.MyItemClickListener { + override fun onRemoveSong(songId: Int) { + songDB.songDao().updateIsLikeById(false,songId) + } + }) + binding.lockerSavedSongRecyclerView.adapter = savedSongRVAdapter + savedSongRVAdapter.addSongs(songDB.songDao().getLikedSongs(true) as ArrayList) + binding.lockerSavedSongRecyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) + } +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/SavedSongRVAdapter.kt b/isoo/template/app/src/main/java/com/example/flo/SavedSongRVAdapter.kt new file mode 100644 index 0000000..0701616 --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/SavedSongRVAdapter.kt @@ -0,0 +1,57 @@ +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.ItemSongBinding +import java.util.* + +class SavedSongRVAdapter(private val songs: ArrayList) : RecyclerView.Adapter(){ + + interface MyItemClickListener { + fun onRemoveSong(songId : Int) + } + + private lateinit var myItemClickListener : MyItemClickListener + + fun setMyItemClickListener(itemClickListener : MyItemClickListener) { + myItemClickListener = itemClickListener + } + + override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): SavedSongRVAdapter.ViewHolder { + val binding: ItemSongBinding = ItemSongBinding.inflate(LayoutInflater.from(viewGroup.context), viewGroup, false) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: SavedSongRVAdapter.ViewHolder, position: Int) { + holder.bind(songs[position]) + holder.binding.itemSongMoreIv.setOnClickListener { + myItemClickListener.onRemoveSong(songs[position].id) + removeSong(position) + } + } + + override fun getItemCount(): Int = songs.size + + inner class ViewHolder(val binding: ItemSongBinding): RecyclerView.ViewHolder(binding.root){ + fun bind(song: Song){ + binding.itemSongTitleTv.text = song.title + binding.itemSongSingerTv.text = song.singer + binding.itemSongImgIv.setImageResource(song.coverImg!!) + } + } + + @SuppressLint("NotifyDataSetChanged") + fun addSongs(songs : ArrayList) { + this.songs.clear() + this.songs.addAll(songs) + notifyDataSetChanged() + } + + @SuppressLint("NotifyDataSetChanged") + fun removeSong(pos : Int) { + songs.removeAt(pos) + notifyDataSetChanged() + } +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/Song.kt b/isoo/template/app/src/main/java/com/example/flo/Song.kt index 643bf6c..26ad03e 100644 --- a/isoo/template/app/src/main/java/com/example/flo/Song.kt +++ b/isoo/template/app/src/main/java/com/example/flo/Song.kt @@ -1,8 +1,19 @@ package com.example.flo +import androidx.room.Entity +import androidx.room.PrimaryKey import java.io.* +@Entity(tableName = "SongTable") data class Song ( val title : String = "", - val singer : String = "" -) : Serializable + val singer : String = "", + var second : Int = 0, + var playTime : Int = 0, + var isPlaying : Boolean = false, + var music : String = "", + var coverImg: Int? = null, + var isLike: Boolean = false +) : Serializable { + @PrimaryKey(autoGenerate = true) var id: Int = 0 +} diff --git a/isoo/template/app/src/main/java/com/example/flo/SongActivity.kt b/isoo/template/app/src/main/java/com/example/flo/SongActivity.kt index 73401ec..f72132b 100644 --- a/isoo/template/app/src/main/java/com/example/flo/SongActivity.kt +++ b/isoo/template/app/src/main/java/com/example/flo/SongActivity.kt @@ -1,43 +1,199 @@ package com.example.flo +import android.media.MediaPlayer import android.os.Bundle import android.util.Log -import android.view.View +import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.example.flo.databinding.ActivitySongBinding +import com.google.gson.Gson class SongActivity : AppCompatActivity() { lateinit var binding : ActivitySongBinding + //lateinit var song : Song + lateinit var timer : Timer + + private var mediaPlayer : MediaPlayer? = null + private var gson : Gson = Gson() + + val songs = arrayListOf() + lateinit var songDB: SongDatabase + var nowPos = 0 // for playing img resource - var playing = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivitySongBinding.inflate(layoutInflater) setContentView(binding.root) + + initPlayList() + initSong() + //setPlayer(song) + initClickListener() + + } + + override fun onPause() { + super.onPause() + setPlayerStatus(false) + songs[nowPos].second = ((binding.songProgressSb.progress * songs[nowPos].playTime)/100)/1000 + val sharedPreferences = getSharedPreferences("song", MODE_PRIVATE) + val editor = sharedPreferences.edit() + //val songJson = gson.toJson(songs[nowPos]) + //editor.putString("songData",songJson) + editor.putInt("songId", songs[nowPos].id) + editor.apply() + } + + override fun onDestroy() { + super.onDestroy() + timer.interrupt() + mediaPlayer?.release() // free resources + mediaPlayer = null + } + + private fun initPlayList() { + songDB = SongDatabase.getInstance(this)!! + songs.addAll(songDB.songDao().getSongs()) + } + + private fun initClickListener() { binding.songDownBtn.setOnClickListener { finish() } binding.songMiniplayerIv.setOnClickListener { - setPlayerStatus() + setPlayerStatus(songs[nowPos].isPlaying) + } + + binding.songNextIv.setOnClickListener { + moveSong(+1) + } + binding.songPreviousIv.setOnClickListener { + moveSong(-1) + } + binding.songLikeBtn.setOnClickListener { + setLike(songs[nowPos].isLike) + } + } + + private fun setLike(isLike : Boolean) { + songs[nowPos].isLike = !isLike + songDB.songDao().updateIsLikeById(!isLike, songs[nowPos].id) + if(!isLike) { + binding.songLikeBtn.setImageResource(R.drawable.ic_my_like_on) + } else { + binding.songLikeBtn.setImageResource(R.drawable.ic_my_like_off) + } + } + + private fun moveSong(direct: Int) { + if(nowPos + direct < 0) { + Toast.makeText(this,"first song",Toast.LENGTH_SHORT).show() + return + } + if(nowPos + direct >= songs.size) { + Toast.makeText(this,"last song",Toast.LENGTH_SHORT).show() + return } + nowPos += direct + timer.interrupt() + startTimer() + mediaPlayer?.release() + mediaPlayer = null + + setPlayer(songs[nowPos]) + } + + private fun initSong() { +/* if(intent.hasExtra("song")) { + song = intent.getSerializableExtra("song") as Song; + }*/ + val spf = getSharedPreferences("song", MODE_PRIVATE) + val songId = spf.getInt("songId", 0) - if(intent.hasExtra("song")) { - val song = intent.getSerializableExtra("song") as Song - binding.songTitleTv.text = song.title - binding.songSingerTv.text = song.singer - Log.d("song", song.title + song.singer) + nowPos = getPlayingSongPosition(songId) + + Log.d("now Song Id",songs[nowPos].id.toString()) + startTimer() + setPlayer(songs[nowPos]) + } + + private fun getPlayingSongPosition(songId : Int): Int { + for(i in 0 until songs.size) { + if(songs[i].id == songId) { + return i + } } + return 0 } - fun setPlayerStatus() { + private fun setPlayer(song : Song) { + binding.songTitleTv.text = song.title + binding.songSingerTv.text = song.singer + binding.songStartTimeTv.text = String.format("%02d:%02d", song.second / 60, song.second % 60) + binding.songEndTimeTv.text = String.format("%02d:%02d", song.playTime / 60, song.playTime % 60) + binding.songAlbumImgIv.setImageResource(song.coverImg!!) + binding.songProgressSb.progress = (song.second * 1000 / song.playTime) + val music = resources.getIdentifier(song.music,"raw",this.packageName) + mediaPlayer = MediaPlayer.create(this, music) + + if(song.isLike) { + binding.songLikeBtn.setImageResource(R.drawable.ic_my_like_on) + } else { + binding.songLikeBtn.setImageResource(R.drawable.ic_my_like_off) + } + + setPlayerStatus(song.isPlaying) + Log.d("song", song.title + song.singer) + } + + private fun startTimer() { + timer = Timer(songs[nowPos].playTime, songs[nowPos].isPlaying) + timer.start() + } + + fun setPlayerStatus(playing : Boolean) { + timer.isPlaying = songs[nowPos].isPlaying if(playing) { binding.songMiniplayerIv.setImageResource(R.drawable.btn_miniplay_pause) - playing = false + songs[nowPos].isPlaying = false + mediaPlayer?.start() } else { binding.songMiniplayerIv.setImageResource(R.drawable.btn_miniplayer_play) - playing = true + songs[nowPos].isPlaying = true + if(mediaPlayer?.isPlaying == true) + mediaPlayer?.pause() + } + } + + inner class Timer(private val playTime: Int, var isPlaying: Boolean = true):Thread() { + private var second : Int = 0; + private var mills : Float = 0f + + override fun run() { + super.run() + try { + while(true) { + if(second >= playTime) + break + if(isPlaying) { + sleep(50) + mills += 50 + runOnUiThread { + binding.songProgressSb.progress = ((mills / playTime)*100).toInt() + } + if(mills % 1000 == 0f) { + runOnUiThread { + binding.songStartTimeTv.text = String.format("%02d:%02d", second / 60, second % 60) + } + second++ + } + } + } + } catch (e : InterruptedException) { + Log.d("Song", "Thread is interrupted ${e.message}") + } } } } \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/SongDao.kt b/isoo/template/app/src/main/java/com/example/flo/SongDao.kt new file mode 100644 index 0000000..69ebaed --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/SongDao.kt @@ -0,0 +1,28 @@ +package com.example.flo + +import androidx.room.* +import java.util.ArrayList + +@Dao +interface SongDao { + @Insert + fun insert(song: Song) + + @Update + fun update(song: Song) + + @Delete + fun delete(song: Song) + + @Query("SELECT * FROM SongTable") + fun getSongs() : List + + @Query("SELECT * FROM SongTable WHERE id = :id") + fun getSong(id: Int) : Song + + @Query("UPDATE SongTable SET isLike = :isLike WHERE id = :id") + fun updateIsLikeById(isLike : Boolean, id : Int) + + @Query("SELECT * FROM SongTable WHERE isLike = :isLike") + fun getLikedSongs(isLike: Boolean) : List +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/SongDatabase.kt b/isoo/template/app/src/main/java/com/example/flo/SongDatabase.kt new file mode 100644 index 0000000..d2ddd71 --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/SongDatabase.kt @@ -0,0 +1,29 @@ +package com.example.flo + +import android.content.Context +import androidx.room.Database +import androidx.room.Room +import androidx.room.RoomDatabase + +@Database(entities = [Song::class], version = 1) +abstract class SongDatabase : RoomDatabase() { + abstract fun songDao() : SongDao + + companion object { + private var instance : SongDatabase? = null + + @Synchronized + fun getInstance(context: Context): SongDatabase? { + if(instance == null) { + synchronized(SongDatabase::class) { + instance = Room.databaseBuilder( + context.applicationContext, + SongDatabase::class.java, + "song-database" + ).allowMainThreadQueries().build() + } + } + return instance + } + } +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/SongFragment.kt b/isoo/template/app/src/main/java/com/example/flo/SongFragment.kt new file mode 100644 index 0000000..033d929 --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/SongFragment.kt @@ -0,0 +1,24 @@ +package com.example.flo + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.flo.databinding.FragmentSongBinding + +class SongFragment : Fragment() { + + lateinit var binding : FragmentSongBinding + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentSongBinding.inflate(inflater,container,false) + + return binding.root + } + +} \ No newline at end of file diff --git a/isoo/template/app/src/main/java/com/example/flo/VideoFragment.kt b/isoo/template/app/src/main/java/com/example/flo/VideoFragment.kt new file mode 100644 index 0000000..66d178b --- /dev/null +++ b/isoo/template/app/src/main/java/com/example/flo/VideoFragment.kt @@ -0,0 +1,24 @@ +package com.example.flo + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.flo.databinding.FragmentVideoBinding + +class VideoFragment : Fragment() { + + lateinit var binding : FragmentVideoBinding + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + binding = FragmentVideoBinding.inflate(inflater,container,false) + + return binding.root + } + +} \ No newline at end of file diff --git a/isoo/template/app/src/main/res/drawable/splash.xml b/isoo/template/app/src/main/res/drawable/splash.xml index ace8a7d..da83aa4 100644 --- a/isoo/template/app/src/main/res/drawable/splash.xml +++ b/isoo/template/app/src/main/res/drawable/splash.xml @@ -4,5 +4,4 @@ - \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/activity_main.xml b/isoo/template/app/src/main/res/layout/activity_main.xml index 7b38a4a..0e4be2c 100644 --- a/isoo/template/app/src/main/res/layout/activity_main.xml +++ b/isoo/template/app/src/main/res/layout/activity_main.xml @@ -14,6 +14,23 @@ app:layout_constraintBottom_toTopOf="@id/main_player_cl" app:layout_constraintTop_toTopOf="parent"/> + + + app:layout_constraintTop_toBottomOf="@+id/album_album_iv"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + app:layout_constraintEnd_toEndOf="parent"/> \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/fragment_banner.xml b/isoo/template/app/src/main/res/layout/fragment_banner.xml new file mode 100644 index 0000000..3b01054 --- /dev/null +++ b/isoo/template/app/src/main/res/layout/fragment_banner.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/fragment_detail.xml b/isoo/template/app/src/main/res/layout/fragment_detail.xml new file mode 100644 index 0000000..479f932 --- /dev/null +++ b/isoo/template/app/src/main/res/layout/fragment_detail.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/fragment_home.xml b/isoo/template/app/src/main/res/layout/fragment_home.xml index e701dd9..ff56f38 100644 --- a/isoo/template/app/src/main/res/layout/fragment_home.xml +++ b/isoo/template/app/src/main/res/layout/fragment_home.xml @@ -2,7 +2,8 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/home_today_music_album_rv"/> + \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/fragment_locker.xml b/isoo/template/app/src/main/res/layout/fragment_locker.xml index 38a93a5..11605da 100644 --- a/isoo/template/app/src/main/res/layout/fragment_locker.xml +++ b/isoo/template/app/src/main/res/layout/fragment_locker.xml @@ -5,12 +5,102 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> + + + + + + + + + + + + + + + + + app:layout_constraintTop_toBottomOf="@id/locker_select_all_img_iv" /> \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/fragment_locker_savedsong.xml b/isoo/template/app/src/main/res/layout/fragment_locker_savedsong.xml new file mode 100644 index 0000000..c01bdde --- /dev/null +++ b/isoo/template/app/src/main/res/layout/fragment_locker_savedsong.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/fragment_song.xml b/isoo/template/app/src/main/res/layout/fragment_song.xml new file mode 100644 index 0000000..533d035 --- /dev/null +++ b/isoo/template/app/src/main/res/layout/fragment_song.xml @@ -0,0 +1,556 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/fragment_video.xml b/isoo/template/app/src/main/res/layout/fragment_video.xml new file mode 100644 index 0000000..4da6a83 --- /dev/null +++ b/isoo/template/app/src/main/res/layout/fragment_video.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/item_album.xml b/isoo/template/app/src/main/res/layout/item_album.xml new file mode 100644 index 0000000..5eba725 --- /dev/null +++ b/isoo/template/app/src/main/res/layout/item_album.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/isoo/template/app/src/main/res/layout/item_song.xml b/isoo/template/app/src/main/res/layout/item_song.xml new file mode 100644 index 0000000..5a494ba --- /dev/null +++ b/isoo/template/app/src/main/res/layout/item_song.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/isoo/template/app/src/main/res/raw/music_bboom.mp3 b/isoo/template/app/src/main/res/raw/music_bboom.mp3 new file mode 100644 index 0000000..b555591 Binary files /dev/null and b/isoo/template/app/src/main/res/raw/music_bboom.mp3 differ diff --git a/isoo/template/app/src/main/res/raw/music_boy.mp3 b/isoo/template/app/src/main/res/raw/music_boy.mp3 new file mode 100644 index 0000000..c19f239 Binary files /dev/null and b/isoo/template/app/src/main/res/raw/music_boy.mp3 differ diff --git a/isoo/template/app/src/main/res/raw/music_butter.mp3 b/isoo/template/app/src/main/res/raw/music_butter.mp3 new file mode 100644 index 0000000..a6b952f Binary files /dev/null and b/isoo/template/app/src/main/res/raw/music_butter.mp3 differ diff --git a/isoo/template/app/src/main/res/raw/music_flu.mp3 b/isoo/template/app/src/main/res/raw/music_flu.mp3 new file mode 100644 index 0000000..e6a0d7e Binary files /dev/null and b/isoo/template/app/src/main/res/raw/music_flu.mp3 differ diff --git a/isoo/template/app/src/main/res/raw/music_lilac.mp3 b/isoo/template/app/src/main/res/raw/music_lilac.mp3 new file mode 100644 index 0000000..2e3c0d9 Binary files /dev/null and b/isoo/template/app/src/main/res/raw/music_lilac.mp3 differ diff --git a/isoo/template/app/src/main/res/raw/music_next.mp3 b/isoo/template/app/src/main/res/raw/music_next.mp3 new file mode 100644 index 0000000..6261b05 Binary files /dev/null and b/isoo/template/app/src/main/res/raw/music_next.mp3 differ diff --git a/isoo/template/app/src/main/res/values/themes.xml b/isoo/template/app/src/main/res/values/themes.xml index 4a5c354..37304e5 100644 --- a/isoo/template/app/src/main/res/values/themes.xml +++ b/isoo/template/app/src/main/res/values/themes.xml @@ -20,4 +20,8 @@ true + \ No newline at end of file diff --git a/isoo/test.txt b/isoo/test.txt deleted file mode 100644 index 30d74d2..0000000 --- a/isoo/test.txt +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file