Skip to content

Commit

Permalink
fragment viewpager2
Browse files Browse the repository at this point in the history
  • Loading branch information
yeseoRyu committed Jan 16, 2025
1 parent a5f79d8 commit 5ec79c2
Show file tree
Hide file tree
Showing 13 changed files with 160 additions and 64 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ dependencies {
implementation(libs.room.runtime)
implementation(libs.room.ktx)
implementation(libs.fragment.ktx)
implementation(libs.activity.ktx)
implementation(libs.viewpager2)

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
Expand Down
30 changes: 21 additions & 9 deletions app/src/main/java/com/flab/deepsleep/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,29 @@ import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.widget.doOnTextChanged
import androidx.viewpager2.widget.ViewPager2
import com.flab.deepsleep.databinding.ActivityMainBinding
import com.flab.deepsleep.ui.home.HomeFragment
import com.flab.deepsleep.ui.adapter.ViewPagerAdapter
import com.flab.deepsleep.ui.photo.PhotoViewModel
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
private val photoViewModel: PhotoViewModel by viewModels()
private val binding: ActivityMainBinding by lazy { ActivityMainBinding.inflate(layoutInflater) }
private val tabLayout: TabLayout by lazy { binding.tabLayout }
private val viewPager: ViewPager2 by lazy { binding.viewPager }
private val viewPagerAdapter: ViewPagerAdapter by lazy { ViewPagerAdapter(this) }

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

/* 검색어 입력시 자동 호출 */
binding.editText.doOnTextChanged { text, start, before, count ->
Expand All @@ -29,16 +36,21 @@ class MainActivity : AppCompatActivity() {

/* 에러 관찰 */
photoViewModel.errorMessage.observe(/* owner = */ this) { it ->
it?.let {
showErrorDialog(it)
}
it?.let { showErrorDialog(it) }
}
}

private fun setHomeFragment(){
supportFragmentManager.beginTransaction()
.replace(binding.mainFragment.id, HomeFragment())
.commit()
private fun setViewPager() {
viewPager.adapter = viewPagerAdapter
val tabIcons = listOf(R.drawable.ic_home, R.drawable.ic_bookmark)
TabLayoutMediator(tabLayout, viewPager) { tab, position ->
tab.icon = ContextCompat.getDrawable(this, tabIcons[position])
tab.text = when (position) {
0 -> ""
1 -> "북마크"
else -> "${position + 1}"
}
}.attach()
}

private fun showErrorDialog(message: String) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package com.flab.deepsleep.ui.adapter

import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
Expand All @@ -10,8 +12,8 @@ import com.flab.deepsleep.data.entity.photos.SinglePhoto
import com.flab.deepsleep.databinding.ItemPhotoBinding
import com.flab.deepsleep.ui.photo.OnButtonClick

class PhotoAdapter(private val buttonClick: OnButtonClick) :
PagingDataAdapter<SinglePhoto, PhotoAdapter.ImageViewHolder>(ARTICLE_DIFF_CALLBACK) {
class PagingAdapter(private val buttonClick: OnButtonClick) :
PagingDataAdapter<SinglePhoto, PagingAdapter.ImageViewHolder>(ARTICLE_DIFF_CALLBACK) {

inner class ImageViewHolder(
private val binding: ItemPhotoBinding,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.flab.deepsleep.ui.adapter

import androidx.fragment.app.Fragment
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.flab.deepsleep.MainActivity
import com.flab.deepsleep.ui.fragment.BookmarkFragment
import com.flab.deepsleep.ui.fragment.HomeFragment

class ViewPagerAdapter(mainActivity: MainActivity) : FragmentStateAdapter(mainActivity) {
override fun getItemCount(): Int = 2

override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> HomeFragment()
1 -> BookmarkFragment()
else -> HomeFragment()
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.flab.deepsleep.ui.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.flab.deepsleep.databinding.FragmentBookmarkBinding
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class BookmarkFragment : Fragment() {

private val binding: FragmentBookmarkBinding by lazy { FragmentBookmarkBinding.inflate(layoutInflater) }

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


}
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
package com.flab.deepsleep.ui.home
package com.flab.deepsleep.ui.fragment

import PhotoAdapter
import com.flab.deepsleep.ui.adapter.PagingAdapter
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.fragment.app.activityViewModels
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 binding: FragmentHomeBinding by lazy { FragmentHomeBinding.inflate(layoutInflater) }
private val photoViewModel: PhotoViewModel by activityViewModels()
private val photoRecyclerView: RecyclerView by lazy { binding.photosRecyclerView }
private val photoAdapter: PhotoAdapter by lazy {
PhotoAdapter { singlePhoto ->
private val pagingAdapter: PagingAdapter by lazy {
PagingAdapter { singlePhoto ->
photoViewModel.insertPhoto(singlePhoto)
}
}
Expand All @@ -40,21 +37,16 @@ class HomeFragment : Fragment() {
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")
}
photoViewModel.items.collectLatest { pagingData ->
pagingAdapter.submitData(pagingData)
}
}
}

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

}
13 changes: 13 additions & 0 deletions app/src/main/res/drawable/ic_bookmark.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="26dp"
android:height="26dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M8,4.41c1.387,-1.425 4.854,1.07 0,4.277C3.146,5.48 6.613,2.986 8,4.412z"
android:fillColor="@color/black"
android:fillType="evenOdd"/>
<path
android:pathData="M2,2a2,2 0,0 1,2 -2h8a2,2 0,0 1,2 2v13.5a0.5,0.5 0,0 1,-0.777 0.416L8,13.101l-5.223,2.815A0.5,0.5 0,0 1,2 15.5zM4,1a1,1 0,0 0,-1 1v12.566l4.723,-2.482a0.5,0.5 0,0 1,0.554 0L13,14.566L13,2a1,1 0,0 0,-1 -1z"
android:fillColor="@color/black"/>
</vector>
12 changes: 12 additions & 0 deletions app/src/main/res/drawable/ic_home.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="26dp"
android:height="26dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M8.707,1.5a1,1 0,0 0,-1.414 0L0.646,8.146a0.5,0.5 0,0 0,0.708 0.708L8,2.207l6.646,6.647a0.5,0.5 0,0 0,0.708 -0.708L13,5.793V2.5a0.5,0.5 0,0 0,-0.5 -0.5h-1a0.5,0.5 0,0 0,-0.5 0.5v1.293z"
android:fillColor="@color/black"/>
<path
android:pathData="m8,3.293 l6,6V13.5a1.5,1.5 0,0 1,-1.5 1.5h-9A1.5,1.5 0,0 1,2 13.5V9.293z"
android:fillColor="@color/black"/>
</vector>
59 changes: 28 additions & 31 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,70 +5,67 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/search_bar"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
app:layout_constraintTop_toTopOf="parent">

<EditText
android:id="@+id/editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:hint="@string/search"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/search_button"
app:layout_constraintBottom_toBottomOf="parent"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<ImageView
android:id="@+id/search_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="8dp"
android:src="@drawable/ic_search"
app:layout_constraintTop_toTopOf="@+id/editText"
app:layout_constraintBottom_toBottomOf="@+id/editText"
app:layout_constraintStart_toEndOf="@+id/editText"
app:layout_constraintEnd_toEndOf="parent"
android:padding="8dp" />

app:layout_constraintStart_toEndOf="@+id/editText"
app:layout_constraintTop_toTopOf="@+id/editText" />
</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.fragment.app.FragmentContainerView
android:id="@+id/main_fragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@+id/search_bar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/tabLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="@+id/foot_bar"/>
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_bar" />

<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/foot_bar"
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_constraintTop_toBottomOf="@+id/main_fragment"
app:layout_constraintStart_toStartOf="parent"
android:layout_height="60dp"
android:background="@color/white_gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent">
app:tabMode="fixed" />

</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
app:layout_constraintBottom_toTopOf="@+id/tabLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_bar" />

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

<TextView
android:id="@+id/test"
android:text="@string/test"
android:textSize="20sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 0 additions & 2 deletions app/src/main/res/layout/fragment_home.xml
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
<?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" />
Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>

<color name="white_gray">#F2F2F2</color>

</resources>
6 changes: 5 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ okhttp-profiler = "1.0.8"
room = "2.6.1"
ksp = "2.0.21-1.0.27"
fragment-ktx = "1.8.5"
activity-ktx = "1.10.0"
viewpager2 = "1.1.0"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
Expand Down Expand Up @@ -59,7 +61,9 @@ 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"}
fragment-ktx = { module = "androidx.fragment:fragment-ktx", version.ref = "fragment-ktx" }
activity-ktx = { module = "androidx.activity:activity-ktx", version.ref = "activity-ktx" }
viewpager2 = { module = "androidx.viewpager2:viewpager2", version.ref = "viewpager2" }

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

0 comments on commit 5ec79c2

Please sign in to comment.