Skip to content

Commit fab56dc

Browse files
committed
Feat: Fragment 화면에 ViewPager 및 TabLayout 구현
1 parent 8273be9 commit fab56dc

22 files changed

+1129
-575
lines changed

Heather/FLOClone/app/src/main/java/com/example/floclone/AlbumFragment.kt

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@ import androidx.fragment.app.Fragment
55
import android.view.LayoutInflater
66
import android.view.View
77
import android.view.ViewGroup
8-
import android.widget.Toast
8+
import com.google.android.material.tabs.TabLayoutMediator
99
import com.example.floclone.databinding.FragmentAlbumBinding
1010

1111
class AlbumFragment : Fragment() {
1212

1313
lateinit var binding: FragmentAlbumBinding
14+
private val information = arrayListOf("수록곡", "상세정보", "영상")
15+
1416

1517
override fun onCreateView(
1618
inflater: LayoutInflater,
@@ -19,14 +21,18 @@ class AlbumFragment : Fragment() {
1921
): View? {
2022
binding = FragmentAlbumBinding.inflate(inflater, container, false)
2123

24+
// 뒤로가기 버튼
2225
binding.albumBackIv.setOnClickListener {
2326
(context as MainActivity).supportFragmentManager.beginTransaction()
2427
.replace(R.id.main_frm, HomeFragment()).commitAllowingStateLoss()
2528
}
2629

27-
binding.songLalacLayout.setOnClickListener {
28-
Toast.makeText(activity, "LILAC", Toast.LENGTH_SHORT).show()
29-
}
30+
// ViewPager랑 TabLayout 연결
31+
val albumAdapter = AlbumVPAdapter(this)
32+
binding.albumContentVp.adapter = albumAdapter
33+
TabLayoutMediator(binding.albumContentTb, binding.albumContentVp) { tab, position ->
34+
tab.text = information[position]
35+
}.attach()
3036

3137
return binding.root
3238
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.example.floclone
2+
3+
import androidx.fragment.app.Fragment
4+
import androidx.viewpager2.adapter.FragmentStateAdapter
5+
6+
class AlbumVPAdapter(fragment:Fragment) : FragmentStateAdapter(fragment) {
7+
override fun getItemCount(): Int = 3
8+
9+
override fun createFragment(position: Int): Fragment {
10+
return when(position){
11+
0 -> SongFragment()
12+
1 -> DetailFragment()
13+
else -> VideoFragment()
14+
}
15+
}
16+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.example.floclone
2+
3+
import android.os.Bundle
4+
import androidx.fragment.app.Fragment
5+
import android.view.LayoutInflater
6+
import android.view.View
7+
import android.view.ViewGroup
8+
import com.example.floclone.databinding.FragmentBannerBinding
9+
10+
class BannerFragment(val imgRes: Int) : Fragment() {
11+
12+
lateinit var binding : FragmentBannerBinding
13+
14+
override fun onCreateView(
15+
inflater: LayoutInflater,
16+
container: ViewGroup?,
17+
savedInstanceState: Bundle?
18+
): View? {
19+
binding = FragmentBannerBinding.inflate(inflater, container, false)
20+
binding.bannerImageIv.setImageResource(imgRes) // 전달받은 imgRes 사용
21+
return binding.root
22+
}
23+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.example.floclone
2+
3+
import androidx.fragment.app.Fragment
4+
import androidx.viewpager2.adapter.FragmentStateAdapter
5+
6+
class BannerVPAdapter(fragment: Fragment) :FragmentStateAdapter(fragment) {
7+
8+
private val fragmentlist : ArrayList<Fragment> = ArrayList()
9+
10+
override fun getItemCount(): Int = fragmentlist.size
11+
12+
override fun createFragment(position: Int): Fragment = fragmentlist[position]
13+
14+
fun addFragment(fragment: Fragment){
15+
fragmentlist.add(fragment)
16+
notifyItemInserted(fragmentlist.size-1)
17+
}
18+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.example.floclone
2+
3+
import android.os.Bundle
4+
import androidx.fragment.app.Fragment
5+
import android.view.LayoutInflater
6+
import android.view.View
7+
import android.view.ViewGroup
8+
import com.example.floclone.databinding.FragmentDetailBinding
9+
10+
class DetailFragment : Fragment() {
11+
12+
lateinit var binding: FragmentDetailBinding
13+
14+
override fun onCreateView(
15+
inflater: LayoutInflater,
16+
container: ViewGroup?,
17+
savedInstanceState: Bundle?
18+
): View? {
19+
binding = FragmentDetailBinding.inflate(inflater,container,false)
20+
21+
return binding.root
22+
}
23+
24+
}

Heather/FLOClone/app/src/main/java/com/example/floclone/HomeFragment.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import androidx.fragment.app.Fragment
55
import android.view.LayoutInflater
66
import android.view.View
77
import android.view.ViewGroup
8+
import androidx.viewpager2.widget.ViewPager2
89
import com.example.floclone.databinding.FragmentHomeBinding
910

1011
class HomeFragment : Fragment() {
@@ -23,6 +24,12 @@ class HomeFragment : Fragment() {
2324
.replace(R.id.main_frm, AlbumFragment()).commitAllowingStateLoss()
2425
}
2526

27+
val bannerAdapter = BannerVPAdapter(this)
28+
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp))
29+
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp2))
30+
binding.homeBannerVp.adapter = bannerAdapter
31+
binding.homeBannerVp.orientation = ViewPager2.ORIENTATION_HORIZONTAL
32+
2633
return binding.root
2734
}
2835

Heather/FLOClone/app/src/main/java/com/example/floclone/LockerFragment.kt

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,55 +5,27 @@ import androidx.fragment.app.Fragment
55
import android.view.LayoutInflater
66
import android.view.View
77
import android.view.ViewGroup
8+
import com.example.floclone.databinding.FragmentLockerBinding
9+
import com.google.android.material.tabs.TabLayoutMediator
810

9-
// TODO: Rename parameter arguments, choose names that match
10-
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
11-
private const val ARG_PARAM1 = "param1"
12-
private const val ARG_PARAM2 = "param2"
1311

14-
/**
15-
* A simple [Fragment] subclass.
16-
* Use the [LockerFragment.newInstance] factory method to
17-
* create an instance of this fragment.
18-
*/
1912
class LockerFragment : Fragment() {
20-
// TODO: Rename and change types of parameters
21-
private var param1: String? = null
22-
private var param2: String? = null
23-
24-
override fun onCreate(savedInstanceState: Bundle?) {
25-
super.onCreate(savedInstanceState)
26-
arguments?.let {
27-
param1 = it.getString(ARG_PARAM1)
28-
param2 = it.getString(ARG_PARAM2)
29-
}
30-
}
13+
lateinit var binding: FragmentLockerBinding
14+
private val information = arrayListOf("저장한곡", "음악파일")
3115

3216
override fun onCreateView(
33-
inflater: LayoutInflater, container: ViewGroup?,
17+
inflater: LayoutInflater,
18+
container: ViewGroup?,
3419
savedInstanceState: Bundle?
35-
): View? {
36-
// Inflate the layout for this fragment
37-
return inflater.inflate(R.layout.fragment_locker, container, false)
38-
}
20+
): View {
21+
binding = FragmentLockerBinding.inflate(inflater, container, false)
22+
23+
val lockerAdapter = LockerVPAdapter(this)
24+
binding.lockerContentVp.adapter = lockerAdapter
25+
TabLayoutMediator(binding.lockerContentTb, binding.lockerContentVp) { tab, position ->
26+
tab.text = information[position]
27+
}.attach()
3928

40-
companion object {
41-
/**
42-
* Use this factory method to create a new instance of
43-
* this fragment using the provided parameters.
44-
*
45-
* @param param1 Parameter 1.
46-
* @param param2 Parameter 2.
47-
* @return A new instance of fragment LockerFragment.
48-
*/
49-
// TODO: Rename and change types and number of parameters
50-
@JvmStatic
51-
fun newInstance(param1: String, param2: String) =
52-
LockerFragment().apply {
53-
arguments = Bundle().apply {
54-
putString(ARG_PARAM1, param1)
55-
putString(ARG_PARAM2, param2)
56-
}
57-
}
29+
return binding.root
5830
}
5931
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.example.floclone
2+
3+
import androidx.fragment.app.Fragment
4+
import androidx.viewpager2.adapter.FragmentStateAdapter
5+
6+
class LockerVPAdapter (fragment : Fragment) : FragmentStateAdapter(fragment) {
7+
override fun getItemCount(): Int = 2
8+
9+
override fun createFragment(position: Int): Fragment {
10+
return when(position){
11+
0 -> SavedSongFragment()
12+
else -> MusicFileFragment()
13+
}
14+
}
15+
}

Heather/FLOClone/app/src/main/java/com/example/floclone/MainActivity.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ class MainActivity : AppCompatActivity() {
1616
private val songActivityLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
1717
if (result.resultCode == RESULT_OK) {
1818
val songTitle = result.data?.getStringExtra("songTitle")
19-
// 노래 제목을 Toast 메시지로 출력
2019
songTitle?.let {
2120
Toast.makeText(this, "$it", Toast.LENGTH_SHORT).show()
2221
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.example.floclone
2+
3+
import android.os.Bundle
4+
import androidx.fragment.app.Fragment
5+
import android.view.LayoutInflater
6+
import android.view.View
7+
import android.view.ViewGroup
8+
import com.example.floclone.databinding.FragmentMusicFileBinding
9+
10+
class MusicFileFragment: Fragment() {
11+
12+
lateinit var binding: FragmentMusicFileBinding
13+
14+
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
15+
binding = FragmentMusicFileBinding.inflate(inflater, container, false)
16+
17+
return binding.root
18+
}
19+
}

0 commit comments

Comments
 (0)