본문 바로가기

유저 인터페이스/뷰(View)

#08. TabView 및 FrameLayout을 이용한 탭 이용하기

이번 강좌에서는 화면 구성에 많이 사용되는 TabView 에 대해서 알아보도록 하겠습니다.
TabView는 윈도우 컨트롤의 Tab 컨트롤과 동일하게 생겼으며, 안드로이드 마켓에서도 사용되는 View이며, 이번에 회색님께서 하신 프로젝트 결과물도 이 TabView를 이용하였습니다.



TabView에 관한 것은 저도 오늘 처음 배운 것이라, 자세한 내용(...)은 다루지 않고, TabView를 생성하고 띄우는 방법까지만 다루도록 하겠습니다. 언제까지나, 이론보다 더 중요한 것은 실습해보고, 직접 결과를 보는 것이니까요.(응?)

TabView를 사용하기 위해서는 몇 가지 조건이 필요한데, 요약하면 다음과 같습니다.

1. Google map을 사용할 때 처럼, 액티비티가 Activity를 상속하지 않고 TabActivity를 상속해야 함
2. 레아아웃 골격 구성에 FrameLayout을 사용해야 함

이번 예제에 사용된 레이아웃의 구성은 다음과 같습니다.


FrameLayout은 TabView처럼 탭의 선택에 따라 여러 개의 View를 보여주어야 할 때 사용되며, FrameLayout 내부에 표시될 View 혹은 Layout이 책처럼 차곡차곡 들어가 있는 형태입니다.

[main.xml]
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent">
          
        <LinearLayout android:layout_height="wrap_content" 
         android:layout_width="fill_parent" 
         android:id="@+id/view1" 
         android:orientation="vertical">
         
         <EditText android:id="@+id/EditText01" 
          android:layout_height="wrap_content" 
          android:hint="첫번째 화면입니다." 
          android:layout_width="fill_parent"></EditText>   

<Button android:id="@+id/Button01" 
    android:layout_height="wrap_content"
    android:layout_width="fill_parent" 
    android:text="버튼!"></Button>
  </LinearLayout>
  
  <LinearLayout android:layout_height="wrap_content" 
   android:layout_width="fill_parent" 
   android:id="@+id/view2">
   
   <ImageView android:id="@+id/ImageView01" 
   android:layout_height="wrap_content" 
   android:layout_width="fill_parent" 
   android:src="@drawable/camera"></ImageView>
  </LinearLayout>
  </FrameLayout>
    </LinearLayout>
</TabHost>



예제에서는 탭 2개를 가지도록 구현하였으며, 하나의 View는 EditText와 버튼을 표시하는 View, 나머지 하나는 ImageView를 표시하도록 하였습니다. 이 예제를 따라하려면 미리 프로젝트의 /res/drawable 폴더에 적절한 그림 파일을 넣어야 하겠죠?
그림 파일의 이름이 그대로 id로 사용되니, 영어로 파일명을 지정해주셔야 합니다. (소문자만 가능)

지금까지 해온 레이아웃 구성과는 다소 다른 모습을 보이는데요, 다음 이미지에 정리해 두었습니다.

그럼, 소스를 한번 볼까요?

[TVExample.java]

package com.androidhuman.TabView;

package com.androidhuman.TabView;

import android.app.TabActivity; // TabActivity
import android.os.Bundle;
import android.widget.TabHost;

public class TVExample extends TabActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        TabHost mTabHost = getTabHost();
        
        mTabHost.addTab(mTabHost.newTabSpec("tab_test1")
        		.setIndicator("위젯")
        		.setContent(R.id.view1)
        		);
        mTabHost.addTab(mTabHost.newTabSpec("tab_test2")
        		.setIndicator("이미지뷰")
        		.setContent(R.id.view2)
        		);
                
        //mTabHost.setCurrentTab(0);
    }

}

소스를 보시면 아까 말씀드렸던 것처럼 TabActivity를 상속하는 것을 볼 수 있습니다.
코드상에서 16번째 줄을 보시면 getTabHost()메소드를 통해 TabHost를 받아오는 것을 확인할 수 있습니다.
이는 실질적으로 우리가 Tab에 내용을 추가하는 등의 작업을 위해 필요합니다.

바로 아래로 내려가보시면, 탭에 탭 항목을 추가하는 것을 확인할 수 있습니다.
탭 항목의 addTab()메소드를 사용합니다.

addTab()메소드 안에서 netTabSpec()메소드를 이용하여 실질적인 Tab 항목별로 설정을 해 주는 것을 확인할 수 있습니다.

public TabHost.TabSpec newTabSpec (String tag)

Get a new TabHost.TabSpec associated with this tab host.


SDK 문서에 나와 있는 내용입니다. 말 그대로 각 탭 항목의 설정 등을 반환하도록 되어있습니다. newTabSpec을 호출할 때, tag는 자세히는 모르겠지만, 아마 나중에 탭을 호출할 때 쓰이는 문자열인듯 합니다.

이어서, setIndicator() 메소드에서는 탭의 이름을 추가해주고 있습니다. 여기에서는 단순히 이름만 추가해 주었는데, 다음과 같이 사용하면 아이콘도 지정 가능합니다.

setIndicator("위젯", getResources().getDrawable(R.drawable.icon))

setContent()메소드에서는 각각의 탭에 표시할 View를 지정해줍니다. 지금까지는 보통 LinearLayout 등 레이아웃 자체에는 id를 지정하지 않았는데, 이번 예제에서는 id를 통해 각각의 View, 혹은 Layout을 불러오므로 ID지정이 필수입니다.

마지막으로, 주석처리된 부분은 보여질 탭을 선택하는 것인데, 따로 지정하지 않을 경우 맨 앞의 탭이 기본으로 보여지게 되고, 다른 탭이 보여지도록 하고 싶다면 보여지게 하고 싶은 탭의 index를 지정해주시면 됩니다.

ps. 탭의 인덱스는 배열과 마찬가지로 0부터 시작합니다!