Skip to content

Commit 4e0ba48

Browse files
committed
Feat: 3주차 미션 HomeFragment에 ViewPager와 자동 슬라이드, Indicator 추가
1 parent 4710b99 commit 4e0ba48

File tree

9 files changed

+159
-40
lines changed

9 files changed

+159
-40
lines changed

Heather/FLOClone/app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ dependencies {
4545
implementation(libs.material)
4646
implementation(libs.androidx.activity)
4747
implementation(libs.androidx.constraintlayout)
48+
implementation("me.relex:circleindicator:2.1.6")
4849
testImplementation(libs.junit)
4950
androidTestImplementation(libs.androidx.junit)
5051
androidTestImplementation(libs.androidx.espresso.core)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class BannerVPAdapter(fragment: Fragment) :FragmentStateAdapter(fragment) {
1111

1212
override fun createFragment(position: Int): Fragment = fragmentlist[position]
1313

14-
fun addFragment(fragment: Fragment){
14+
fun addFragment(fragment: Fragment) {
1515
fragmentlist.add(fragment)
1616
notifyItemInserted(fragmentlist.size-1)
1717
}

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ import android.view.View
77
import android.view.ViewGroup
88
import androidx.viewpager2.widget.ViewPager2
99
import com.example.floclone.databinding.FragmentHomeBinding
10+
import me.relex.circleindicator.CircleIndicator3
11+
import android.os.Handler
12+
import android.os.Looper
1013

1114
class HomeFragment : Fragment() {
1215

1316
lateinit var binding: FragmentHomeBinding
17+
lateinit var handler: Handler
18+
lateinit var runnable: Runnable
1419

1520
override fun onCreateView(
1621
inflater: LayoutInflater,
@@ -24,12 +29,38 @@ class HomeFragment : Fragment() {
2429
.replace(R.id.main_frm, AlbumFragment()).commitAllowingStateLoss()
2530
}
2631

32+
// ViewPager 설정
2733
val bannerAdapter = BannerVPAdapter(this)
2834
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp))
2935
bannerAdapter.addFragment(BannerFragment(R.drawable.img_home_viewpager_exp2))
3036
binding.homeBannerVp.adapter = bannerAdapter
3137
binding.homeBannerVp.orientation = ViewPager2.ORIENTATION_HORIZONTAL
3238

39+
val panelAdpater = PanelVPAdapter(this)
40+
panelAdpater.addFragment(PanelFragment(R.drawable.img_first_album_default))
41+
panelAdpater.addFragment(PanelFragment(R.drawable.img_first_album_default))
42+
binding.homePanelBackgroundVp.adapter = panelAdpater
43+
binding.homePanelBackgroundVp.orientation = ViewPager2.ORIENTATION_HORIZONTAL
44+
45+
// Indicator 설정
46+
val indicator: CircleIndicator3 = binding.homePanelIndicator
47+
indicator.setViewPager(binding.homeBannerVp)
48+
49+
// 자동 슬라이드 구현
50+
handler = Handler(Looper.getMainLooper())
51+
runnable = object : Runnable {
52+
override fun run() {
53+
if (binding.homePanelBackgroundVp.currentItem == bannerAdapter.itemCount - 1) {
54+
binding.homePanelBackgroundVp.currentItem = 0
55+
} else {
56+
binding.homePanelBackgroundVp.currentItem = binding.homePanelBackgroundVp.currentItem + 1
57+
}
58+
handler.postDelayed(this, 3000) // 3초마다 슬라이드
59+
}
60+
}
61+
handler.postDelayed(runnable, 3000) // 최초 실행
62+
63+
3364
return binding.root
3465
}
3566

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
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.FragmentPanelBinding
9+
10+
class PanelFragment(val imgRes : Int) : Fragment() {
11+
lateinit var binding : FragmentPanelBinding
12+
13+
override fun onCreate(savedInstanceState: Bundle?) {
14+
super.onCreate(savedInstanceState)
15+
16+
}
17+
18+
override fun onCreateView(
19+
inflater: LayoutInflater, container: ViewGroup?,
20+
savedInstanceState: Bundle?
21+
): View? {
22+
binding = FragmentPanelBinding.inflate(inflater, container, false)
23+
binding.pannelImageIv.setImageResource(imgRes)
24+
return binding.root
25+
}
26+
}
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 PanelVPAdapter(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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<shape xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:shape="oval">
4+
<solid android:color="@color/select_color"/>
5+
<size android:width="5dp"
6+
android:height="5dp"/>
7+
</shape>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<shape xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:shape="oval">
4+
<solid android:color="@color/gray_color"/>
5+
<size android:width="5dp"
6+
android:height="5dp"/>
7+
</shape>

Heather/FLOClone/app/src/main/res/layout/fragment_home.xml

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,49 @@
1010
android:layout_width="match_parent"
1111
android:layout_height="wrap_content">
1212

13-
<ImageView
14-
android:id="@+id/home_pannel_background_iv"
13+
<androidx.viewpager2.widget.ViewPager2
14+
android:id="@+id/home_panel_background_vp"
1515
android:layout_width="match_parent"
1616
android:layout_height="430dp"
1717
android:scaleType="centerCrop"
18-
android:src="@drawable/img_first_album_default"
1918
app:layout_constraintEnd_toEndOf="parent"
19+
app:layout_constraintHorizontal_bias="0.0"
2020
app:layout_constraintStart_toStartOf="parent"
21-
app:layout_constraintTop_toTopOf="parent" />
21+
app:layout_constraintTop_toTopOf="parent"/>
22+
23+
<me.relex.circleindicator.CircleIndicator3
24+
android:id="@+id/home_panel_indicator"
25+
android:layout_width="wrap_content"
26+
android:layout_height="15dp"
27+
android:layout_marginTop="5dp"
28+
app:layout_constraintTop_toBottomOf="@id/home_panel_background_vp"
29+
app:layout_constraintEnd_toEndOf="@id/home_panel_background_vp"
30+
app:layout_constraintStart_toStartOf="@id/home_panel_background_vp"
31+
app:ci_drawable="@drawable/indicator_selected_circle"
32+
app:ci_drawable_unselected="@drawable/indicator_unselected_circle"/>
2233

2334
<ImageView
24-
android:id="@+id/home_pannel_btn_nugu_iv"
35+
android:id="@+id/home_panel_btn_nugu_iv"
2536
android:layout_width="35dp"
2637
android:layout_height="35dp"
2738
android:layout_marginTop="20dp"
2839
android:layout_marginEnd="15dp"
2940
android:src="@drawable/btn_main_mike"
30-
app:layout_constraintEnd_toStartOf="@id/home_pannel_btn_ticket_iv"
41+
app:layout_constraintEnd_toStartOf="@id/home_panel_btn_ticket_iv"
3142
app:layout_constraintTop_toTopOf="parent" />
3243

3344
<ImageView
34-
android:id="@+id/home_pannel_btn_ticket_iv"
45+
android:id="@+id/home_panel_btn_ticket_iv"
3546
android:layout_width="35dp"
3647
android:layout_height="35dp"
3748
android:layout_marginTop="20dp"
3849
android:layout_marginEnd="15dp"
3950
android:src="@drawable/btn_main_ticket"
40-
app:layout_constraintEnd_toStartOf="@id/home_pannel_btn_setting_iv"
51+
app:layout_constraintEnd_toStartOf="@id/home_panel_btn_setting_iv"
4152
app:layout_constraintTop_toTopOf="parent" />
4253

4354
<ImageView
44-
android:id="@+id/home_pannel_btn_setting_iv"
55+
android:id="@+id/home_panel_btn_setting_iv"
4556
android:layout_width="35dp"
4657
android:layout_height="35dp"
4758
android:layout_marginTop="20dp"
@@ -51,7 +62,7 @@
5162
app:layout_constraintTop_toTopOf="parent" />
5263

5364
<TextView
54-
android:id="@+id/home_pannel_title_tv"
65+
android:id="@+id/home_panel_title_tv"
5566
android:layout_width="wrap_content"
5667
android:layout_height="wrap_content"
5768
android:layout_marginStart="20dp"
@@ -61,98 +72,98 @@
6172
android:textSize="28sp"
6273
android:textStyle="bold"
6374
app:layout_constraintStart_toStartOf="parent"
64-
app:layout_constraintTop_toBottomOf="@id/home_pannel_btn_nugu_iv" />
75+
app:layout_constraintTop_toBottomOf="@id/home_panel_btn_nugu_iv" />
6576

6677
<ImageView
67-
android:id="@+id/home_pannel_btn_play_iv"
78+
android:id="@+id/home_panel_btn_play_iv"
6879
android:layout_width="60dp"
6980
android:layout_height="60dp"
7081
android:layout_marginEnd="20dp"
7182
android:src="@drawable/btn_panel_play_large"
7283
app:layout_constraintEnd_toEndOf="parent"
73-
app:layout_constraintTop_toBottomOf="@id/home_pannel_title_tv" />
84+
app:layout_constraintTop_toBottomOf="@id/home_panel_title_tv" />
7485

7586
<TextView
76-
android:id="@+id/home_pannel_album_info_01_tv"
87+
android:id="@+id/home_panel_album_info_01_tv"
7788
android:layout_width="wrap_content"
7889
android:layout_height="wrap_content"
7990
android:layout_marginStart="20dp"
8091
android:layout_marginBottom="12dp"
8192
android:text="총 15곡 2019.11.11"
8293
android:textColor="@color/white"
8394
android:textSize="12sp"
84-
app:layout_constraintBottom_toTopOf="@id/home_pannel_album_img_01_iv"
95+
app:layout_constraintBottom_toTopOf="@id/home_panel_album_img_01_iv"
8596
app:layout_constraintStart_toStartOf="parent" />
8697

8798

8899
<ImageView
89-
android:id="@+id/home_pannel_album_img_01_iv"
100+
android:id="@+id/home_panel_album_img_01_iv"
90101
android:layout_width="40dp"
91102
android:layout_height="40dp"
92103
android:layout_marginStart="20dp"
93104
android:layout_marginBottom="30dp"
94105
android:src="@drawable/img_album_exp"
95-
app:layout_constraintBottom_toTopOf="@id/home_pannel_album_img_02_iv"
106+
app:layout_constraintBottom_toTopOf="@id/home_panel_album_img_02_iv"
96107
app:layout_constraintStart_toStartOf="parent" />
97108

98109
<TextView
99-
android:id="@+id/home_pannel_album_title_01_tv"
110+
android:id="@+id/home_panel_album_title_01_tv"
100111
android:layout_width="wrap_content"
101112
android:layout_height="wrap_content"
102113
android:layout_marginStart="15dp"
103114
android:text="잠이 안온다"
104115
android:textColor="@color/white"
105116
android:textStyle="bold"
106-
app:layout_constraintBottom_toTopOf="@id/home_pannel_album_singer_02_tv"
107-
app:layout_constraintStart_toEndOf="@id/home_pannel_album_img_01_iv"
108-
app:layout_constraintTop_toTopOf="@id/home_pannel_album_img_01_iv" />
117+
app:layout_constraintBottom_toTopOf="@id/home_panel_album_singer_02_tv"
118+
app:layout_constraintStart_toEndOf="@id/home_panel_album_img_01_iv"
119+
app:layout_constraintTop_toTopOf="@id/home_panel_album_img_01_iv" />
109120

110121
<TextView
111-
android:id="@+id/home_pannel_album_singer_02_tv"
122+
android:id="@+id/home_panel_album_singer_02_tv"
112123
android:layout_width="wrap_content"
113124
android:layout_height="wrap_content"
114125
android:layout_marginStart="15dp"
115126
android:text="젠(zen)"
116127
android:textColor="@color/white"
117128
android:textStyle="bold"
118-
app:layout_constraintBottom_toBottomOf="@id/home_pannel_album_img_01_iv"
119-
app:layout_constraintStart_toEndOf="@id/home_pannel_album_img_01_iv"
120-
app:layout_constraintTop_toBottomOf="@id/home_pannel_album_title_01_tv" />
129+
app:layout_constraintBottom_toBottomOf="@id/home_panel_album_img_01_iv"
130+
app:layout_constraintStart_toEndOf="@id/home_panel_album_img_01_iv"
131+
app:layout_constraintTop_toBottomOf="@id/home_panel_album_title_01_tv" />
121132

122133

123134
<ImageView
124-
android:id="@+id/home_pannel_album_img_02_iv"
135+
android:id="@+id/home_panel_album_img_02_iv"
125136
android:layout_width="40dp"
126137
android:layout_height="40dp"
127138
android:layout_marginStart="20dp"
128139
android:layout_marginBottom="30dp"
129140
android:src="@drawable/img_album_exp"
130-
app:layout_constraintBottom_toBottomOf="@id/home_pannel_background_iv"
141+
app:layout_constraintBottom_toBottomOf="@id/home_panel_background_vp"
131142
app:layout_constraintStart_toStartOf="parent" />
132143

133144
<TextView
134-
android:id="@+id/home_pannel_album_title_03_tv"
145+
android:id="@+id/home_panel_album_title_03_tv"
135146
android:layout_width="wrap_content"
136147
android:layout_height="wrap_content"
137148
android:layout_marginStart="15dp"
138149
android:text="잠이 안온다"
139150
android:textColor="@color/white"
140151
android:textStyle="bold"
141-
app:layout_constraintBottom_toTopOf="@id/home_pannel_album_singer_04_tv"
142-
app:layout_constraintStart_toEndOf="@id/home_pannel_album_img_02_iv"
143-
app:layout_constraintTop_toTopOf="@id/home_pannel_album_img_02_iv" />
152+
app:layout_constraintBottom_toTopOf="@id/home_panel_album_singer_04_tv"
153+
app:layout_constraintStart_toEndOf="@id/home_panel_album_img_02_iv"
154+
app:layout_constraintTop_toTopOf="@id/home_panel_album_img_02_iv" />
144155

145156
<TextView
146-
android:id="@+id/home_pannel_album_singer_04_tv"
157+
android:id="@+id/home_panel_album_singer_04_tv"
147158
android:layout_width="wrap_content"
148159
android:layout_height="wrap_content"
149160
android:layout_marginStart="15dp"
150161
android:text="젠(zen)"
151162
android:textColor="@color/white"
152163
android:textStyle="bold"
153-
app:layout_constraintBottom_toBottomOf="@id/home_pannel_album_img_02_iv"
154-
app:layout_constraintStart_toEndOf="@id/home_pannel_album_img_02_iv"
155-
app:layout_constraintTop_toBottomOf="@id/home_pannel_album_title_03_tv" />
164+
app:layout_constraintBottom_toBottomOf="@id/home_panel_album_img_02_iv"
165+
app:layout_constraintStart_toEndOf="@id/home_panel_album_img_02_iv"
166+
app:layout_constraintTop_toBottomOf="@id/home_panel_album_title_03_tv" />
156167

157168
<TextView
158169
android:id="@+id/home_today_music_title_tv"
@@ -166,7 +177,7 @@
166177
android:textSize="18sp"
167178
android:textStyle="bold"
168179
app:layout_constraintStart_toStartOf="parent"
169-
app:layout_constraintTop_toBottomOf="@id/home_pannel_background_iv" />
180+
app:layout_constraintTop_toBottomOf="@id/home_panel_background_vp" />
170181

171182
<ImageView
172183
android:id="@+id/home_today_music_title_btn_iv"
@@ -189,7 +200,7 @@
189200
android:textColor="#3F3FFF"
190201
android:textSize="16sp"
191202
app:layout_constraintEnd_toStartOf="@id/home_today_music_domestic_tv"
192-
app:layout_constraintTop_toBottomOf="@id/home_pannel_background_iv" />
203+
app:layout_constraintTop_toBottomOf="@id/home_panel_background_vp" />
193204

194205
<TextView
195206
android:id="@+id/home_today_music_domestic_tv"
@@ -200,7 +211,7 @@
200211
android:text="국내"
201212
android:textSize="16sp"
202213
app:layout_constraintEnd_toStartOf="@id/home_today_music_oversea_tv"
203-
app:layout_constraintTop_toBottomOf="@id/home_pannel_background_iv" />
214+
app:layout_constraintTop_toBottomOf="@id/home_panel_background_vp" />
204215

205216
<TextView
206217
android:id="@+id/home_today_music_oversea_tv"
@@ -211,7 +222,7 @@
211222
android:text="해외"
212223
android:textSize="16sp"
213224
app:layout_constraintEnd_toEndOf="parent"
214-
app:layout_constraintTop_toBottomOf="@id/home_pannel_background_iv" />
225+
app:layout_constraintTop_toBottomOf="@id/home_panel_background_vp" />
215226

216227
<HorizontalScrollView
217228
android:id="@+id/home_today_music_oversea_hs"
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:layout_width="match_parent"
4+
android:layout_height="wrap_content"
5+
xmlns:app="http://schemas.android.com/apk/res-auto">
6+
7+
<ImageView
8+
android:id="@+id/pannel_image_iv"
9+
android:layout_width="match_parent"
10+
android:layout_height="430dp"
11+
android:scaleType="fitXY"
12+
android:src="@drawable/img_first_album_default"
13+
app:layout_constraintTop_toTopOf="parent"
14+
app:layout_constraintBottom_toBottomOf="parent"
15+
app:layout_constraintStart_toStartOf="parent"
16+
app:layout_constraintEnd_toEndOf="parent"/>
17+
18+
</androidx.constraintlayout.widget.ConstraintLayout>

0 commit comments

Comments
 (0)