[Android] Intent기반 TabActivity 구현시 첫번째 탭이 무조건 생성되는 문제 해결 꼼수

안드로이드에서 탭을 구현할때는 대부분이 FrameLayout을 이용한 두개 이상의 레이아웃을 바꿔가며 보여주는 방법을 구현하고 있는것으로 알고 있습니다. 하지만 이경우엔 두개의 탭간의 상호 관계를 잘 생각해두어야 하며 각각의 탭에서 구현해야 하는 내용이 복잡하고 메모리 효율성을 많이 고민해야 한다면 아무래도 개발에 신경이 많이 쓰이게 되는 것이 사실입니다.

그래서 간단하게 다음에 설명할 탭을 구현하되 각각의 탭을 엑티비티로 구현하는 방법을 선호합니다.(물론 저 개인적인 선호입니다.) 우선 간단하게나마 탭엑티비티를 구현하는 방법에 대해 언급해 보겠습니다.

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"
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>

MyTabActivity.java

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Resources res = getResources();
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent;

// 첫번째 탭(0)
intent = new Intent(this, ArtistsActivity.class);
spec = tabHost.newTabSpec("artists").setIndicator("Artists",
res.getDrawable(R.drawable.icon))
.setContent(intent);
tabHost.addTab(spec);

// 두번째 탭(1)
intent = new Intent(this, AlbumsActivity.class);
spec = tabHost.newTabSpec("albums").setIndicator("Albums",
res.getDrawable(R.drawable.icon))
.setContent(intent);
tabHost.addTab(spec);

// 세번째 탭(2)
intent = new Intent(this, SongsActivity.class);
spec = tabHost.newTabSpec("songs").setIndicator("Songs",
res.getDrawable(R.drawable.icon))
.setContent(intent);
tabHost.addTab(spec);

// 세번째 탭 선택
tabHost.setCurrentTab(2);
}

ArtistsActivity.java / AlbumsActivity.java / SongsActivity.java

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);

String activityName = getClass().getSimpleName();

Log.e(activityName, activityName + " created");

TextView tvTitle = new TextView(this);
tvTitle.setText(activityName);
setContentView(tvTitle);
}

AndroidManifest.xml

<activity android:name=".BlankActivity"/>
<activity android:name=".ArtistsActivity"/>
<activity android:name=".AlbumsActivity"/>
<activity android:name=".SongsActivity"/>

위의 코드 정도로 테스트를 해볼수 있게 되었습니다. 각 탭의 컨텐츠 엑티비티들에는 onCreate시에 현재의 엑티비티 이름을 로그로 출력하도록 만들어져있습니다. 그리고 위의 탭엑티비티에서는 마지막 탭을 처음부터 선택하도록 하였습니다. 그런데 여기서! 엄청난 문제가 발생합니다.

사용자 삽입 이미지
마지막 엑티비티는 SongActivity입니다. 그런데 왜 ArtistsActivity도 생성이 되는것일까요. 안드로이드의 좀 병맛같은 버그 혹은 병맛같은 제 능력 둘중에 하나가 분명합니다. 위의 방법은 다음과 같이 해결이 가능합니다. 해결은 아니고 꼼수로 피해갈수 있다고 말하는게 맞겠네요.

MyTabActivity.java

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Resources res = getResources();
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent;

// 탭엑티비티 무조건 0번째 탭이 선택되어지는 버그를 회피하기 위한 코드
intent = new Intent(this, BlankActivity.class);
spec = tabHost.newTabSpec("").setIndicator("")
.setContent(intent);
tabHost.addTab(spec);
tabHost.getTabWidget()
.getChildTabViewAt(0).setVisibility(View.GONE);

// 첫번째 탭(1)
intent = new Intent(this, ArtistsActivity.class);
spec = tabHost.newTabSpec("artists").setIndicator("Artists",
res.getDrawable(R.drawable.icon))
.setContent(intent);
tabHost.addTab(spec);

// 두번째 탭(2)
intent = new Intent(this, AlbumsActivity.class);
spec = tabHost.newTabSpec("albums").setIndicator("Albums",
res.getDrawable(R.drawable.icon))
.setContent(intent);
tabHost.addTab(spec);

// 세번째 탭(3)
intent = new Intent(this, SongsActivity.class);
spec = tabHost.newTabSpec("songs").setIndicator("Songs",
res.getDrawable(R.drawable.icon))
.setContent(intent);
tabHost.addTab(spec);

// 세번째 탭 선택
tabHost.setCurrentTab(3);
}

AndroidManifest.xml

<activity android:name=".BlankActivity"/>
<activity android:name=".ArtistsActivity"/>
<activity android:name=".AlbumsActivity"/>
<activity android:name=".SongsActivity"/>

BlankActivity.java

public class BlankActivity extends Activity
{

}

안드로이드의 탭엑티비티를 호출할때 무조건 첫번째 엑티비티가 호출된다고 가정하여 빈 엑티비티를 첫번째 탭으로 등록하고 그 탭을 보이지 않게 변경하였습니다. 그러므로 결과적으로 탭엑티비티가 생성되면서 첫번째 탭이 자동 선택이 된후에 원하는 탭으로 이동할 수 있습니다.

이렇게 함으로써 첫번째 탭이 원치 않는 서버와의 통신을 한다거나 하는 것을 피할 수 있습니다.

[샘플코드 다운로드]