Skip to content

Commit

Permalink
fragment
Browse files Browse the repository at this point in the history
  • Loading branch information
yeseoRyu committed Jan 15, 2025
1 parent bc1b12c commit a5f79d8
Show file tree
Hide file tree
Showing 10 changed files with 118 additions and 56 deletions.
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ dependencies {
implementation(libs.okhttp.profiler)
implementation(libs.room.runtime)
implementation(libs.room.ktx)
implementation(libs.fragment.ktx)

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
Expand Down
40 changes: 8 additions & 32 deletions app/src/main/java/com/flab/deepsleep/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,56 +1,26 @@
package com.flab.deepsleep

import PhotoAdapter
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.widget.doOnTextChanged
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.Observer
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.flab.deepsleep.data.entity.photos.SinglePhoto
import com.flab.deepsleep.databinding.ActivityMainBinding
import com.flab.deepsleep.ui.home.HomeFragment
import com.flab.deepsleep.ui.photo.PhotoViewModel
import com.flab.deepsleep.ui.photo.OnButtonClick
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import timber.log.Timber

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val photoViewModel: PhotoViewModel by viewModels()
private val binding: ActivityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) }
private val photoRecyclerView: RecyclerView by lazy { binding.photosRecyclerView }
private val photoAdapter: PhotoAdapter by lazy {
PhotoAdapter { singlePhoto ->
photoViewModel.insertPhoto(singlePhoto)
}
}

private fun setRecyclerView() {
photoRecyclerView.layoutManager = GridLayoutManager(this, 2)
photoRecyclerView.adapter = photoAdapter
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(binding.root)
setRecyclerView()

lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
photoViewModel.items.collectLatest {
photoAdapter.submitData(it)
}
}
}
setHomeFragment();

/* 검색어 입력시 자동 호출 */
binding.editText.doOnTextChanged { text, start, before, count ->
Expand All @@ -65,6 +35,12 @@ class MainActivity : AppCompatActivity() {
}
}

private fun setHomeFragment(){
supportFragmentManager.beginTransaction()
.replace(binding.mainFragment.id, HomeFragment())
.commit()
}

private fun showErrorDialog(message: String) {
AlertDialog.Builder(this)
.setTitle("Error")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
package com.flab.deepsleep.data.api

import com.flab.deepsleep.data.entity.photos.SinglePhoto

import com.flab.deepsleep.data.entity.photos.SearchPhotos
import retrofit2.http.GET
import retrofit2.http.Path
import retrofit2.http.Query

interface UnplashService {

@GET("/photos/random")
suspend fun getRandomPhotos(
@Query("client_id") clientId: String,
@Query("count") count: Int = 1
): List<SinglePhoto>


@GET("/search/photos")
suspend fun getSearchPhotos(
@Query("client_id") clientId: String,
Expand All @@ -27,6 +24,4 @@ interface UnplashService {
@Path("id") photoId: String,
@Query("client_id") clientId: String
): SinglePhoto


}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.flab.deepsleep.data.source
import androidx.paging.PagingSource
import androidx.paging.PagingState
import com.flab.deepsleep.data.entity.photos.SinglePhoto
import timber.log.Timber

class PhotoPagingSource(
private val photos: List<SinglePhoto>
Expand Down
60 changes: 60 additions & 0 deletions app/src/main/java/com/flab/deepsleep/ui/home/HomeFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.flab.deepsleep.ui.home

import PhotoAdapter
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.flab.deepsleep.databinding.FragmentHomeBinding
import com.flab.deepsleep.ui.photo.PhotoViewModel
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import timber.log.Timber

@AndroidEntryPoint
class HomeFragment : Fragment() {
private val photoViewModel: PhotoViewModel by viewModels()
val binding: FragmentHomeBinding by lazy { FragmentHomeBinding.inflate(layoutInflater) }
private val photoRecyclerView: RecyclerView by lazy { binding.photosRecyclerView }
private val photoAdapter: PhotoAdapter by lazy {
PhotoAdapter { singlePhoto ->
photoViewModel.insertPhoto(singlePhoto)
}
}

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View {
return binding.root
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setRecyclerView()


viewLifecycleOwner.lifecycleScope.launch {
Timber.d("HomeFragment Coroutine 시작됨 (onViewCreated)") // 로그 추가
viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
photoViewModel.items.collectLatest {
photoAdapter.submitData(it)

Timber.d("HomeFragment $it")
}
}
}
}
private fun setRecyclerView() {
photoRecyclerView.layoutManager = GridLayoutManager(context, 2)
photoRecyclerView.adapter = photoAdapter
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class PhotoAdapter(private val buttonClick: OnButtonClick) :
buttonClick.onButtonClick(photo)
}

val imageUrl = photo?.urls?.raw
val imageUrl = photo.urls?.raw
if (imageUrl != null) {
Glide.with(imageView.context)
.load(imageUrl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.flab.deepsleep.data.source.PhotoPagingSource
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
Expand All @@ -44,10 +45,7 @@ class PhotoViewModel @Inject constructor(
private val _photoState = MutableLiveData<List<SinglePhoto>?>()
val photoState: MutableLiveData<List<SinglePhoto>?> get() = _photoState

/* Photo Database */
val allPhotos: Flow<List<Photo>> = photoRepository.getAllPhotos()


@OptIn(ExperimentalCoroutinesApi::class)
val items: Flow<PagingData<SinglePhoto>> = _photoState.asFlow()
.map { state -> state ?: emptyList() }
.flatMapLatest { photos ->
Expand All @@ -70,7 +68,7 @@ class PhotoViewModel @Inject constructor(
}
}

suspend fun getSearchPhotos(query: String): List<SinglePhoto> {
private suspend fun getSearchPhotos(query: String): List<SinglePhoto> {
return coroutineScope {
try {
unplashRepository.getSearchPhotos(query)
Expand Down
38 changes: 25 additions & 13 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,35 @@

</androidx.constraintlayout.widget.ConstraintLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/photosRecyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="10dp"
android:padding="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_bar" />
<!-- <androidx.recyclerview.widget.RecyclerView-->
<!-- android:id="@+id/photosRecyclerView"-->
<!-- android:layout_width="0dp"-->
<!-- android:layout_height="0dp"-->
<!-- android:layout_margin="10dp"-->
<!-- android:padding="16dp"-->
<!-- app:layout_constraintBottom_toBottomOf="parent"-->
<!-- app:layout_constraintEnd_toEndOf="parent"-->
<!-- app:layout_constraintStart_toStartOf="parent"-->
<!-- app:layout_constraintTop_toBottomOf="@+id/search_bar" />-->

<androidx.fragment.app.FragmentContainerView
android:id="@+id/menu_bar"
android:id="@+id/main_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/foot_bar"/>

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/foot_bar"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintTop_toBottomOf="@+id/main_fragment"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">

</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
17 changes: 17 additions & 0 deletions app/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?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">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/photosRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 2 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ okhttp = "4.12.0"
okhttp-profiler = "1.0.8"
room = "2.6.1"
ksp = "2.0.21-1.0.27"
fragment-ktx = "1.8.5"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
Expand Down Expand Up @@ -58,6 +59,7 @@ okhttp-profiler = { module = "com.localebro:okhttpprofiler", version.ref = "okht
room-runtime = { module = "androidx.room:room-runtime", version.ref = "room" }
room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragment-ktx"}

[plugins]
android-application = { id = "com.android.application", version.ref = "agp" }
Expand Down

0 comments on commit a5f79d8

Please sign in to comment.