2012-05-25 3 views
0

내 애플리케이션에서 탭을 사용할 필요가 있으므로 안드로이드 FragmentTabs 예를 중심으로 코드를 기반으로했습니다. here.입니다. 그러나 나는 다음과 같이 내 자신의 목적에 맞게 코드에서 두 줄을 변경했습니다.Android 예제 코드 'FragmentTabs'로 인해 기기 방향에 예외가 발생합니다.

주어진 안드로이드 코드에서 탭이 사용자에 의해 변경 될 때마다 Fragment-of-view가 삭제되고보기로 들어오는 Fragment가 생성됩니다. 내 목적으로는 바람직하지 않습니다. 내 Fragments는 서로 독립형 일 수 있지만 네트워크 연결을 통해 실시간 데이터에 반응하고 이에 따라 작동합니다. 프래그먼트가 아웃 오브 뷰이기 때문에 내가 백그라운드에서 작업하는 것을 멈추길 원한다는 것을 의미하지는 않습니다. (안타깝게도 안드로이드 예제에서 생각해 볼 수 있습니다.) 결과적으로 코드를 만들고 숨기지 않고 탭을 숨기고 표시하도록 코드를 변경했습니다. 아래 그림과 같이

이를 달성하기 위해, 예제 코드에 내가이 곳에서 onTabChanged()을 변경 : I가 원하는대로이 지금 작동

public void onTabChanged(String tabId) { 
     TabInfo newTab = mTabs.get(tabId); 
     if (mLastTab != newTab) { 
      FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); 
      if (mLastTab != null) { 
       if (mLastTab.fragment != null) { 
        ft.hide(mLastTab.fragment); //***** 1st Alteration 
        //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.show(newTab.fragment); //************ 2nd Alteration 
        //ft.attach(newTab.fragment); 
       } 
      } 

      mLastTab = newTab; 
      ft.commit(); 
      mActivity.getSupportFragmentManager().executePendingTransactions(); 
     } 
    } 

. 이제 장치가 방향을 바꿀 때 문제가 발생합니다. 제 1 방향 변경시, 이전에 선택된 탭 콘텐츠, 즉 단편은 표시되지 않습니다. 이것은 내가 '숨어'있고 '보여주는'탭이라는 사실과 관련이 있습니다. 그러나 더 심각하게는 디바이스의 제 재교육에 예외가 발생된다

E/AndroidRuntime (371)에 의해 발생 : java.lang.NullPointerException이 E/AndroidRuntime (371)에서 android.support.v4.app.FragmentManagerImpl.findFragmentByTag E/AndroidRuntime (371) (FragmentManager.java:1211) : $ TabManager.addTab에서 (ClassName.java:121)는

는 addTab 방법은 여기에서 :

public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) { 
     tabSpec.setContent(new DummyTabFactory(mActivity)); 
     String tag = tabSpec.getTag(); 

     TabInfo info = new TabInfo(tag, clss, args); 

     // Check to see if we already have a fragment for this tab, probably 
     // from a previously saved state. If so, deactivate it, because our 
     // initial state is that a tab isn't shown. 
     FragmentManager fm = mActivity.getSupportFragmentManager(); 
     Log.i("Class Name","addTab() FragmentManager = " + fm.toString()); 
     Log.i("Class_Name","addTab() tag = " + tag); 
     info.fragment = fm.findFragmentByTag(tag); // **** This causes the exception 

     /* 
     * Commented the following as Fragments are not removed but hidden/shown on tab change. 
     */ 
     if (info.fragment != null && !info.fragment.isDetached()) { 
      FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction(); 
      ft.detach(info.fragment); 
      ft.commit(); 
     } 

     mTabs.put(tag, info); 
     mTabHost.addTab(tabSpec); 
    } 

더 구체적으로 예외는 info.fragment = fm.findFragmentByTag(tag);에서 발생합니다. 코드에서 볼 수 있듯이 어떤 객체가 Null인지 즉, FragmentManager 또는 태그인지 정확히 구분하려고했지만 null로 기록되지 않습니다.

안드로이드 예제를 완전히 이해하지 못하고 프래그먼트를 숨기고 표시하지 않고 첨부하고 분리하면 제대로 작동합니다. 누구든지 문제가 무엇인지 설명 할 수 있습니까?

+0

방금 ​​전에 오리 엔테이션 변경 전에 복원 해야하는 아무것도 할 saveInstanceState! = null' 확인하는 경우 나에게 보인다 ... – Barak

+0

그것은 코드에서 뭔가 있는지 궁금하네요. FragmentManager 자체. – Kerry

+0

탭이 포함 된 활동에 대해 onCreate를 게시 할 수 있습니까? – Barak

답변

1

the android docs on runtime changes에 따라 오리엔테이션이 변경되면 활동이 다시 시작됩니다. 이는 FragmentManager가 상태를 번들로 저장 한 다음 다시로드한다는 것을 의미합니다.

보이는 탭이 보이지 않아도 모든 탭이 추가되어 FragmentManager의 추가 된 조각 목록에 숨겨집니다. TabManager는 아무 것도 저장하지 않지만 새로 생성되면 새로운 TabManager와 복원 된 FragmentManager 사이의 불일치라고 생각됩니다.

나는 that doco을주의 깊게 읽고 탭 저장/복원에 대한 몇 가지 매우 신중한 선택을 권장합니다.

나머지는 순수한 추측입니다. Fragment.instantiate 나 ft.add와 같이 보이지 않습니다. 새로운 조각이 이전 조각을 복제하는지 확인하십시오. 이는 TabManager가 하나의 프래그먼트에 대한 참조를 보유하고 FragmentManager가 해당 프래그먼트의 두 인스턴스를 보유하는 시나리오로 이어질 수 있습니다.

현재 onCreate에 표시되지 않는 탭에서 FragmentManager를 지우거나 새 인스턴스를 만들기 전에 조각 존재 여부를 확인하는 것으로 충분할 수 있습니다.

관련 문제