Custom Tab 만들기
728x90
반응형

많은 메뉴를 보여줄 때에는 Navigation을 쓰지만

그렇지 않은 경우에는 Tab을 많이 사용한다.

아래는 Google material design 홈페이지에서 가져온 Sample 이미지이다.



이와 비슷한 Tab layout을 만들려고 한다.

조건은 아래와 같다.


  1. 화면 하단에 Tab을 둔다.
  2. 개별 Tab 외부로 글자가 나오지 않게 만든다.
  3. 해당 Tab별 아이콘과 타이틀 텍스트를 모두 출력한다.
  4. 아이콘과 타이틀은 수직 배열
  5. 아이콘과 타이틀은 Selected될 때 색상이 변경된다.
  6. 개별 Tab에서 Selected될 때 생기는 Line는 제거한다.

완성한 모습은 아래와 같다.



자 그럼 위처럼 만들어보자.
당연히 필요한 것은 Tab layout과 ViewPager이다.


1. Main activity layout


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/lyt_content_fullscreen"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".content.ContentActivity">
 
    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/grey"
        app:layout_constraintBottom_toTopOf="@+id/tab_content" />
 
    <android.support.design.widget.TabLayout
        android:id="@+id/tab_content"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_74"
        app:layout_constraintBottom_toBottomOf="parent"
        app:tabMode="fixed"
        app:tabGravity="fill"
        app:tabIndicatorHeight="@dimen/dp_0"/>
 
</android.support.constraint.ConstraintLayout>
cs

  • design:tabGravity
    • 탭의 정렬 방식을 선택한다.
    • fill : 너비를 모두 같게 표시
    • center : 가운데 정렬하여 표시
  • design:tabMode
    • 탭의 표시 방식을 선택
    • Fixed : 모든 탭을 한번에 표시
    • Scrollable : 일부 탭만 표시, 나머지 스크롤
Tab의 color를 변경하는 tabIndicatorColor, tabTextColor, tabSelectedTextColor 등의 옵션이 있지만
수직형 Tab을 만들기위해 Custom tab을 사용해서 위 옵션은 의미가 없다.



2. Main acitivity - Base code


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// MainActivity
 
@BindView(R.id.viewpager_content)
ViewPager viewpagerContent;
@BindView(R.id.tab_content)
TabLayout tabContent;
@BindView(R.id.lyt_content_fullscreen)
ConstraintLayout lytContentFullscreen;
 
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_content);
    ButterKnife.bind(this);
 
    // 여기 아래 3줄이 구현한 Custom Tab의 주요 부분이다.
    // 하나씩 집고 넘어가보자.
    setupViewPager(viewpagerContent);
    tabContent.setupWithViewPager(viewpagerContent);
    setupTabIcons();
}
cs



3. custom_tab.xml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/img_tab"
        android:layout_width="@dimen/dp_34"
        android:layout_height="@dimen/dp_28"
        android:layout_marginBottom="@dimen/dp_6"
        android:layout_gravity="center"
        android:scaleType="fitCenter"
        android:tint="@color/selector_click_tab"
        tools:src="@drawable/ic_tab_main_first_normal"/>
    <TextView
        android:id="@+id/txt_tab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:textIsSelectable="true"
        android:textSize="@dimen/dp_13"
        android:textColor="@color/selector_click_tab"
        tools:text="Sample text"/>
</LinearLayout>
 
cs



4. selector_click_tab.xml


1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:color="@color/cyon_a500" />
    <item android:color="@color/grey_700_" />
</selector>
cs




5. ContentViewPagerAdapter


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ContentViewPagerAdapter extends FragmentPagerAdapter {
 
    private final List<Fragment> mFragmentList = new ArrayList<>();
 
    public ContentViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }
 
    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }
 
    @Override
    public int getCount() {
        return mFragmentList.size();
    }
 
    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
    }
}
 
cs


개별 Fragment를 ViewPager에 담고

MainActivity에서 Tab과 연결을 해주기 위한 adapter이다.

getPageTitle은 쓰지 않는다.

Custom view에서 Text view로 title을 표현하기 때문이다.



6. MainActivity - setupViewPager


1
2
3
4
5
6
7
8
private void setupViewPager(ViewPager viewPager) {
    ContentViewPagerAdapter adapter = new ContentViewPagerAdapter(getSupportFragmentManager());
    adapter.addFragment(new FirstFragment(), "First");
...
    viewPager.setAdapter(adapter);
}
cs


Fragment는 알아서 만들도록 하자.

위 영상에서는 4개가 나왔다.

그러니 Fragment도 4개가 필요하다.

Fragment 코드는 가장 기본 코드로 작성하면 되기 때문에

별도로 여기에 남기진 않지만 혹시 필요한 경우에는

따로 연락주면 답하도록 하겠다.



7. MainActivity - setupTabIcons


1
2
3
4
5
6
7
8
9
10
11
12
13
14
private void setupTabIcons() {
 
    View viewFirst = getLayoutInflater().inflate(R.layout.custom_tab, null);
    ImageView imgFirst = viewFirst.findViewById(R.id.img_tab);
    TextView txtFirst = viewFirst.findViewById(R.id.txt_tab);
    imgFirst.setImageResource(R.drawable.ic_tab_main_First_normal);
    txtFirst.setText(R.string.First);
 
    ... 생략 ...
 
    tabContent.getTabAt(0).setCustomView(viewFirst);
 
    ... 생략 ...
}
cs


tab layout에 들어가는 tab이 4개라면 getTabAt 함수에는 0부터 3까지 세팅을 해줘야한다.

즉 마지막에는 

tabContent.getTabAt(3).setCustomView(***);

...가 들어가야 한다는 것이다.

viewFirst같은 것이 총 4개를 먼저 만들고 setCustomView로 Tab을 추가하게 된다.



참고한 자료



728x90
반응형