• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.example.android.supportv4.app;
17 
18 //BEGIN_INCLUDE(complete)
19 import java.util.HashMap;
20 
21 import com.example.android.supportv4.R;
22 
23 import android.content.Context;
24 import android.os.Bundle;
25 import android.support.v4.app.Fragment;
26 import android.support.v4.app.FragmentActivity;
27 import android.support.v4.app.FragmentTransaction;
28 import android.view.View;
29 import android.widget.TabHost;
30 
31 /**
32  * This demonstrates how you can implement switching between the tabs of a
33  * TabHost through fragments.  It uses a trick (see the code below) to allow
34  * the tabs to switch between fragments instead of simple views.
35  */
36 public class FragmentTabs extends FragmentActivity {
37     TabHost mTabHost;
38     TabManager mTabManager;
39 
40     @Override
onCreate(Bundle savedInstanceState)41     protected void onCreate(Bundle savedInstanceState) {
42         super.onCreate(savedInstanceState);
43 
44         setContentView(R.layout.fragment_tabs);
45         mTabHost = (TabHost)findViewById(android.R.id.tabhost);
46         mTabHost.setup();
47 
48         mTabManager = new TabManager(this, mTabHost, R.id.realtabcontent);
49 
50         mTabManager.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
51                 FragmentStackSupport.CountingFragment.class, null);
52         mTabManager.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
53                 LoaderCursorSupport.CursorLoaderListFragment.class, null);
54         mTabManager.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
55                 LoaderCustomSupport.AppListFragment.class, null);
56         mTabManager.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
57                 LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);
58 
59         if (savedInstanceState != null) {
60             mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
61         }
62     }
63 
64     @Override
onSaveInstanceState(Bundle outState)65     protected void onSaveInstanceState(Bundle outState) {
66         super.onSaveInstanceState(outState);
67         outState.putString("tab", mTabHost.getCurrentTabTag());
68     }
69 
70     /**
71      * This is a helper class that implements a generic mechanism for
72      * associating fragments with the tabs in a tab host.  It relies on a
73      * trick.  Normally a tab host has a simple API for supplying a View or
74      * Intent that each tab will show.  This is not sufficient for switching
75      * between fragments.  So instead we make the content part of the tab host
76      * 0dp high (it is not shown) and the TabManager supplies its own dummy
77      * view to show as the tab content.  It listens to changes in tabs, and takes
78      * care of switch to the correct fragment shown in a separate content area
79      * whenever the selected tab changes.
80      */
81     public static class TabManager implements TabHost.OnTabChangeListener {
82         private final FragmentActivity mActivity;
83         private final TabHost mTabHost;
84         private final int mContainerId;
85         private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>();
86         TabInfo mLastTab;
87 
88         static final class TabInfo {
89             private final String tag;
90             private final Class<?> clss;
91             private final Bundle args;
92             private Fragment fragment;
93 
TabInfo(String _tag, Class<?> _class, Bundle _args)94             TabInfo(String _tag, Class<?> _class, Bundle _args) {
95                 tag = _tag;
96                 clss = _class;
97                 args = _args;
98             }
99         }
100 
101         static class DummyTabFactory implements TabHost.TabContentFactory {
102             private final Context mContext;
103 
DummyTabFactory(Context context)104             public DummyTabFactory(Context context) {
105                 mContext = context;
106             }
107 
108             @Override
createTabContent(String tag)109             public View createTabContent(String tag) {
110                 View v = new View(mContext);
111                 v.setMinimumWidth(0);
112                 v.setMinimumHeight(0);
113                 return v;
114             }
115         }
116 
TabManager(FragmentActivity activity, TabHost tabHost, int containerId)117         public TabManager(FragmentActivity activity, TabHost tabHost, int containerId) {
118             mActivity = activity;
119             mTabHost = tabHost;
120             mContainerId = containerId;
121             mTabHost.setOnTabChangedListener(this);
122         }
123 
addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args)124         public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
125             tabSpec.setContent(new DummyTabFactory(mActivity));
126             String tag = tabSpec.getTag();
127 
128             TabInfo info = new TabInfo(tag, clss, args);
129 
130             // Check to see if we already have a fragment for this tab, probably
131             // from a previously saved state.  If so, deactivate it, because our
132             // initial state is that a tab isn't shown.
133             info.fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag);
134             if (info.fragment != null && !info.fragment.isDetached()) {
135                 FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
136                 ft.detach(info.fragment);
137                 ft.commit();
138             }
139 
140             mTabs.put(tag, info);
141             mTabHost.addTab(tabSpec);
142         }
143 
144         @Override
onTabChanged(String tabId)145         public void onTabChanged(String tabId) {
146             TabInfo newTab = mTabs.get(tabId);
147             if (mLastTab != newTab) {
148                 FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
149                 if (mLastTab != null) {
150                     if (mLastTab.fragment != null) {
151                         ft.detach(mLastTab.fragment);
152                     }
153                 }
154                 if (newTab != null) {
155                     if (newTab.fragment == null) {
156                         newTab.fragment = Fragment.instantiate(mActivity,
157                                 newTab.clss.getName(), newTab.args);
158                         ft.add(mContainerId, newTab.fragment, newTab.tag);
159                     } else {
160                         ft.attach(newTab.fragment);
161                     }
162                 }
163 
164                 mLastTab = newTab;
165                 ft.commit();
166                 mActivity.getSupportFragmentManager().executePendingTransactions();
167             }
168         }
169     }
170 }
171 //END_INCLUDE(complete)
172