IT 개발/Android

[안드로이드] TabLayout과 ViewPager (Material Design)

KADOSHOLY 2020. 4. 19. 18:26
반응형

 

TabLayout과 ViewPager (Material Design)

 

 

AndroidX의 ViewPager를 이용하면 스와이프 기능으로 화면 이동을 할 수 있습니다. 

또한 TabLayout 과 결합하여 이동된 화면 위치를 직관적으로 알 수 있고, Tab을 클릭하여 화면이동을 할 수도 있습니다. 

예제에서는 아래와 같은 화면구성을 만들어 보도록 하겠습니다.

 

탭레이아웃과 뷰페이저
TabLayout + ViewPager

 

 

1. gradle 설정

 

먼저 Material Components를 사용할수 있도록 gradle에 추가해줍니다. 

현재 최신버전은 1.2.0-alpha06 이네요

dependencies {
        ...
        implementation 'com.google.android.material:material:1.2.0-alpha06'
    }

 

 

 

2. styles.xml 수정

 

ActionBar 영역을 사용하기 위해 기본 ActionBar 부분을 NoActionBar로 변경해 줍니다. 

res -> values -> styles.xml 에서 parent="" 부분을 parent="Theme.MaterialComponents.Light.NoActionBar" 로 변경합니다. 

 

- styles.xml

<resources>
  <!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
  </style>
</resources>

 

 

 

3. 화면을 구성할 Fragment 생성

   

각 화면을 나타낼 3개의 Fragment(FirstFragment, SecondFragment, ThirdFragment)를 생성해줍니다. 

여기서는 최소한의 코드로 구성된 Fragment를 만들어 주도록 하겠습니다.

(Fragment 사용법은 다음에 글을 작성하도록 하겠습니다.)

 

ex) FirstFragment예제 (SecondFragment와 ThirdFragment도 이름만 바꿔서 동일하게 만들어 주면됩니다.)

 

- FirstFragment.java 

public class FirstFragment extends Fragment {
    public FirstFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_first, container, false);
        return view;
    }
}

 

- fragment_first.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".FirstFragment">
    
    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:text="First Fragment"
        android:textSize="16dp"/>
</FrameLayout>

 

 

 

4. MainActivity 화면구성 

   

MainActivity화면 구성을 Toolbar, TabLayout, Viewpager 영역을 아래와 같이 설정해줍니다.

최상위 Layout은 CoordinatorLayout 대신에 LinearLayout 등을 사용해도 상관없습니다. 

 

- activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    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=".MainActivity">

    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@android:color/white" />

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab_layout"
            android:background="@android:color/white"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </com.google.android.material.tabs.TabLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>


 

 

 

5. ViewPagerAdapter.class 생성

   

위에 작성된 ViewPager에 하위 View를 삽입하기 위해서는  PagerAdapter와의 연결이 필요합니다. 

 

PagerAdapter는 두가지가 있는데 

1) FragmentPagerAdapter는 사용될 Fragment가 적고 그 수가 정해져있을때 사용하고

2) FragmentStatePagerAdapter는 사용될 Fragment 수가 유동적이거나 많아서 메모리 사용을 효율적으로 사용하고 싶을 때 사용합니다.

 

대신 메모리 관리를 위해서 페이지를 탐색할때 Fragment를 삭제하고 생성하게 됨으로 주의해야할 부분이 있습니다.

이때 setOffscreenPageLimit()을 사용하면 미리 로딩하여 유지할 페이지 수를 지정할 수 있습니다.

 

예제에서는 FragmentStatePagerAdapter를 사용하도록 하겠습니다.

 

- ViewPagerAdapter.java

public class ViewPagerAdapter extends FragmentStatePagerAdapter {

    private ArrayList<Fragment> fragmentList = new ArrayList<>();
    private ArrayList<String> fragmentTitle = new ArrayList<>();

    public ViewPagerAdapter(@NonNull FragmentManager fm, int behavior) {
        super(fm, behavior);
    }

    @NonNull
    @Override   // 화면의 실제 Fragment를 반환한다.
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override   // Page수
    public int getCount() {
        return fragmentList.size();
    }

    @Nullable
    @Override   // 제목
    public CharSequence getPageTitle(int position) {
        return fragmentTitle.get(position);
    }

    public void addFragment (Fragment fragment, String title) {
        fragmentList.add(fragment);
        fragmentTitle.add(title);
    }
}

 

 

 

6. Icon으로 사용할 Drawable 이미지 생성

   

res -> drawable 폴더 우클릭 -> New -> Vector Asset 에서 본인이 원하는 이미지를 세개 준비한다. 

(예제에서는 icon_1.xml, icon_2.xml, icon_3.xml 로 파일이름을 설정하였음)

 

 

 

 

7. MainActivity 작성

   

위에 만들어둔 코드 재료들을 아래와 같이 조합하도록 합니다. 

 

- MainActivity.java

public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;

    private FirstFragment firstFragment;
    private SecondFragment secondFragment;
    private ThirdFragment thirdFragment;

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

        // toolbar 설정
        toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // ViewPager 설정
        viewPager = findViewById(R.id.view_pager);
        viewPager.setOffscreenPageLimit(3); //페이지 유지 개수

        // tabLayout에 ViewPager 연결
        tabLayout = findViewById(R.id.tab_layout);
        tabLayout.setupWithViewPager(viewPager);

        // Fragment 생성
        firstFragment = new FirstFragment();
        secondFragment = new SecondFragment();
        thirdFragment = new ThirdFragment();

        // ViewPagerAdapter를 이용하여 Fragment 연결
        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager(), 0);
        viewPagerAdapter.addFragment(firstFragment, "First");
        viewPagerAdapter.addFragment(secondFragment, "Second");
        viewPagerAdapter.addFragment(thirdFragment, "Third");
        viewPager.setAdapter(viewPagerAdapter);

        // tabLayout에 아이콘 설정 부분
        tabLayout.getTabAt(0).setIcon(R.drawable.icon_1);
        tabLayout.getTabAt(1).setIcon(R.drawable.icon_2);
        tabLayout.getTabAt(2).setIcon(R.drawable.icon_3);

        // 세번째 화면에 Badge 달기
        BadgeDrawable badgeDrawable = tabLayout.getTabAt(2).getOrCreateBadge();
        badgeDrawable.setVisible(true);
        badgeDrawable.setNumber(7);
    }
}

 

 

8. 실행하기

 

실행하면 다음과 같은 화면을 보실수 있습니다.

이제부터는 각 Fragment에 본인이 원하는 컨텐츠를 채우시면 되겠습니다.

 

TabLayout 및 ViewPager 실행결과
실행결과

 

반응형