7

한 번에 하나씩 조각이있는 세 개의 탭 (ActionBar 탭)이있는 앱이 있습니다.하나의 ActionBar 탭 내부에서만 조각 사이의 트랜잭션

TabListener

TabsActivity

TAB1 -> ListFragment1 -> ListFragment2 -> Fragment3

TAB2 -> Tab2Fragment

tab3에 -> Tab3Fragment

내가 만들 때 문제가 ListFragment1에서 ListFragment2 로의 FragmentTransaction (OnListItemClicked 내부), 다른 t 내부의 프래그먼트 abs 또한 ListFragment2로 변경됩니다.

결국에는 조각 내에서만 조각을 변경하고 다른 탭의 상태를 유지하려고합니다.

저는 상태 (OnSavedInstance())를 이미 저장하고 있습니다. 내가 여기에없는 것을 알고 있습니까?

코드의 일부 :

public class TabsActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.tabs); 

     // setup Action Bar for tabs 
     ActionBar actionBar = getActionBar(); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 

     // instantiate fragment for the tab 
     Fragment networksFragment = new NetworksFragment(); 
     // add a new tab and set its title text and tab listener 
     actionBar.addTab(actionBar.newTab().setText("Tab1") 
       .setTabListener(new TabsListener(ListFragment1))); 

     // instantiate fragment for the tab 
     Fragment historyFragment = new HistoryFragment(); 
     // add a new tab and set its title text and tab listener 
     actionBar.addTab(actionBar.newTab().setText("Tab2") 
       .setTabListener(new TabsListener(Tab2Fragment))); 

     // instantiate fragment for the tab 
     Fragment settingsFragment = new SettingsFragment(); 
     // add a new tab and set its title text and tab listener 
     actionBar.addTab(actionBar.newTab().setText("Tab3") 
       .setTabListener(new TabsListener(Tab3Fragment))); 
    } 
} 

public class TabsListener implements ActionBar.TabListener { 

    private Fragment frag; 


    // Called to create an instance of the listener when adding a new tab 
    public TabsListener(Fragment networksFragment) { 
     frag = networksFragment; 
    } 

    @Override 
    public void onTabReselected(Tab arg0, FragmentTransaction arg1) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) {  
     ft.add(R.id.fragment_container, frag, null); 
    } 

    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     ft.remove(frag);   
    } 
} 

public class ListFragment1 extends ListFragment { 

    @Override 
    public void onListItemClick(ListView l, View v, int position, long id) { 

     getListView().setItemChecked(position, true); 

     ListFragment2 fragment2 = ListFragment2.newInstance(position); 

     FragmentTransaction ft = getFragmentManager().beginTransaction(); 
     ft.replace(R.id.fragment_container, fragment2); 
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); 
     ft.addToBackStack(null); 
     ft.commit(); 
    } 
} 

답변

6

당신은 아무것도 누락하지 않는 (또는 내가 너무 그것을 누락).

"제대로"수행 할 수있는 방법을 길고도 열심히 수색했지만 아무것도 찾을 수 없습니다. 내가 한 일은 내 자신의 백 스택 논리를 작성하는 것입니다. 불행히도 제 고용주는 제 코드를 소유하고 있기 때문에 그대로 쓰지 않아도되지만 여기에 나의 접근 방식이 있습니다 :

각각의 탭마다 하나의 항목이있는 enum을 만듭니다. TabType이라고합시다. HashMap<TabType, Stack<String>> 유형의 tabStacks 인스턴스 변수를 만듭니다. 이제 각 탭마다 하나의 스택을 인스턴스화 할 수 있습니다. 각 스택은 Fragment.getTag()으로 지정된 태그 목록입니다. 이 방법을 사용하면 Fragments에 대한 참조를 저장하는 것에 대해 걱정할 필요가없고 장치를 돌릴 때 사라지는 지 여부를 걱정할 필요가 없습니다. Fragment에 대한 참조가 필요할 때마다 스택에서 오른쪽 태그를 잡고 FragmentManager.findFragmentByTag()을 사용합니다.

이제 언제든지 Fragment을 탭에 푸시하고 싶을 때 새 태그 (UUID.randomUUID().toString()을 사용)를 생성하고 FragmentTransaction.add()으로 전화를 걸 때 사용하십시오. 그런 다음 현재 표시된 탭의 스택 맨 위에 태그를 푸세요. 당신은 이전의 상단에 새로운 조각을 밀어 할 때 FragmentManager가 사라 고려하기 때문에, 예전 remove()을하지 않는, 그것은 정리됩니다

은주의해야합니다. detach()으로 지정하고 나중에 attach()으로 지정하십시오. Fragment을 영구히 터뜨릴 때만 remove()을 사용하고 처음으로 표시하려면 add()을 사용하십시오.

그런 다음 비교적 간단한 로직을 TabListener에 추가해야합니다.탭이 선택되지 않은 경우 스택에 peek(), 연관된 조각은 detatch()입니다. 탭을 선택하면 의 상단이 이고 스택이고 attach() 조각입니다.

마지막으로 오리엔테이션 변경과 같은 활동 라이프 사이클 단점을 처리해야합니다. MapStacks과 현재 선택된 탭으로 유지하고 onCreate()에 다시 포장을 푸십시오. (포장을 풀고 포장을 풀지는 않지만 무료입니다.) 다행히도 TabType 열거 형은 Serializable이므로 Bundle에 넣는 것이 중요합니다.

+1

고맙습니다. 이 문제를 해결하는 데 도움이 된 유일한 답변은 StackOverflow뿐입니다. –

+0

저는 고용주의 의무가 없습니다. 그래서 필요한 모든 코드를 담은 요지를 만들었습니다 : https://gist.github.com/4619215 –