Android

[Android-Java] ViewPager와 TabLayout을 이용해 Custom 탭 만들기

기시미 2021. 3. 18. 23:31

오늘은 TabLayout ViewPager에 대해 알아보겠습니다.

 

ViewPager란?

하나의 전체 화면에서 다른 전체 화면으로 전환하는 것으로, 화면 슬라이드에 자동으로 애니메이션(스와이프)을 적용할 수 있습니다. 

 

TabLayout이란?

탭 레이아웃은 탭을 표시할 수 있는 수평 레이아웃을 제공합니다. 화면 전환을 위해 ViewPager와 함께 사용합니다.

 

이제 구현을 해보겠습니다. (Databinding 사용)

 

1. style에 tab_text를 생성해줍니다.

style.xml

<style name="TabText" parent="TextAppearance.Design.Tab">
    //폰트
    <item name="fontFamily">@font/gmarketsansbold</item>
    //텍스트사이즈
    <item name="android:textSize">12dp</item>
</style>
    

TabLayout의 텍스트 폰트와 사이즈을 설정해줍니다.

 

2. XML에 TabLayout과 ViewPager를 추가해줍니다.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.viewpager.widget.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_above="@+id/tab"/>

        <com.google.android.material.tabs.TabLayout
            android:id="@+id/tab"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_alignParentBottom="true" //탭을 아래에 두기 위해 설정
            app:tabIndicatorColor="#0070C0" //하단 움직이는 바 색상
            app:tabIndicatorGravity="top" // 하단 움직이는 바 위치 설정
            app:tabTextColor="#0070C0" //탭 텍스트 색상
            app:tabSelectedTextColor="@color/white" //선택된 탭 텍스트 색상
            app:tabBackground="@drawable/tab_background" //탭 배경
            app:tabTextAppearance="@style/TabText"//Style에서 추가한 폰트와 텍스트 사이즈 추가
            />
    </RelativeLayout>

</layout>

style.xml에서 정의한 TabText는 app:tabTextAppearance="@style/TabText"로 탭에 적용해줍니다. 또한 선택된 탭만 배경색이 변경되도록 하기 위해 drawable을 만들어 적용해주었습니다. 

 

code-hyoon.tistory.com/10

 

[Android-Java] TabLayout 배경색 다르게 설정하기

Android에서 TabLayout에서 탭했을 때 배경색을 변경하는 코드는 따로 없기 때문에 drawable을 만들어주어야 합니다. 1. 기본 배경색 drawable > tab_background_unselected.xml

code-hyoon.tistory.com

TabLayout XML attributes 정리

더보기

app : tabBackground - 탭 배경 설정

app : tabTextColors - 탭에 사용되는 텍스트 색상을 설정

app : tabSelectiedTextColors - 선택된 텍스트 색상을 설정

app : tabIndicatorColor - 움직이는 하단 바 색상 설정

app : tabIndicatorGravity - 움직이는 하단 바 위치 설정

3. ViewPager에 넣을 Fragment를 만들어 줍니다.

.java
.xml

CalendarFragment.java

public class CalendarFragment extends Fragment {

    public CalendarFragment () {}

    public static CalendarFragment newInstance() {
        CalendarFragment calendarFragment= new CalendarFragment();
        Bundle bundle = new Bundle();
        return calendarFragment;
    }

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

4. Fragment와 ViewPager, TabLayout을 연결해줄 FragmentPagerAdapter를 만들어줍니다.

FragmentAdapter.java

public class FragmentAdapter extends FragmentPagerAdapter {

    public static int PAGE_POSITION = 4;

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

    @NonNull
    @Override
    public Fragment getItem(int position) {
        switch (position){
            //1번째 탭
            case 0:
                return CalendarFragment.newInstance();
            //2번째 탭    
            case 1:
                return ExerciseReportFragment.newInstance();
            //3번째 탭
            case 2:
                return ExerciseRankFragment.newInstance();
            //4번째 탭
            case 3:
                return MyPageFragment.newInstance();
            default:
                return null;
        }
    }

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

5. MainActivity에 탭레이아웃을 연결해줍니다.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private TabLayout tabLayout;
    private ViewPager viewPager;
    private ArrayList<String> tabNames = new ArrayList<>();
    private ActivityMainBinding binding;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding= DataBindingUtil.setContentView(this, R.layout.activity_main);

        //ArrayList에 Tab 이름 저장
        loadTabName();
        //TabLayout 설정
        setTabLayout();
        //ViewPager 연결
        setViewPager();

    }
    //ArrayList에 차례대로 저장함
    private void loadTabName(){
        tabNames.add("운동일지");
        tabNames.add("운동 리포트");
        tabNames.add("운동 순위");
        tabNames.add("마이페이지");
    }
    @TargetApi(Build.VERSION_CODES.N)
    private void setTabLayout(){
    
        tabLayout = binding.tab;//== (tabLayout = findViewById(R.id.tab); 
        //ArrayList에 저장된 순서대로 Tab 이름을 지정해줌
        tabNames.stream().forEach(name ->tabLayout.addTab(tabLayout.newTab().setText(name)));
        
        //Tab 아이콘 설정
        tabLayout.getTabAt(0).setIcon(R.drawable.ic_calendar);
        tabLayout.getTabAt(1).setIcon(R.drawable.ic_chart);
        tabLayout.getTabAt(2).setIcon(R.drawable.ic_trophy);
        tabLayout.getTabAt(3).setIcon(R.drawable.ic_mypage);
	
        //Tab 아이콘 색상 초기화 (맨 처음 화면일때의 Tab 아이콘 색상 설정)
        tabLayout.getTabAt(0).getIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
        tabLayout.getTabAt(1).getIcon().setColorFilter(Color.parseColor("#0070C0"), PorterDuff.Mode.SRC_IN);
        tabLayout.getTabAt(2).getIcon().setColorFilter(Color.parseColor("#0070C0"), PorterDuff.Mode.SRC_IN);
        tabLayout.getTabAt(3).getIcon().setColorFilter(Color.parseColor("#0070C0"), PorterDuff.Mode.SRC_IN);
    }
private void setViewPager() {

        //어댑터 초기화
        FragmentAdapter adapter = new FragmentAdapter(getSupportFragmentManager(), PAGE_POSITION);
        viewPager = binding.viewPager;//== (viewPager = findViewById(R.id.viewPager);
        //어댑터 연결
        viewPager.setAdapter(adapter);
        //페이지 리스너 (viewPager와 TabLayout의 페이지를 맞춰줌)
        viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        //탭 선택 리스너 (탭 행동 설정)
        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
            //선택된 탭일 때
            @Override
            public void onTabSelected(TabLayout.Tab tab) {
                //선택된 탭과 연결된 fragment를 가져옴
                viewPager.setCurrentItem(tab.getPosition());
                //아이콘 색상을 흰색으로 설정
                tab.getIcon().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_IN);
            }
            //선택되지 않은 탭일 때
            @Override
            public void onTabUnselected(TabLayout.Tab tab) {
            	//아이콘 색상을 #0070C0 으로 설정
                tab.getIcon().setColorFilter(Color.parseColor("#0070C0"), PorterDuff.Mode.SRC_IN);
            }

            @Override
            public void onTabReselected(TabLayout.Tab tab) {

            }
        });
    }

 


결과 화면