오늘은 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을 만들어 적용해주었습니다.
TabLayout XML attributes 정리
더보기
app : tabBackground - 탭 배경 설정
app : tabTextColors - 탭에 사용되는 텍스트 색상을 설정
app : tabSelectiedTextColors - 선택된 텍스트 색상을 설정
app : tabIndicatorColor - 움직이는 하단 바 색상 설정
app : tabIndicatorGravity - 움직이는 하단 바 위치 설정
3. ViewPager에 넣을 Fragment를 만들어 줍니다.
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) {
}
});
}
결과 화면
'Android' 카테고리의 다른 글
[Android-java] ScrollView 사용법 및 에러 해결 (0) | 2021.08.26 |
---|---|
[Android-java] 서버 통신 시 SocketTimeoutException 에러 (2) | 2021.08.25 |
[Android-Java] Spinner를 이용해 드롭다운 리스트 구현하기 (0) | 2021.08.25 |
[Android-Java] TabLayout 배경색 다르게 설정하기 (1) | 2021.03.18 |
[Android-java] Retrofit2 적용하기 / 로그인 구현 (3) | 2021.03.12 |