안드로이드 탭을 구현해 보자, Fragment

2018. 1. 17. 20:45 안드로이드/프래그먼트(Fragment)

맨 처음 어플을 만들게 되면서 가장 먼저 생각한 것은 바로 [탭, Tabs]이었습니다

무엇보다도 양옆으로 스크롤 하면서 사용할 수 있는 Fixed Tab + Scroll이 가장 마음에 들었는대요!


제가 네이버를 찾아보며 가장 설명이 잘되어 있는곳은 http://blog.naver.com/liar1938/30171663892 이라 생각됩니다

그러나 모든것은 직접 써봐야 더 능통해 지므로 서평이 끝난 지금, 지금부터 어플 강좌를 하나씩 시작하겠습니다~


이 강좌를 통해 알수 있는것들

Fragment

Fixed Tabs + Scroll

Fragment에서 id값 찾기



먼저 프로젝트를 만들어 주세요


Min API 11이상부터 Fixed Tabs + Swipe라는 네비게이션 타입을 지원하는것으로 알고있습니다

적절하게 잡아주시고

이렇게 Navigation Type를 "Fixed Tabs + Swipe"로 결정해 주세요 ㅎㅎ


프로젝트 생성이 끝났다면 이제 MainActivity에 들어가 봅시다

src/(패키지 네임)/MainActivity.java파일입니다


제 경험상

res/layout/activity_main.xml

res/layout/fragment_main_dummy.xml

이 두개의 파일은 건들일 필요가 없더군요


기본적으로 아래와 같은 내용이 있을겁니다 MainActivity을 눌러 펼쳐주세요


MainActivity



이 소스가 이 예제 어플에서 가장 중요한 소스입니다

먼저 처음 빨간색으로 칠해져 있는 메소드 public Fragment getItem(int position)의 경우 아래와 같이 변경이 필요합니다


@Override

public Fragment getItem(int position) {

// getItem is called to instantiate the fragment for the given page.

// Return a DummySectionFragment (defined as a static inner class

// below) with the page number as its lone argument.

switch(position) {

case 0:

return new 첫번째탭에들어갈내용이담긴액티비티이름(mContext);

case 1:

return new 두번째탭에들어갈내용이담긴액티비티이름(mContext);

case 2:

return new 세번째탭에들어갈내용이담긴액티비티이름(mContext);

}

return null;

}


그런대 여기서도 수정이 필요한대요, "첫번째탭에들어갈내용이담긴액티비티이름"... 길긴한대 일단 가봅시다

이 부분도 수정이 필요합니다

그런대 지금은 필요가 없으니 일단 넘어가겠습니다


분홍색으로 칠해진 것은 추가가 필요합니다 ㅎㅎ


그다음 초록색으로 칠해져 있는 return 3; 은 탭의 갯수를 반환합니다

이미 눈치채신분들은 아시겠지만 탭의 갯수를 줄이려면 이 값을 줄인다음 switch-case문도 줄여주면 되겠지요??


DummySectionFragment로 탭을 구현할 수도 있지만 onCreateView() 메소드는 inflater 객체를 사용하여 뷰를

반환하여 화면에 뿌려주므로 getItem() 메소드로 탭 화면을 지정할 때에 비해 코드가 길어지므로 지워버립니다


마지막 파란색 부분은 탭의 이름입니다

return getString(R.string.title_section1).toUpperCase(l);

굵고 밑줄친 부분이 탭의 이름이 되는대요 이부분은 어떻게 이루어져 있냐,

R(R.java파일을 참조합니다).string(R파일중 string부분을 참조합니다, 즉 values/string.xml을 참조합니다)

.title_section1(title_section1이란 이름의 값을 반환합니다)

이렇게 생각하시면됩니다 저도 이렇게 생각했고요


(이글이 올려지는 당시가 강좌가 하나도 올라와 있지 않지만 시간이 지나 강좌를 많이 쓴다음 차례가 되면 넣을탠대

그때쯤이면 더 쉽게 이해가 되실겁니다 지금은 이해하지 않아도 됩니다)


그럼 탭의 이름을 수정하기 위해서는 values/string.xml을 수정해야 겠죠?

이부분은 너무 쉬우니 따로 말씀드리지는 않겠습니다


밑줄이 그어 있는 onCreateOptionsMenu 메소드는 메뉴키를 누르면 뜨는 내용을 정의하는건대 필요없으니 삭제합니다



이제 MainActivity는 끝났습니다

이어서 각 탭에 들어갈 내용물들을 만들어 봅시다


만들고 있던 프로젝트에 마우스 오른쪽을 누른다음 New-other-Android Activity를 눌러주세요

아무렇게나 BlankActivity를 만들어 주신다음 소스를 확인해 봅시다


package com.tistory.whdghks913.exampletabs;


import android.os.Bundle;

import android.app.Activity;

import android.view.Menu;


public class Tabs1 extends Activity {


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_tabs1);

}


@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.tabs1, menu);

return true;

}


}

 

너무 간단합니다 ㅎㅎ...;

각 탭에 나타날 화면과 관련된 모든 자바 소스를 이곳에 기록해야 합니다

자 아래와 같이 그냥 수정해 주세요

package com.tistory.whdghks913.exampletabs;


import android.annotation.SuppressLint;

import android.content.Context;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;


@SuppressLint("ValidFragment")

public class Tabs1 extends Fragment {

Context mContext;

public Tabs1(Context context) {

mContext = context;

}

@Override

public View onCreateView(LayoutInflater inflater, 

ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.activity_tabs1, null);


     return view;

}


}

위 원본소스의 취소선은 삭제된 부분, 아래 소스의 굵은 부분은 추가, 수정된 부분 입니다

밑줄친 부분은 다들 아시다 싶이 레이아웃을 결정하는 xml에 관한 구문입니다


MainActivity는 FragmentActivity를 상속하지만 탭에 들어갈 내용들은 Fragment을 상속(extends)해야 합니다


혹시 Fragment에 대해 더 알고 싶으시다면 

http://developer.android.com/guide/components/fragments.html

http://developer.android.com/reference/android/support/v4/app/FragmentActivity.html


이제 이런 소스와 같이 나머지 탭에 들어갈 내용물들도 하나씩 구성해 주시면 됩니다

모든 탭의 구성이 끝났다면 아까 MainActivity에서 건너뛰었던 부분으로 돌아가 이름을 지정해야하는대요


switch(position) {

case 0:

return new 첫번째탭에들어갈내용이담긴액티비티이름(mContext);

case 1:

return new 두번째탭에들어갈내용이담긴액티비티이름(mContext);

case 2:

return new 세번째탭에들어갈내용이담긴액티비티이름(mContext);

}

위 세개의 문구를 만드신 Activity의 이름으로 변경해 주시면 됩니다

이제 빌드 해보시고 작동 시켜 보시면 각 탭과 연결된 xml에 기록된 내용물들이 탭 아래에 나타나는것을 볼수 있습니다

자 근대 문제가 발생했습니다

우리가 탭을 구현하기 위해 쓴것은 Fragment, 그런대 Fragment에서는 findViewById가 잘 작동하지 않는대요

Button button1;

button1 = (Button) view.findViewById(R.id.button1);

이렇게 구현하시면 쉽게 작동됩니다 ㅎㅎ

위치는 View view = inflater.inflate(R.layout.activity_tab1, null);와 return view;사이에 넣어주세요


실행 스샷

옆으로 스크롤하면 나타납니다



메뉴 아이탬을 아래로 이동하는것은 가능합니다

일명 루익처럼 말이죠

이렇게 아래로 이동하는것은 가능하며, API 14 (4.0)이상에서 사용가능합니다

<activity .. android:uiOptions="splitActionBarWhenNarrow" ..></activity>

이 빨간 문구를 AndroidManifest.xml의 <activity> 부분에 넣어주세요


API 14보다 낮을경우, 이 구문은 무시됩니다

ExampleTabs.zip

출처 : http://itmir.tistory.com/283