Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Week7 필수 과제 구..현.. 중 #5

Open
wants to merge 1 commit into
base: develop/view
Choose a base branch
from
Open
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
23 changes: 13 additions & 10 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,37 @@
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.INTERNET" />
//외부 sd카드 접근 권한
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:usesCleartextTraffic="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.INSOPTAndroidPractice"
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".home.HomeActivity"
android:exported="false">
</activity>
<activity
android:name=".signup.SignUpActivity"
android:exported="false" />
<activity
android:name=".login.LoginActivity"
android:name=".music.PlayListActivity"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".home.HomeActivity"
android:exported="false"></activity>
<activity
android:name=".signup.SignUpActivity"
android:exported="false" />
<activity
android:name=".login.LoginActivity"
android:exported="true">

</activity>
</application>
Expand Down
42 changes: 42 additions & 0 deletions app/src/main/java/org/sopt/androidpractice/music/MusicAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.sopt.androidpractice.music

import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import org.sopt.androidpractice.databinding.ItemMusicBinding
import org.sopt.androidpractice.remote.ResponseMusicListDto

class MusicAdapter(context: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val inflater by lazy { LayoutInflater.from(context) }
private var playList: List<ResponseMusicListDto.MusicList> = emptyList()

class MusicViewHolder(private val binding: ItemMusicBinding) :
RecyclerView.ViewHolder(binding.root) {
fun setPlayList(music: ResponseMusicListDto.MusicList) {
Glide.with(this.binding.root)
.load(music.image)
.circleCrop()
.into(binding.music)
binding.musicTitle.text = music.title
binding.singer.text = music.singer
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val binding = ItemMusicBinding.inflate(inflater, parent, false)
return MusicViewHolder(binding)
}

override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is MusicViewHolder) holder.setPlayList(playList[position])
}

override fun getItemCount() = playList.size

fun setPlayList(playList: List<ResponseMusicListDto.MusicList>) {
this.playList = playList.toList()
notifyDataSetChanged()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package org.sopt.androidpractice.music

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.activity.viewModels
import com.google.android.material.snackbar.Snackbar
import org.sopt.androidpractice.databinding.ActivityPlayListBinding
import org.sopt.androidpractice.home.adapter.UserAdapter
import org.sopt.androidpractice.remote.MusicServicePool
import org.sopt.androidpractice.remote.ResponseMusicListDto
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class PlayListActivity : AppCompatActivity() {
private val playListService = MusicServicePool.musicService
private val viewModel : PlayListViewModel by viewModels()

private var _binding: ActivityPlayListBinding? = null
val binding : ActivityPlayListBinding
get() = requireNotNull(_binding) {"error in MusicActivity"}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
_binding = ActivityPlayListBinding.inflate(layoutInflater)
setContentView(binding.root)

val adapter = MusicAdapter(this)
playListService.getPlaylist().enqueue(object : Callback<ResponseMusicListDto>{
override fun onResponse(
call: Call<ResponseMusicListDto>,
response: Response<ResponseMusicListDto>
) {
if(response.isSuccessful){
viewModel.musicList.addAll(response.body()?.data!!)

binding.rvMusic.adapter = adapter
adapter.setPlayList(viewModel.musicList)
}
else if (response.code() in 400 until 500) {
Snackbar.make(binding.root, "{${response.code()}error}", Snackbar.LENGTH_LONG)
.show()
}
}

override fun onFailure(call: Call<ResponseMusicListDto>, t: Throwable) {
Snackbar.make(binding.root, "서버 통신 장애가 발생", Snackbar.LENGTH_LONG).show()
}
})


}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.sopt.androidpractice.music

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import org.sopt.androidpractice.remote.MusicServicePool
import org.sopt.androidpractice.remote.ResponseMusicListDto
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class PlayListViewModel : ViewModel() {
private val _music = MutableLiveData<ResponseMusicListDto>()
val music: LiveData<ResponseMusicListDto>
get() = _music

private val _errorMessage = MutableLiveData<String>()
val errorMessage: LiveData<String>
get() = _errorMessage

val musicList = mutableListOf<ResponseMusicListDto.MusicList>()
// private val playListService = MusicServicePool.musicService
//
// fun generatePlayList() {
// playListService.getPlaylist().enqueue(object : Callback<ResponseMusicListDto> {
// override fun onResponse(
// call: Call<ResponseMusicListDto>,
// response: Response<ResponseMusicListDto>
// ) {
// if (response.isSuccessful) {
// _music.value = response.body()!!
// } else if (response.code() in 400 until 500) {
// _errorMessage.value = response.message()
// }
// }
//
// override fun onFailure(call: Call<ResponseMusicListDto>, t: Throwable) {
// _errorMessage.value = t.message
// }
// })
//
// }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.sopt.androidpractice.remote

import com.jakewharton.retrofit2.converter.kotlinx.serialization.asConverterFactory
import kotlinx.serialization.json.Json
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit

object MusicApiFactory{
private val client by lazy {
OkHttpClient.Builder()
.addInterceptor(
HttpLoggingInterceptor().apply {
level = HttpLoggingInterceptor.Level.BODY
}
).build()
}

val retrofit: Retrofit by lazy {
Retrofit.Builder()
.baseUrl("http://3.34.53.11:8080/")
.addConverterFactory(Json.asConverterFactory("application/json".toMediaType()))
.build()
}

inline fun <reified T> create(): T = retrofit.create<T>(T::class.java)
}

object MusicServicePool {
val musicService = MusicApiFactory.create<MusicService>()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.sopt.androidpractice.remote

import retrofit2.Call
import retrofit2.http.GET

interface MusicService {
@GET("music/list")
fun getPlaylist(): Call<ResponseMusicListDto>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.sopt.androidpractice.remote

import kotlinx.serialization.Serializable

@Serializable
data class ResponseMusicListDto(
val data: List<MusicList>,
val message: String,
val statusCode: Int,
val success: Boolean
) {
@Serializable
data class MusicList(
val id: Int,
val image: String,
val singer: String,
val title: String
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.sync.Mutex
import org.sopt.androidpractice.remote.RequestSignupDto
import org.sopt.androidpractice.remote.ResponseSignupDto
import org.sopt.androidpractice.remote.ServicePool.signupService
Expand Down
Binary file added app/src/main/res/drawable/ic_diary.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions app/src/main/res/layout/activity_play_list.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".music.PlayListActivity">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_music"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"
tools:listitem="@layout/item_music"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>

</androidx.constraintlayout.widget.ConstraintLayout>
57 changes: 57 additions & 0 deletions app/src/main/res/layout/item_music.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
>

<!-- <data>-->
<!-- <variable-->
<!-- name="music"-->
<!-- type="org.sopt.androidpractice.music.PlayListActivity" />-->
<!-- </data>-->

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingVertical="16dp"
android:paddingHorizontal="6dp"
>

<ImageView
android:id="@+id/music"
android:layout_width="100dp"
android:layout_height="0dp"
android:src="@drawable/ic_diary"
app:layout_constraintDimensionRatio="1"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/music_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginStart="30dp"
android:textColor="@color/black"
android:textSize="20dp"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@+id/music"
app:layout_constraintTop_toTopOf="@id/music"
tools:text="Diary" />


<TextView
android:id="@+id/singer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16dp"
android:textStyle="bold"
android:layout_marginTop="16dp"
app:layout_constraintStart_toStartOf="@+id/music_title"
app:layout_constraintTop_toBottomOf="@+id/music_title"
tools:text="Nowin" />


</androidx.constraintlayout.widget.ConstraintLayout>

</layout>
13 changes: 13 additions & 0 deletions app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,17 @@
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="gray">#e0e0e0</color>

<color name="grey_50">#fafafa</color>
<color name="grey_100">#f5f5f5</color>
<color name="grey_200">#eeeeee</color>
<color name="grey_300">#e0e0e0</color>
<color name="grey_400">#bdbdbd</color>
<color name="grey_500">#9e9e9e</color>
<color name="grey_600">#757575</color>
<color name="grey_700">#616161</color>
<color name="grey_800">#424242</color>
<color name="grey_900">#212121</color>
<color name="grey_1000b">#000000</color>
<color name="grey_1000w">#ffffff</color>
</resources>
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.nonTransitiveRClass=true