🤖 안드로이드 Android

[안드로이드/Android] TabLayout 과 ViewPager 를 이용한 탭 Tab 메뉴 화면

핑크빛연어 2021. 5. 12. 13:20

 

TabLayout 과 ViewPager 를 이용한 탭 메뉴 화면 을 구현하는 소스코드에 대해 포스팅 해 보겠습니다~

 

 

TabLayout : Tab 메뉴들을 담은 큰 틀의 레이아웃

 

ViewPager : 화면을 양옆으로 넘겨서 Page 를 바꾸는 슬라이드 동작을 할 수 있도록 도와주는 View 위젯 

 

 

 

작성한 파일 목록 입니다.

 

1. build.gradle(:app)

2. OneFragment.java / fragment_one.xml

3. TabActivity.java

4. activity_tab.xml

5. layout_tab_custom.xml

6. PagerAdapter.java

 

 

 

1. build.gradle(:app)

 

TabLayout 은 Design Support Library 에 속해있기 때문에

dependencies 에 implementation 'com.android.support:design:28.0.0' 를 추가해줍니다.

 

라이브러리를 추가할 때 모든 support 라이브러리의 버전은 같아야 하므로 저는 appcompat-v7 라이브러리와 동일한 버전인 28.0.0 버전을 사용하였습니다.

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:2.0.4'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

    implementation 'com.android.support:design:28.0.0'
}

 

 

 

2. OneFragment.java / fragment_one.xml

Fragment 는 간단하게 TextView 만 표시하는 화면으로 구성하였습니다.

 

 

 OneFragment.java

TwoFragment.java, ThreeFragment.java 도 다음과 같습니다.

public class OneFragment extends Fragment {

    private TextView tv_one;
    
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_one,container,false);
        tv_one = view.findViewById(R.id.tv_one);
        return view;
    }
}

 

 

 fragment_one.xml

fragment_two.xml, fragment_three.xml 도 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical" 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FFD9FA">

    <TextView
        android:id="@+id/tv_one"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="one"
        android:textColor="#000"
        android:textSize="60sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

 

프래그먼트 (Fragment) 의 상세설명은 이전 게시물을 확인해주세요!

eunoia3jy.tistory.com/53?category=1011678

 

[안드로이드/Android] 프래그먼트(Fragment) 생명주기

 프래그먼트 (Fragment)  - 앱 UI의 재사용 가능한 부분  - 독립적으로 존재할 수 없고 항상 액티비티(Activity) 내에 포함되어 있어야 하고  활동이나 다른 프래그먼트에서 호스팅되어야 한다.  - 자

eunoia3jy.tistory.com

 

 

 

3. TabActivity.java 

TabLayout 과 ViewPager 를 이용하여 Tab 메뉴 화면을 구현할 TabActivity 앱티비티를 생성합니다.

 

이 액티비티에서 PagerAdapter 를 통해 Fragment 와 ViewPager 를 연결해주고,

이 액티비티의 리소스에서 TayLayout 과 ViewPager 를 배치합니다.

public class TabActivity extends AppCompatActivity {
    private String TAG = TabActivity.class.getSimpleName();
    private Context context = TabActivity.this;

    private TabLayout mTabLayout;
    private ViewPager layout_viewpager;
    private PagerAdapter pagerAdapter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tab);

        mTabLayout = (TabLayout) findViewById(R.id.layout_tab);

        mTabLayout.addTab(mTabLayout.newTab().setCustomView(createCustomTabView("첫번째 탭")));
        mTabLayout.addTab(mTabLayout.newTab().setCustomView(createCustomTabView("두번째 탭")));
        mTabLayout.addTab(mTabLayout.newTab().setCustomView(createCustomTabView("세번째 탭")));

        //PagerAdapter 를 통해 TabLayout 과 ViewPager 연결
        layout_viewpager = (ViewPager) findViewById(R.id.layout_viewpager);
        pagerAdapter = new PagerAdapter(getSupportFragmentManager(), mTabLayout.getTabCount());
        layout_viewpager.setAdapter(pagerAdapter);

        layout_viewpager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(mTabLayout));

        layout_viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float v, int i1) {
                Log.d(TAG, "onPageScrolled() - position : "+position);
            }

            @Override
            public void onPageSelected(int position) {
                Log.d(TAG, "onPageSelected() - position : "+position);
            }

            @Override
            public void onPageScrollStateChanged(int position) {
                Log.d(TAG, "onPageScrollStateChanged() - position : "+position);
            }

        });

        mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabSelected() - position : "+tab.getPosition());
                layout_viewpager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabUnselected() - position : "+tab.getPosition());
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {
                Log.d(TAG, "onTabReselected() - position : "+tab.getPosition());
            }

        });

    }

    
    /* Tab 커스텀뷰 생성 */
    private View createCustomTabView(String tabNm) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View tabView = inflater.inflate(R.layout.layout_tab_custom, null);
        TextView tv_tab_nm = (TextView) tabView.findViewById(R.id.tv_tab_nm);
        tv_tab_nm.setText(tabNm);
        return tabView;
    }
    
}

 

* layout_viewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener(){...});

 - ViewPager의 페이지가 변경될 때 알려주는 리스너

 - ViewPager의 페이지가 변경 될 때 TabLayout에도 알려주도록 설정

 

 

* mTabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener(){...});

 - Tab이 선택 되었을 때 알려주는 리스너

 - onTabSelected() : 탭이 선택 되었을 때, 호출

 - onTabUnselected() : 탭이 선택되지 않았을 때, 호출

 - onTabReselected() : 탭이 다시 선택되었을 때, 호출

 

 

 

4. activity_tab.xml

TabActivity 액티비티의 레이아웃 리소스 입니다.

<?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"
    tools:context=".TabActivity"
    android:weightSum="100"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="30"
        android:background="#FAF4C0"
        android:gravity="center">
        <TextView
            android:id="@+id/tv_one"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TabActivity"
            android:textColor="#22741C"
            android:textSize="30sp" />

    </LinearLayout>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="70"
        android:background="#D4F4FA"
        android:weightSum="100"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="20" >
            <android.support.design.widget.TabLayout
                android:id="@+id/layout_tab"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                app:tabGravity="center"
                app:tabMode="fixed"
                app:tabTextColor="#000000"
                app:tabSelectedTextColor="@color/colorPrimary"
                app:tabIndicatorColor="@color/colorPrimary"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="80" >
            <android.support.v4.view.ViewPager
                android:id="@+id/layout_viewpager"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent" />
        </LinearLayout>

    </LinearLayout>

</LinearLayout>

 

 

 

5. layout_tab_custom.xml

Tab 커스텀뷰에 대한 레이아웃 리소스 입니다.

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/tv_tab_nm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#000000"
        android:text="탭이름"/>

</LinearLayout>

 

 

 

6. PagerAdapter.java

Fragment 와 ViewPager 를 연결해주는 FragmentStatePagerAdapter 를 상속한 Adapter 인 PagerAdapter 입니다.

public class PagerAdapter extends FragmentStatePagerAdapter {
    private int pageCnt;

    public PagerAdapter(FragmentManager fm, int pageCnt) {
        super(fm);
        this.pageCnt = pageCnt;
    }

    @Override
    public Fragment getItem(int position) {
    	//position 에 따라 Fragment 생성하여 반환
        switch (position) {
            case 0:
                OneFragment oneFragment = new OneFragment();
                return oneFragment;

            case 1:
                TwoFragment twoFragment = new TwoFragment();
                return twoFragment;

            case 2:
                ThreeFragment threeFragment = new ThreeFragment();
                return threeFragment;

            default:
                return null;

        }
    }

    @Override
    public int getCount() {
        return pageCnt;
    }
}

 

* getItem(int position)

 - position 에 해당하는 Fragment 반환

 

 

* getCount() 

 - page 개수 반환

 - 반환되는 수에 따라 페이지의 수가 결정된다.

 

 

 

안드로이드 결과화면

 

 

 

 

 

 

끝 🤗

 

 

 

728x90
반응형