본문 바로가기

Programming/Android

[안드로이드] 탭 레이아웃(Tab Layout) 사용하기 - Intent 방식1

트랙백 주소 : http://www.tipssoft.com/bulletin/tb.php/FAQ/987
  Download :  TipsTabWidgetProject.zip(72.9K), 2011-08-09 19:44:02
팁스소프트에서 제공하는 프로그래밍과 관련된 자료나 정보들을 무단으로 복제하거나 게재하는 행위는
상호간의 신뢰를 무너뜨리는 행위이며, 법적인 문제를 야기할 수 있으므로 각별한 주의를 당부드립니다.
* 팁스소프트 저작권 정책 보기 -  http://www.tipssoft.com/bulletin/tb.php/FAQ/637
 
이 자료들은 팁스소프트에서 제공하는 [ 알짜배기 ] 프로그램을 이용하면 더 편리하게 볼수 있습니다.
* 알짜배기 프로그램 받기 -  http://www.tipssoft.com/bulletin/tb.php/QnA/8406
 
* 안드로이드 강좌 목록 - http://www.tipssoft.com/bulletin/tb.php/old_bbs/501
 
 
안드로이드용 기기들은 대부분 스마트폰처럼 휴대성을 강조하기때문에 화면의 크기가 작고, 사용자 조작
방식으로는 터치 방식을 많이 사용합니다. 그래서 프로그래머는 어플리케이션을 구성할 때 사용자가
기기를 조작하는데 불편함을 느끼지 않도록 컨트롤의 배치에 신경을 써주어야합니다. 이러한 문제 때문에
어느정도의 복잡도를 가진 어플리케이션을 구성할 때에는 탭 레이아웃 ( Tab Layout ) 으로 배치하는
것이 좋습니다.
 
탭 레이아웃은 어플리케이션이 제공하는 기능을 특징별, 항목별로 그룹지어서 여러개의 탭에 나누어
접근할 수 있도록 해줍니다. 예를 들면 작업관리자 어플리케이션을 실행했을 때 "실행중", "시스템",
"사용팁" 으로 해당 기기의 작업에 대한 기능을 나누어 제공하는 것을 볼 수 있습니다.
 
탭 레이아웃을 사용하는 방법에는 여러개가 있지만 이번 강좌에서는 그 중에 하나인 Intent 를 사용하여
각 탭 화면에 각기 다른 액티비티를 사용하는 방법에 대하여 알아보도록 하겠습니다.
 
 
1. 탭 레이아웃의 구성
 
    탭 레이아웃은 어플리케이션의 기능들을 여러개의 탭으로 나누어 구성하고, 일반적으로 한번에 
    하나의 탭 화면만을 볼 수 있습니다. 그렇기때문에 사용자가 보고자 하는 탭을 선택할 수 있게 
    탭의 이름을 출력하는 탭 선택 부분과 선택한 탭과 연결된 페이지를 출력하는 탭 페이지 부분이
    존재하게 됩니다. 
 
    이렇게 탭 선택 부분에 대한 기능을 수행하는 클래스가 TabWidget 이고, 탭 페이지 부분에 대한
    기능을 수행하는 클래스가 FrameLayout 입니다. 이 두 클래스는 서로 다른 일을 수행하지만 각자의
    기능을 수행하는데에 있어서 밀접한 관련이 있기 때문에 두 클래스를 조율하고, 관리해주는 TabHost
    클래스가 필요하게 됩니다.
 
    아래의 그림에서 TabWidget 부분이 탭을 선택하는 영역이며 FrameLayout 부분은 선택한 탭에 맞는
    페이지를 출력하는 영역입니다.
 
     
 
    TabWidget 클래스와 FrameLayout 클래스는 대부분 TabHost 클래스에 의해 호출되고 관리되어지기
    때문에 개발자는 대부분 TabHost 클래스를 다루게 됩니다.
 
  
2. 탭의 각 화면 구성하기
 
    탭 레이아웃에서 사용할 페이지 화면을 구성하는 것입니다. 모든 탭은 각각 따로 Activity 클래스를
    이용하여 화면 별로 나누어서 구성되어야 합니다. 예를 들어, 어떤 어플리케이션에서 Music, Book,
    Movie 라는 탭을 가져야 한다면 MusicActivity 와 BookActibity 그리고 MovieActivity 를 따로 구성
    하여야 합니다. 이 때 이 액티비티들은 XML 형식을 이용하여 레이아웃을 구성할 수도 있고, 아래의
    코드처럼 소스 코드로 컨트롤들을 생성하여 구성할 수도 있습니다.
 
    public class MusicActivity extends Activity
    {
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
 
            // 텍스트뷰를 생성한다.
            TextView tv = new TextView(this);
            // 텍스트뷰에 문자열을 설정한다.
            tv.setText("This is the Music Tab");
            // 액티비티에 텍스트뷰를 배치한다.
            setContentView(tv);
        }
    }
 
    위와 같이 탭별로 클래스를 구성한 후에 프로젝트 폴더 내의 AndroidManifest.xml 파일에 새로 만든
    클래스들을 아래와 같이 추가시켜주어야 합니다.
 
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.TipsTabWidget"
          android:versionCode="1"
          android:versionName="1.0">
        <application android:label="@string/app_name" android:icon="@drawable/icon">
            <activity android:name="TipsTabWidgetActivity"
                      android:label="@string/app_name">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name="MusicActivity">
            </activity>
            <activity android:name="BookActivity">
            </activity>
            <activity android:name="MovieActivity">
            </activity>
        </application>
    </manifest>
 
 
3. XML 형식으로 탭 레이아웃 구성하기
  
    탭을 사용하는 액티비티의 레이아웃을 XML 형식으로 구성합니다. XML 로 구성할 때에는 TabHost
    항목 내에 TabWidget 과 FrameLayout 항목을 반드시 포함시켜야 하는데 이 때, LinearLayout 을
    사용하면 수직방향으로 적절하게 배치시킬 수 있습니다. 
 
    아래의 코드는 탭 레이아웃을 구성하는 XML 코드입니다. 아래의 코드를 보면 TabWidget 항목과
    FrameLayout 항목이 각각 tabs 와 tabcontent 라는 ID 값을 가지고 있는데 이 ID 는 TabHost 에서
    사용하는 고유한 ID 값이기 때문에 다른 컨트롤을 구성할 때처럼 사용자가 임의로 ID 값을 설정하면 
    컴파일 에러가 발생할 수 있습니다.
 
    <?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"
            android:padding="5dp">
            <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"
                android:padding="5dp" />
        </LinearLayout>
    </TabHost>
 
    만약 사용자가 선택하는 탭의 위치를 화면의 하단으로 배치하고 싶은 경우에는 위의 코드에서
    TabWidget 과 FrameLayout 의 위치를 바꾸고 FrameLayout 의 weight 속성을 추가하여 아래와
    같이 파랑색 부분만 코드를 변경해 주시면 됩니다.
 
    <TabHost  ... 생략... >
        <LinearLayout ... 생략... >
            <FrameLayout
                android:id="@android:id/tab_content"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                
android:layout_weight="1"
                android:padding="5dp" />
            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </TabHost>
  
 
3. 탭 기능 구현하기
 
    메인 액티비티에서 탭 레이아웃을 쉽게 구현하려면 Activity 클래스가 아닌 TabActivity 클래스를
    상속받아야 합니다. TabActivity 클래스를 상속받은 클래스에서는 탭 레이아웃에 관한 멤버 메소드를
    제공하기 때문에 보다 쉽게 탭 레이아웃을 구성할 수 있습니다.
 
    이 강좌의 1번 항목에서도 언급하였듯이 탭 레이아웃을 소스코드에서 다루려면 TabWidget 과
    FrameLayout 을 관리하는 TabHost 객체를 이용해야합니다. TabActivity 클래스의 getTabHost
    멤버 메소드를 호출하면 해당 액티비티에서 사용할 수 있는 TabHost 객체를 얻을 수 있습니다.
 
    TabHost 객체에 탭 레이아웃에 대한 정보를 전달할 때에는 TabSpec 객체를 사용하는데 이 또한
    TabHost 클래스의 newTabSpec 멤버 메소드로 얻을 수 있습니다. TabSpec 객체에서 setIndicator
    메소드를 이용하면 탭의 선택 영역에 출력될 아이콘이나 탭이름을 설정할 수 있고, setContent
    메소드를 이용하면 해당 탭이 보여줄 화면(액티비티 혹은 뷰) 을 설정할 수 있습니다. 이 예제에서는
    각 탭 화면에 해당하는 액티비티를 인텐트로 구성하여 setContent 메소드로 전달하고 있습니다.
    
    public class TipsTabWidgetActivity extends TabActivity
    {
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            // main.xml 파일에 구성한 리소스를 이 액티비티에서 사용한다.
            setContentView(R.layout.main);
  
            // 이 탭액티비티에서 사용할 수 있는 TabHost 객체를 얻는다. 
            TabHost tab_host = getTabHost();  
            // 각 탭에 사용할 TabSpec 객체.
            // 탭호스트에 TabWidget 과 FrameLayout 이 사용할 정보를 넘겨주는 역할을 한다.
            TabHost.TabSpec spec;
            // 각 탭의 FrameLayout 이 사용하는 액티비티를 구성하는 객체
            Intent intent;
 
            // 탭에서 액티비티를 사용할 수 있도록 인텐트를 생성한다.
            intent = new Intent().setClass(this, MusicActivity.class);
            // "music" 이라는 태그 값을 가진 TabSpec 객체를 생성한다.
            spec = tab_host.newTabSpec("music");
            // TabSpec 객체에 TabWidget 객체가 출력할 탭의 이름을 설정한다.
            spec.setIndicator("Music");
            // TabSpec 객체에 FrameLayout 이 출력할 페이지를 설정한다.
            spec.setContent(intent);
            // 탭호스트에 해당 정보를 가진 탭을 추가한다.
            tab_host.addTab(spec);
 
            // 탭에서 액티비티를 사용할 수 있도록 인텐트를 생성한다.
            intent = new Intent().setClass(this, BookActivity.class);
            // "book" 이라는 태그 값을 가진 TabSpec 객체를 생성한다.
            spec = tab_host.newTabSpec("book");
            // TabSpec 객체에 TabWidget 객체가 출력할 탭의 이름을 설정한다.
            spec.setIndicator("Book");
            // TabSpec 객체에 FrameLayout 이 출력할 페이지를 설정한다.
            spec.setContent(intent);
            // 탭호스트에 해당 정보를 가진 탭을 추가한다.
            tab_host.addTab(spec);
  
            // 탭에서 액티비티를 사용할 수 있도록 인텐트를 생성한다.
            intent = new Intent().setClass(this, MovieActivity.class);
            // "movie" 이라는 태그 값을 가진 TabSpec 객체를 생성한다.
            spec = tab_host.newTabSpec("movie");
            // TabSpec 객체에 TabWidget 객체가 출력할 탭의 이름을 설정한다.
            spec.setIndicator("Movie");
            // TabSpec 객체에 FrameLayout 이 출력할 페이지를 설정한다.
            spec.setContent(intent);
            // 탭호스트에 해당 정보를 가진 탭을 추가한다.
            tab_host.addTab(spec);
 
            // 첫번째 탭을 선택한 상태로 지정한다.
            tab_host.setCurrentTab(0);
        }
    }
 
 
4. 실행 화면
 
    이 강좌에서 다룬 예제를 실행하면 아래의 그림과 같습니다. 좌측 그림은 이 강좌의 3 번 항목에서  
    <TabWidget> -  <FrameLayout> 순서로 탭 레이아웃을 구성했을 때 출력되는 어플리케이션의
    모습이고, 우측 그림은 <FrameLayout> - <TabWidget> 순서로 레이아웃을 구성했을 때 출력되는
    모습입니다.