FragmentTabsPager.java revision aefd2819f5d9f972a6c6dc33a3c66d6d2891d4e8
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 */
16package com.example.android.supportv4.app;
17
18import java.util.ArrayList;
19
20import com.example.android.supportv4.R;
21
22import android.content.Context;
23import android.os.Bundle;
24import android.support.v4.app.Fragment;
25import android.support.v4.app.FragmentActivity;
26import android.support.v4.app.FragmentPagerAdapter;
27import android.support.v4.view.ViewPager;
28import android.view.View;
29import android.widget.TabHost;
30
31/**
32 * Demonstrates combining a TabHost with a ViewPager to implement a tab UI
33 * that switches between tabs and also allows the user to perform horizontal
34 * flicks to move between the tabs.
35 */
36public class FragmentTabsPager extends FragmentActivity {
37    TabHost mTabHost;
38    ViewPager  mViewPager;
39    TabsAdapter mTabsAdapter;
40
41    @Override
42    protected void onCreate(Bundle savedInstanceState) {
43        super.onCreate(savedInstanceState);
44
45        setContentView(R.layout.fragment_tabs_pager);
46        mTabHost = (TabHost)findViewById(android.R.id.tabhost);
47        mTabHost.setup();
48
49        mViewPager = (ViewPager)findViewById(R.id.pager);
50
51        mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
52
53        mTabsAdapter.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
54                FragmentStackSupport.CountingFragment.class, null);
55        mTabsAdapter.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
56                LoaderCursorSupport.CursorLoaderListFragment.class, null);
57        mTabsAdapter.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
58                LoaderCustomSupport.AppListFragment.class, null);
59        mTabsAdapter.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
60                LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);
61
62        if (savedInstanceState != null) {
63            mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
64        }
65    }
66
67    @Override
68    protected void onSaveInstanceState(Bundle outState) {
69        super.onSaveInstanceState(outState);
70        outState.putString("tab", mTabHost.getCurrentTabTag());
71    }
72
73    /**
74     * This is a helper class that implements the management of tabs and all
75     * details of connecting a ViewPager with associated TabHost.  It relies on a
76     * trick.  Normally a tab host has a simple API for supplying a View or
77     * Intent that each tab will show.  This is not sufficient for switching
78     * between pages.  So instead we make the content part of the tab host
79     * 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
80     * view to show as the tab content.  It listens to changes in tabs, and takes
81     * care of switch to the correct paged in the ViewPager whenever the selected
82     * tab changes.
83     */
84    public static class TabsAdapter extends FragmentPagerAdapter
85            implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
86        private final Context mContext;
87        private final TabHost mTabHost;
88        private final ViewPager mViewPager;
89        private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
90
91        static final class TabInfo {
92            private final String tag;
93            private final Class<?> clss;
94            private final Bundle args;
95
96            TabInfo(String _tag, Class<?> _class, Bundle _args) {
97                tag = _tag;
98                clss = _class;
99                args = _args;
100            }
101        }
102
103        static class DummyTabFactory implements TabHost.TabContentFactory {
104            private final Context mContext;
105
106            public DummyTabFactory(Context context) {
107                mContext = context;
108            }
109
110            @Override
111            public View createTabContent(String tag) {
112                View v = new View(mContext);
113                v.setMinimumWidth(0);
114                v.setMinimumHeight(0);
115                return v;
116            }
117        }
118
119        public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
120            super(activity.getSupportFragmentManager());
121            mContext = activity;
122            mTabHost = tabHost;
123            mViewPager = pager;
124            mTabHost.setOnTabChangedListener(this);
125            mViewPager.setAdapter(this);
126            mViewPager.setOnPageChangeListener(this);
127        }
128
129        public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
130            tabSpec.setContent(new DummyTabFactory(mContext));
131            String tag = tabSpec.getTag();
132
133            TabInfo info = new TabInfo(tag, clss, args);
134            mTabs.add(info);
135            mTabHost.addTab(tabSpec);
136            notifyDataSetChanged();
137        }
138
139        @Override
140        public int getCount() {
141            return mTabs.size();
142        }
143
144        @Override
145        public Fragment getItem(int position) {
146            TabInfo info = mTabs.get(position);
147            return Fragment.instantiate(mContext, info.clss.getName(), info.args);
148        }
149
150        @Override
151        public void onTabChanged(String tabId) {
152            int position = mTabHost.getCurrentTab();
153            mViewPager.setCurrentItem(position);
154        }
155
156        @Override
157        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
158        }
159
160        @Override
161        public void onPageSelected(int position) {
162            mTabHost.setCurrentTab(position);
163        }
164    }
165}
166