Android에서 Action Bar를 이용하여 아래와 같은 탭 액티비티를 만들수 있다.

물론 이전에도 Tab Host등을 이용하고 여러개의 액티비티들을 이용해서 탭을 만들수 있었지만, 지금 처럼 아주 간결하게 만들기가 쉽지는 않았다.


액티비티 하나에 Fragment들을 탭의 개수 만큼 구현하고, 그리고 가장 중요한 ActionBar 모드를 ActionBar.NAVIGATION_MODE_TABS로 설정해주면 간단하게 탭을 구현할수 있다.





너무 간단하니까.. 바로 소스를 보고 따로 구현하도록 하면 될듯하다.

 1. 탭들을 등록하고 관리하는 Activity 하나.

 2. 탭들을 표현할 Fragment 들이 탭의 개수만큼(위에서는 3개)

 3. TabListener 하나.




FragmentTabs Activity.

package com.hopeisagoodthing.actionbar.tab;

import android.app.ActionBar;
import android.app.Activity;
import android.os.Bundle;

public class FragmentTabs extends Activity {

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

		final ActionBar actionBar = getActionBar();
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

		actionBar.addTab(actionBar
				.newTab()
				.setText("Tab1")
				.setTabListener(
						new TabListener<FragmentTab1>(this, "tab1",
								FragmentTab1.class)));
		actionBar.addTab(actionBar
				.newTab()
				.setText("Tab2")
				.setTabListener(
						new TabListener<FragmentTab2>(this, "tab3",
								FragmentTab2.class)));
		actionBar.addTab(actionBar
				.newTab()
				.setText("Tab3")
				.setTabListener(
						new TabListener<FragmentTab3>(this, "tab3",
								FragmentTab3.class)));

		if (savedInstanceState != null) {
			actionBar.setSelectedNavigationItem(savedInstanceState.getInt(
					"selectedTab", 0));
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putInt("selectedTab", getActionBar()
				.getSelectedNavigationIndex());
	}
}



FragmentTab1

package com.hopeisagoodthing.actionbar.tab;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class FragmentTab1 extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.simple, container, false);
		View tv = v.findViewById(R.id.text);
		((TextView) tv).setText("coolkim.tistory.com");
		return v;
	}
}



FragmentTab2

package com.hopeisagoodthing.actionbar.tab;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class FragmentTab2 extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.simple, container, false);
		View tv = v.findViewById(R.id.text);
		((TextView) tv).setText("Hope is a good thing.");
		return v;
	}
}



FragmentTab3

package com.hopeisagoodthing.actionbar.tab;

import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class FragmentTab3 extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.simple, container, false);
		View tv = v.findViewById(R.id.text);
		((TextView) tv).setText("Simple Tab");
		return v;
	}
}



TabListener

package com.hopeisagoodthing.actionbar.tab;

import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.app.ActionBar.Tab;
import android.widget.Toast;

public class TabListener<T extends Fragment> implements ActionBar.TabListener {

	private final Activity mActivity;
	private final String mTag;
	private final Class<T> mClass;
	private Fragment mFragment;

	public TabListener(Activity activity, String tag, Class<T> clz) {
		mActivity = activity;
		mTag = tag;
		mClass = clz;

		mFragment = mActivity.getFragmentManager().findFragmentByTag(mTag);
		if (mFragment != null && !mFragment.isDetached()) {
			FragmentTransaction fragmentTransaction = mActivity
					.getFragmentManager().beginTransaction();
			fragmentTransaction.detach(mFragment);
			fragmentTransaction.commit();
		}
	}

	public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) {
		if (mFragment == null) {
			mFragment = Fragment.instantiate(mActivity, mClass.getName(), null);
			fragmentTransaction.add(android.R.id.content, mFragment, mTag);
		} else {
			fragmentTransaction.attach(mFragment);
		}
	}

	public void onTabUnselected(Tab tab, FragmentTransaction fragmentTransaction) {
		if (mFragment != null) {
			fragmentTransaction.detach(mFragment);
		}
	}

	public void onTabReselected(Tab tab, FragmentTransaction fragmentTransaction) {
		Toast.makeText(mActivity, "onTabReselected!", Toast.LENGTH_SHORT)
				.show();
	}
}

저작자 표시
신고
  1. 안드로이드 개발자 2013.03.12 02:09 신고

    안녕하세요. 안드로이드 앱을 개발중인 개발자입니다.

    혹시 위의 예제 전체 소스를 얻을 수 있을까요?^^;;

    • rekun,ekun 커뉴 2013.03.15 14:00 신고

      넵, 안녕하세요.
      제가 게시한 내용이 풀소스 입니다.

      혹시 안되는 부분이 있던가요???

  2. 지나가던 개발자 2013.03.21 10:11 신고

    xml도 올려달라는 말씀이신거 같은데..

  3. ㅂㅈㄷ 2013.05.13 14:28 신고

    잘보고 갑니다 엑션바에 저런기능도 있었군요 ㅡㅡ;;

    가끔 보면 탭은 도대체 만드는 방법이 얼마나 많은지 좀 하나로 정했으면 싶어요

  4. 지나가던 개발자 2013.05.25 14:35 신고

    ApiDemos에 나와있는 내용이네요.

    • rekun,ekun 커뉴 2013.05.27 22:36 신고

      그런가요??
      회사에서 안드로이드4.0 api 나온거 공부하다가 발견한건데
      거기에도 나와있었군요~

  5. 달걀 2013.05.27 20:35 신고

    안녕하세요. 덕분에 많은 정보 얻고갑니다 ㅠ.ㅠ
    감사합니다.

    게시하신대로 똑같이 따라해서 actionbar를 사용한 Tab을 구현했습니다.
    그런데 상단에 HopesiaGoodthing.Tab이라고 써있는 상단바를 없애는 방법은 없을까요?

    requestWindowFeature(Window.FEATURE_NO_TITLE);도 써보고
    매니페스트도 건드려봤는데 자꾸 프로그램이 죽네요 ㅠ.ㅠ

    • rekun,ekun 커뉴 2013.05.27 22:36 신고

      패키지 이름을 바꾸셔도 되구요,
      테마중에 타이틀 안나오게 하는것도 있습니다.

  6. 달걀2 2013.05.28 19:09 신고

    또 질문이 있는데요
    2번째 tab 안에 ViewFlipper쓰려고하는데
    혹시 가능한가요?

    구글링해봐도 예제를 찾기 힘들어서
    혼자 해보고있는데 실행자체가 안되서요

    • rekun,ekun 커뉴 2013.05.30 23:53 신고

      viewFlipper를 탭안에 구현하신다는거는... 어떤 용도인지 모르겠지만,
      일반적인 viewFlipper예제들을 하나의 액티비티 내에서 구현하는것은 똑같습니다.

      어떤게 안되는건지 잘 모르겠네요@.@

  7. 뉴비 2013.10.11 16:24 신고

    제가 메뉴아이템을 이용해서 탭1프레그먼트와 intent로 값을 주고 받고 싶은데요.. 빨간줄은 안뜨는데 어플실행시키면 중지되네요..
    탭프레그먼트는 블로거님이 포스팅한 소스 그대로 썻고요 intent 소스는
    public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case R.id.save:
    Toast.makeText(this, "main", Toast.LENGTH_SHORT).show();
    Intent intent = new Intent(this, FragmentTab1.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("su", su1);
    startActivity(intent);
    return true;
    case R.id.delete:

    }
    return super.onOptionsItemSelected(item);
    }
    입니다.
    FragmentTab1 소스 그대로에
    su1 = getActivity().getIntent().getExtras().getInt("su");
    했고요..
    아무래도 소스가 완전히 잘못된거 같은데 fragment tab에서 intent 대해 포스팅좀 해주실수 있으신가요? 아니면 덧글이라도 ㅠㅠ

  8. Yeom 2013.11.07 17:56 신고

    안녕하세요 Tab안에 image를 넣어서 Tab을 image화 시키고싶은데 image적용 시키는법은 어떻게 되는건가요 ㅠㅠ

  9. 만식 2014.10.16 14:19 신고

    fragment 를 어떻게 만드는지 간단한 설명 부탁 드려도 될까요? 여러 방법으로 시도 중인데 자꾸 APP 이 죽습니다. 미치겠어요.

  10. K1A22015 2016.10.23 18:06 신고

    저는 왜 오류가 날까요???

    E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.a2015.k1a2.unipackcreater, PID: 4352
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.a2015.k1a2.unipackcreater/com.a2015.k1a2.unipackcreater.unimain}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setNavigationMode(int)' on a null object reference
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2306)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368)
    at android.app.ActivityThread.access$800(ActivityThread.java:149)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5292)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703)
    Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setNavigationMode(int)' on a null object reference
    at com.a2015.k1a2.unipackcreater.unimain.onCreate(unimain.java:20)
    at android.app.Activity.performCreate(Activity.java:6020)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2259)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2368) 
    at android.app.ActivityThread.access$800(ActivityThread.java:149) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1284) 
    at android.os.Handler.dispatchMessage(Handler.java:102) 
    at android.os.Looper.loop(Looper.java:135) 
    at android.app.ActivityThread.main(ActivityThread.java:5292) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at java.lang.reflect.Method.invoke(Method.java:372) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:908) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:703) 

+ Recent posts

티스토리 툴바