posted by Kyleslab 2012. 11. 12. 11:24

fragmentManager에 추가된 fragment를 어떻게 떼어내어 다시 fragment로 만들수 있을까? 혹은 이미 있는 fragment를 어떻게 다시 붙일수 있을까? 이때 attach와 detach메소드가 있다.

먼저 reference를 보자 

public abstract FragmentTransaction attach (Fragment fragment)

Re-attach a fragment after it had previously been deatched from the UI with detach(Fragment). This causes its view hierarchy to be re-created, attached to the UI, and displayed.

Parameters
fragmentThe fragment to be attached.
Returns
  • Returns the same FragmentTransaction instance.

public abstract FragmentTransaction detach (Fragment fragment)

Detach the given fragment from the UI. This is the same state as when it is put on the back stack: the fragment is removed from the UI, however its state is still being actively managed by the fragment manager. When going into this state its view hierarchy is destroyed.

Parameters
fragmentThe fragment to be detached.
Returns
  • Returns the same FragmentTransaction instance.

보면 attach보다 detach를 먼저 사용하도록 되어있다. detach는 UI로부터 fragment를 떼어내는 것이고 attach는 그것을 다시 UI에 붙인다는 의미이다. 이것을 제대로 사용하는 예제는 tab fragment소스에 찾아볼수 있다.


        @Override
        public void onTabChanged(String tabId) {
            TabInfo newTab = mTabs.get(tabId);	// 넣어놨던 tabinfo찾아온다.
            if (mLastTab != newTab) {//라스트탭이 뉴탭과 같지 않다면
                FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
                if (mLastTab != null) {	//라스트탭이 널이 아니면
                    if (mLastTab.fragment != null) {	//라스트탭의 프래그먼트가 널이 아니면
                        ft.detach(mLastTab.fragment);	//떼어낸다
                    }
                }
                if (newTab != null) {	// 뉴탭이 널이 아니면
                    if (newTab.fragment == null) {	//프래그먼트가 널이면
                        newTab.fragment = Fragment.instantiate(mActivity,
                                newTab.clss.getName(), newTab.args);//새로 만들어준다
                        ft.add(mContainerId, newTab.fragment, newTab.tag);	//추가해준다
                    } else {
                        ft.attach(newTab.fragment);	//널이 아니면 그대로 붙여준다.
                    }
                }

                mLastTab = newTab;	//새로운탭이 라스트탭이 된다.
                ft.commit();
                mActivity.getSupportFragmentManager().executePendingTransactions();
            }
        }


위에 소스처럼 detach로 잘떼어놨다가 다시 attach로 붙여준다.

이것만 봐도 위에서 설명한 것처럼 Activity와는 사용하는 방법, 개념이 완전히 다르고 조금 더 유동적을 사용할 수 있다는 것을 알수 있다. 

그런데 여기서 한가지 생기는 의문은 fragmentTransaction에는 add, remove와 같은 메소드도 있다. 이것을 왜 사용하지 않았을까? 내가 보기에는 자원 재활용과 fragment정보 유지라는 생각이 들었다. add와 remove를 반복적으로 사용하려면 fragment를 계속 동적으로 생성하고 지우고를 반복해야한다. 그리고 위의 예제처럼 TabInfo라는 자료형을 만들어 fragment를 유지한다면 그안의 정보도 유지될것으로 보인다.

그런데 이 detach메소드가 작동하지 않은경우가 있다. 바로 정적으로 fragment가 선언된 경우이다.

xml 파일로 아래와 같이 class가 지정되어 fragment가 선언된경우에는 detach, remove모두 작동하지 않는다.

    


###. Fragment생명주기에 onAttach, onDetach라는 콜백메소드가 있어 attach(), detach()메소드 실행시 이 콜백메소드들을 호출하지 않을까 했지만 호출하지는 않았다.


언제든 틀린 설명은 말씀해주세요^^





'Mobile > Android' 카테고리의 다른 글

JNI를 Xcode이용하기  (2) 2012.11.13
Fragment(2)  (0) 2012.11.12
Fragment 에서 방향 전환시 null 체크  (0) 2012.11.09
Fragment를 이용한 TabActivity  (0) 2012.11.09
Fragment(1)  (0) 2012.11.09