일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 현대 IT&E
- 코드업
- tcp
- Dialog
- 2024-08-20
- di
- 채용확정형
- url
- Factory Method Pattern
- http method
- reflection
- swagger
- datepicker
- URN
- menutab
- uri
- fontstyle
- AndroidStudio
- IOC
- FACTORY
- 어노테이션
- udp
- OpenAPI
- 기초100제
- 2024-08-21
- Kotlin
- 객체지향프로그래밍
- OOP
- Python
- Android Studio
dingdong coding
[ Android / Kotlin ] ViewPager, TabLayout을 이용해 메뉴 Tab 구현 ( + Custom ) 본문
[ Android / Kotlin ] ViewPager, TabLayout을 이용해 메뉴 Tab 구현 ( + Custom )
🐶 개발개발 🐾 2022. 1. 4. 01:29Android project에서 ViewPager, TabLayout, Fragment를 이용해 메뉴Tab을 구현하겠습니다.
HomeActivity.kt : 먼저 메뉴Tab을 구현할 Activity를 만들어 줍니다.
class HomeAvtivity : AppCompatActivity() {
// 저는 Empty Activity로 생성했습니다.
}
onCreate Method를 override 해줍니다.
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home_activity)
}
}
그리고 생성된 activity_home_activity.xml 로 이동해보겠습니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".HomeActivity">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:fillViewport="true">
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</ScrollView>
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_gravity="bottom"
android:gravity="center"
/>
</LinearLayout>
ViewPager가 포함된 레이아웃을 만들기 위해 위와 같이 ViewPager와 TabLayout을 구현했습니다.
다음으로 ViewPager에 표시될 Fragment와 xml을 생성해주겠습니다.
( HomeActivity와 같은 패키지에 생성했습니다. )
GrapFragment.kt
class GrapFragment: Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.grap_fragment, container, false)
//layout > grap_fragment.xml view 사용
}
}
layout > grap_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="grap"
android:textSize="30dp"
/>
</LinearLayout>
4개의 메뉴Tab을 구현하기 위해 위와 같은 형식으로 3개를 더 생성해줍니다.
이제 메뉴 텝을 구현하기 위한 준비과정을 마쳤습니다.
다시 HomeActivity.kt로 돌아와 Fragment를 연결하기 위한 Adapter Class를 하나 생성해줍니다.
class HomePagerAdapter(
fragmentManager: FragmentManager,
val tabCount: Int
): FragmentPagerAdapter(fragmentManager){
override fun getCount(): Int {
return tabCount
}
override fun getItem(position: Int): Fragment {
when (position){
0->{ // 첫번째 Tab
return GrapFragment() // 생성한 Fragment 연결
}
1->{ // 두번째 Tab
return ManageFragment()
}
2->{ // 세번째 Tab
return HomeFragment()
}
3->{ // 네번째 Tab
return MyFragment()
}
else->{
return HomeFragment()
}
}
}
}
+ FragmentPagerAdapter를 사용하니
'FragmentPagerAdapter' is deprecated. Deprecated in Java 메세지가 뜨는데 ViewPager에서 업데이트가 되었나 봅니다.
https://stackoverflow.com/questions/56778106/fragmentpageradapter-deprecated
FragmentPagerAdapter deprecated
Since API 27 FragmentPagerAdapter is deprecated. What's the best alternative to use for this? In my case, I understand something like super(fragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) ...
stackoverflow.com
다시 HomeActivity class로 돌아와 custom한 Tab을 Add 해줍니다. 그리고 view와 menu tab을 연결해줍니다.
( Custom은 밑에서 다루겠습니다.)
class HomeActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home_activity)
// activity_home_activity.xml 에서 생성한 TabLayout id
val tab_layout : TabLayout = findViewById(R.id.tab_layout)
// TabLayout을 custom 하기 위해 layout > customtab.xml을 생성했습니다.
// drawable > grap_tab.png Menutab Icon Img
// Tab을 생성하기 위해 custom한 tab icon을 add 해줍니다.
val grap: View = layoutInflater.inflate(R.layout.customtab, null)
grap.findViewById<ImageView>(R.id.icon).setBackgroundResource(R.drawable.grap_tab)
tab_layout.addTab(tab_layout.newTab().setCustomView(grap))
val list: View = layoutInflater.inflate(R.layout.customtab, null)
list.findViewById<ImageView>(R.id.icon).setBackgroundResource(R.drawable.list_tab)
tab_layout.addTab(tab_layout.newTab().setCustomView(list))
val home: View = layoutInflater.inflate(R.layout.customtab, null)
home.findViewById<ImageView>(R.id.icon).setBackgroundResource(R.drawable.home_tab)
tab_layout.addTab(tab_layout.newTab().setCustomView(home))
val my: View = layoutInflater.inflate(R.layout.customtab, null)
my.findViewById<ImageView>(R.id.icon).setBackgroundResource(R.drawable.my_tab)
tab_layout.addTab(tab_layout.newTab().setCustomView(my))
// activity_home_activity.xml 에서 생성한 ViewPager id
val view_pager : ViewPager = findViewById(R.id.view_pager)
// Tab 4개
val pagerAdapter = HomePagerAdapter(supportFragmentManager, 4)
view_pager.adapter = pagerAdapter
tab_layout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener{
override fun onTabSelected(tab: TabLayout.Tab?) {
view_pager.currentItem = tab!!.position
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
// view와 menu tab을 연결하기 위해 -> view가 바뀔 때 menu tab도 함께 바뀜
view_pager.addOnPageChangeListener(TabLayout.TabLayoutOnPageChangeListener(tab_layout))
}
}
여기까지 했다면 메뉴 Tab 구현은 완료됐을 것입니다.
이제 잠시 넘어갔던 TabLayout Custom을 해보겠습니다.
저는 Icon만을 사용했기에 Icon과 tabIndicator에 대해서만 Custom했습니다.
activity_home_activity.xml
<com.google.android.material.tabs.TabLayout
android:background="@drawable/border"
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_gravity="bottom"
android:gravity="center"
app:tabIndicatorHeight="0dp"
android:scaleType="fitCenter"
app:tabRippleColor="@android:color/transparent"
/>
메뉴Tab top border
drawable > border.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#969696" />
</shape>
</item>
<item android:top="1dp" >
<shape android:shape="rectangle">
<solid android:color="#ffffff" />
</shape>
</item>
</layer-list>
layout > customtab.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<!--메뉴 텝 아이콘 커스텀-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/icon"
android:scaleType="fitCenter"
android:backgroundTint="@drawable/color_selector"
android:layout_gravity="center_horizontal"
/>
</LinearLayout>
icon select 시 color change를 위한
drawable > color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/dark_gray" android:state_selected="true"/>
<item android:color="@color/light_gray"/>
</selector>
완성된 화면
P.S : 부족한 부분은 계속해서 수정하겠습니다. 🥰
참조
https://recipes4dev.tistory.com/148?category=783067
안드로이드 뷰페이저 기본 사용법. (Android ViewPager)
1. 화면에 표시될 컨텐츠를 전환하는 방법. 안드로이드를 탑재한 스마트폰이 처음 만들어지던 시기에는, 앱 화면을 구성할 때 UI(User Interface)의 "직관성"이 가장 중요한 이슈 중 하나였습니다. 사
recipes4dev.tistory.com
https://developer.android.com/training/animation/screen-slide?hl=ko
ViewPager로 프래그먼트 간 슬라이드 | Android 개발자 | Android Developers
ViewPager로 프래그먼트 간 슬라이드 화면 슬라이드는 하나의 전체 화면에서 다른 전체 화면으로 전환하는 것으로, 설정 마법사 또는 슬라이드쇼와 같은 UI에서 일반적으로 사용됩니다. 이 과정에
developer.android.com
'🌃Android > UI' 카테고리의 다른 글
[ Android / Kotlin ] Custom Dialog 만들기 (0) | 2022.01.16 |
---|---|
[ Android / Kotlin ] DatePicker 활용하기 ( +Custom) (0) | 2022.01.10 |