Notice
Recent Posts
Link
Today
Total
07-07 13:09
관리 메뉴

dingdong coding

[ Android / Kotlin ] ViewPager, TabLayout을 이용해 메뉴 Tab 구현 ( + Custom ) 본문

🌃Android/UI

[ Android / Kotlin ] ViewPager, TabLayout을 이용해 메뉴 Tab 구현 ( + Custom )

🐶 개발개발 🐾 2022. 1. 4. 01:29

Android 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

 

 

Comments