관리 메뉴

나만을 위한 블로그

[Android] TabLayout, ViewPager, Fragment를 활용해서 화면 넘기기 구현하기 본문

Android

[Android] TabLayout, ViewPager, Fragment를 활용해서 화면 넘기기 구현하기

참깨빵위에참깨빵_ 2020. 6. 10. 23:03
728x90
반응형

이번 글에선 탭 레이아웃과 뷰페이저, 프래그먼트를 써서 좌우로 화면 넘기기 예제를 구현할 것이다.

먼저 앱 수준 gradle에다가 의존성을 하나 추가해준다.

 

implementation 'com.google.android.material:material:1.3.0-alpha01'

 

뷰페이저, 카드뷰 등의 머티리얼 디자인을 쓰기 위해 필요한 의존성이다. 위의 의존성을 입력해주면 한방에 다 쓸 수 있다.

 

그 다음으로 MainActivity의 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=".MainActivity">

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

        <com.google.android.material.tabs.TabItem
            android:id="@+id/item1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1번 탭" />

        <com.google.android.material.tabs.TabItem
            android:id="@+id/item2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2번 탭" />

        <com.google.android.material.tabs.TabItem
            android:id="@+id/item3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="3번 탭" />
        
    </com.google.android.material.tabs.TabLayout>

    <androidx.viewpager.widget.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

 

그 다음 탭 별 페이지로 설정할 프래그먼트를 만들어준다.

프래그먼트를 만들 줄 모른다면 아래 그림을 따라가면 된다. 자바 파일들이 있는 패키지를 우클릭한 다음 메뉴를 타고타고 들어가면 된다.

 

 

 

저 메뉴를 누르면 이 화면이 나온다.

 

 

Include fragament 어쩌고는 지금 쓸모없으니 체크해제한다.

이런 식으로 3개의 탭에 각각 넣어줄 FirstFragment, SecondFragment, ThirdFragment 총 3개의 프래그먼트를 만들어준다.

이름을 바꿔도 상관없다. 바꿀 경우 저 아래에 있는 코드에서 프래그먼트 이름들만 바꿔주면 된다.

 

 

java, xml 폴더에 각각 이렇게 만들어졌다면 페이지가 넘겨지는 걸 구분하기 쉽게 하기 위해 배경색을 임의로 설정해주자. 부모 레이아웃 태그에 background 속성을 넣고 색깔 이름만 써주면 된다.

 

 

다음으로 어댑터를 만들어줘야 한다. 이 어댑터는 뷰페이저에서 쓰일 어댑터인데, 자바 파일을 하나 만든 다음 이렇게 작성하면 된다.

 

 

Superclass 부분에 Fragmentpager라고만 치면 저 문장이 자동완성된다. 또한 이 상태로 OK를 누르면 FragmentPagerAdapter를 상속받은 ViewpagerAdapter 클래스가 완성된다.

완성 직후에 함수들을 implements하고 생성자를 만들어주면 이런 형태의 자바 코드가 완성된다.

참고로 생성자는 만들고 보면 삭선이 그어져 있다. 무시하고 진행한다.

 

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

public class ViewpagerAdapter extends FragmentPagerAdapter {

    public ViewpagerAdapter(@NonNull FragmentManager fm)
    {
        super(fm);
    }

    @NonNull
    @Override
    public Fragment getItem(int position)
    {
        return null;
    }

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

}

 

이 상태에서 전역 변수로 ArrayList를 추가한다. 프래그먼트를 담을 것이기 때문에 뒤에 <Fragment>를 붙여야 한다.

그 다음 ArrayList에다 이전에 만들었던 프래그먼트들을 넣어준다.

완성된 코드는 아래와 같다.

 

import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

import java.util.ArrayList;

public class ViewpagerAdapter extends FragmentPagerAdapter {

    private ArrayList<Fragment> arrayList = new ArrayList<>();

    public ViewpagerAdapter(@NonNull FragmentManager fm)
    {
        super(fm);
        arrayList.add(new FirstFragment());
        arrayList.add(new SecondFragment());
        arrayList.add(new ThirdFragment());
    }

    @NonNull
    @Override
    public Fragment getItem(int position)
    {
        return arrayList.get(position);
    }

    @Override
    public int getCount()
    {
        return arrayList.size();
    }

}

 

다음은 MainActivity로 가서 xml의 뷰페이저에 위의 어댑터를 set해줘야 한다.

 

public class MainActivity extends AppCompatActivity {

    ViewPager viewPager;
    
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        viewPager = findViewById(R.id.viewpager);
        ViewpagerAdapter adapter = new ViewpagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(adapter);
    }
}

 

그 후 탭 레이아웃의 탭들과 페이지들을 서로 연결시켜줘야 한다. 그래야 탭을 바꿀 때마다 원하는 페이지들로 휙휙 바뀌어 보이게 되기 때문이다.

만약 탭 안에 이미지를 넣을 거라면 추가된 코드를 활용하면 된다. 그게 아니라면 이미지 넣는 부분은 없애버려도 된다.

아래는 MainActivity.java의 최종 형태다.

 

public class MainActivity extends AppCompatActivity {

    ViewPager viewPager;

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

        viewPager = findViewById(R.id.viewpager);
        ViewpagerAdapter adapter = new ViewpagerAdapter(getSupportFragmentManager());
        viewPager.setAdapter(adapter);

        TabLayout tabLayout = findViewById(R.id.tab_layout);
        tabLayout.setupWithViewPager(viewPager);
        
        // 탭에 이미지 추가(이미지를 안 넣을거면 38번 줄까지는 생략해도 됨)
        ArrayList<Integer> image = new ArrayList<>();
        image.add(R.drawable.photo);
        image.add(R.drawable.person);
        image.add(R.drawable.folder);
        
        for (int i = 0; i < 3; i++)
        {
            tabLayout.getTabAt(i).setIcon(image.get(i));
        }
    }
}

 

이제 어댑터로 이동해서 ArrayList를 하나 더 만들고 여기에 탭 이름을 넣어주고, 이것이 탭 이름이 될 수 있도록 getPageTitle()을 재정의해야 한다.

아래는 ViewpagerAdapter의 최종 형태다.

 

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentPagerAdapter;

import java.util.ArrayList;

public class ViewpagerAdapter extends FragmentPagerAdapter {

    private ArrayList<Fragment> arrayList = new ArrayList<>();
    private ArrayList<String> name = new ArrayList<>();

    public ViewpagerAdapter(@NonNull FragmentManager fm)
    {
        super(fm);
        arrayList.add(new FirstFragment());
        arrayList.add(new SecondFragment());
        arrayList.add(new ThirdFragment());
        
        name.add("1번 탭");
        name.add("2번 탭");
        name.add("3번 탭");
    }

    @Nullable
    @Override
    public CharSequence getPageTitle(int position)
    {
        return name.get(position);
    }

    @NonNull
    @Override
    public Fragment getItem(int position)
    {
        return arrayList.get(position);
    }

    @Override
    public int getCount()
    {
        return arrayList.size();
    }

}

 

여기까지 하고 앱을 빌드하면 아래와 같이 작동한다.

 

 

 

추가로 화면이 바뀔 때마다 탭 아래의 청록색의 "ㅡ" 모양 바가 움직이는 걸 볼 수 있다. 이걸 탭 인디케이터라고 한다.

이것의 색깔을 바꿀 수도 있는데, MainActivity.xml에서 TabLayout 태그에 tabIndicator 속성을 추가하기만 하면 된다.

 

<com.google.android.material.tabs.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorColor="@android:color/black">

 

검은색으로 바꾼 후 앱을 빌드하면 이렇게 동작한다.

인디케이터 색만 검게 바뀌어서 화면이 잘 바뀌는 걸 볼 수 있다.

 

 

텍스트를 빼고 싶다면 탭 제목을 넣는 부분을 없애고, 이미지를 빼고 싶다면 이미지를 추가하는 부분만 없애면 된다.

반응형
Comments