174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn/*
274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * Copyright (C) 2012 The Android Open Source Project
374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn *
474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * you may not use this file except in compliance with the License.
674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * You may obtain a copy of the License at
774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn *
874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn *
1074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * Unless required by applicable law or agreed to in writing, software
1174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
1274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * See the License for the specific language governing permissions and
1474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * limitations under the License.
1574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn */
1674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
1774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornpackage android.support.v13.app;
1874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
1974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport java.util.ArrayList;
2074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
2174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.app.Fragment;
2274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.app.FragmentManager;
2374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.app.FragmentTransaction;
2474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.content.Context;
2574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.content.res.TypedArray;
2674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.os.Bundle;
2774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.os.Parcel;
2874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.os.Parcelable;
2974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.util.AttributeSet;
3074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.view.View;
3174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.view.ViewGroup;
3274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.widget.FrameLayout;
3374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.widget.LinearLayout;
3474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.widget.TabHost;
3574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornimport android.widget.TabWidget;
3674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
3774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn/**
3874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * Version of {@link android.support.v4.app.FragmentTabHost} that can be
3974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * used with the platform {@link android.app.Fragment} APIs.  You will not
4074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn * normally use this, instead using action bar tabs.
4174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn */
4274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackbornpublic class FragmentTabHost extends TabHost
4374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        implements TabHost.OnTabChangeListener {
4474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
4574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private FrameLayout mRealTabContent;
4674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private Context mContext;
4774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private FragmentManager mFragmentManager;
4874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private int mContainerId;
4974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private TabHost.OnTabChangeListener mOnTabChangeListener;
5074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private TabInfo mLastTab;
5174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private boolean mAttached;
5274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
5374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    static final class TabInfo {
5474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        private final String tag;
5574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        private final Class<?> clss;
5674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        private final Bundle args;
5774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        private Fragment fragment;
5874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
5974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        TabInfo(String _tag, Class<?> _class, Bundle _args) {
6074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            tag = _tag;
6174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            clss = _class;
6274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            args = _args;
6374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
6474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
6574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
6674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    static class DummyTabFactory implements TabHost.TabContentFactory {
6774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        private final Context mContext;
6874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
6974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        public DummyTabFactory(Context context) {
7074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            mContext = context;
7174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
7274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
7374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        @Override
7474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        public View createTabContent(String tag) {
7574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            View v = new View(mContext);
7674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            v.setMinimumWidth(0);
7774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            v.setMinimumHeight(0);
7874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            return v;
7974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
8074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
8174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
8274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    static class SavedState extends BaseSavedState {
8374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        String curTab;
8474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
8574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        SavedState(Parcelable superState) {
8674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            super(superState);
8774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
8874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
8974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        private SavedState(Parcel in) {
9074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            super(in);
9174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            curTab = in.readString();
9274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
9374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
9474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        @Override
9574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        public void writeToParcel(Parcel out, int flags) {
9674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            super.writeToParcel(out, flags);
9774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            out.writeString(curTab);
9874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
9974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
10074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        @Override
10174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        public String toString() {
10274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            return "FragmentTabHost.SavedState{"
10374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    + Integer.toHexString(System.identityHashCode(this))
10474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    + " curTab=" + curTab + "}";
10574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
10674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
10774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        public static final Parcelable.Creator<SavedState> CREATOR
10874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                = new Parcelable.Creator<SavedState>() {
10974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            public SavedState createFromParcel(Parcel in) {
11074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                return new SavedState(in);
11174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
11274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
11374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            public SavedState[] newArray(int size) {
11474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                return new SavedState[size];
11574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
11674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        };
11774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
11874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
11974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    public FragmentTabHost(Context context) {
12074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // Note that we call through to the version that takes an AttributeSet,
12174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // because the simple Context construct can result in a broken object!
12274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        super(context, null);
12374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        initFragmentTabHost(context, null);
12474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
12574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
12674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    public FragmentTabHost(Context context, AttributeSet attrs) {
12774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        super(context, attrs);
12874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        initFragmentTabHost(context, attrs);
12974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
13074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
13174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private void initFragmentTabHost(Context context, AttributeSet attrs) {
13274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        TypedArray a = context.obtainStyledAttributes(attrs,
13374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                new int[] { android.R.attr.inflatedId }, 0, 0);
13474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mContainerId = a.getResourceId(0, 0);
13574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        a.recycle();
13674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
13774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        super.setOnTabChangedListener(this);
13874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
13974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // If owner hasn't made its own view hierarchy, then as a convenience
14074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // we will construct a standard one here.
14174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (findViewById(android.R.id.tabs) == null) {
14274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            LinearLayout ll = new LinearLayout(context);
14374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            ll.setOrientation(LinearLayout.VERTICAL);
14474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            addView(ll, new FrameLayout.LayoutParams(
14574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    ViewGroup.LayoutParams.FILL_PARENT,
14674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    ViewGroup.LayoutParams.FILL_PARENT));
14774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
14874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            TabWidget tw = new TabWidget(context);
14974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            tw.setId(android.R.id.tabs);
15074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            tw.setOrientation(TabWidget.HORIZONTAL);
15174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            ll.addView(tw, new LinearLayout.LayoutParams(
15274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    ViewGroup.LayoutParams.FILL_PARENT,
15374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    ViewGroup.LayoutParams.WRAP_CONTENT, 0));
15474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
15574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            FrameLayout fl = new FrameLayout(context);
15674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            fl.setId(android.R.id.tabcontent);
15774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            ll.addView(fl, new LinearLayout.LayoutParams(0, 0, 0));
15874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
15974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            mRealTabContent = fl = new FrameLayout(context);
16074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            mRealTabContent.setId(mContainerId);
16174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            ll.addView(fl, new LinearLayout.LayoutParams(
16274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    LinearLayout.LayoutParams.FILL_PARENT, 0, 1));
16374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
16474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
16574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
16674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    /**
16774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn     * @deprecated Don't call the original TabHost setup, you must instead
16874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn     * call {@link #setup(Context, FragmentManager)} or
16974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn     * {@link #setup(Context, FragmentManager, int)}.
17074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn     */
17174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    @Override @Deprecated
17274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    public void setup() {
17374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        throw new IllegalStateException(
17474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                "Must call setup() that takes a Context and FragmentManager");
17574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
17674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
17774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    public void setup(Context context, FragmentManager manager) {
17874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        super.setup();
17974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mContext = context;
18074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mFragmentManager = manager;
18174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        ensureContent();
18274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
18374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
18474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    public void setup(Context context, FragmentManager manager, int containerId) {
18574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        super.setup();
18674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mContext = context;
18774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mFragmentManager = manager;
18874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mContainerId = containerId;
18974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        ensureContent();
19074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mRealTabContent.setId(containerId);
19174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
19274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // We must have an ID to be able to save/restore our state.  If
19374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // the owner hasn't set one at this point, we will set it ourself.
19474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (getId() == View.NO_ID) {
19574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            setId(android.R.id.tabhost);
19674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
19774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
19874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
19974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private void ensureContent() {
20074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (mRealTabContent == null) {
20174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            mRealTabContent = (FrameLayout)findViewById(mContainerId);
20274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            if (mRealTabContent == null) {
20374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                throw new IllegalStateException(
20474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                        "No tab content FrameLayout found for id " + mContainerId);
20574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
20674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
20774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
20874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
20974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    @Override
21074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    public void setOnTabChangedListener(OnTabChangeListener l) {
21174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mOnTabChangeListener = l;
21274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
21374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
21474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
21574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        tabSpec.setContent(new DummyTabFactory(mContext));
21674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        String tag = tabSpec.getTag();
21774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
21874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        TabInfo info = new TabInfo(tag, clss, args);
21974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
22074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (mAttached) {
22174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            // If we are already attached to the window, then check to make
22274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            // sure this tab's fragment is inactive if it exists.  This shouldn't
22374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            // normally happen.
22474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            info.fragment = mFragmentManager.findFragmentByTag(tag);
22574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            if (info.fragment != null && !info.fragment.isDetached()) {
22674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                FragmentTransaction ft = mFragmentManager.beginTransaction();
22774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                ft.detach(info.fragment);
22874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                ft.commit();
22974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
23074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
23174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
23274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mTabs.add(info);
23374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        addTab(tabSpec);
23474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
23574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
23674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    @Override
23774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    protected void onAttachedToWindow() {
23874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        super.onAttachedToWindow();
23974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
24074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        String currentTab = getCurrentTabTag();
24174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
24274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // Go through all tabs and make sure their fragments match
24374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // the correct state.
24474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        FragmentTransaction ft = null;
24574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        for (int i=0; i<mTabs.size(); i++) {
24674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            TabInfo tab = mTabs.get(i);
24774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            tab.fragment = mFragmentManager.findFragmentByTag(tab.tag);
24874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            if (tab.fragment != null && !tab.fragment.isDetached()) {
24974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                if (tab.tag.equals(currentTab)) {
25074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    // The fragment for this tab is already there and
25174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    // active, and it is what we really want to have
25274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    // as the current tab.  Nothing to do.
25374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    mLastTab = tab;
25474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                } else {
25574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    // This fragment was restored in the active state,
25674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    // but is not the current tab.  Deactivate it.
25774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    if (ft == null) {
25874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                        ft = mFragmentManager.beginTransaction();
25974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    }
26074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    ft.detach(tab.fragment);
26174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                }
26274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
26374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
26474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
26574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // We are now ready to go.  Make sure we are switched to the
26674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        // correct tab.
26774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mAttached = true;
26874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        ft = doTabChanged(currentTab, ft);
26974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (ft != null) {
27074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            ft.commit();
27174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            mFragmentManager.executePendingTransactions();
27274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
27374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
27474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
27574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    @Override
27674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    protected void onDetachedFromWindow() {
27774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        super.onDetachedFromWindow();
27874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        mAttached = false;
27974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
28074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
28174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    @Override
28274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    protected Parcelable onSaveInstanceState() {
28374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        Parcelable superState = super.onSaveInstanceState();
28474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        SavedState ss = new SavedState(superState);
28574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        ss.curTab = getCurrentTabTag();
28674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        return ss;
28774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
28874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
28974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    @Override
29074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    protected void onRestoreInstanceState(Parcelable state) {
29174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        SavedState ss = (SavedState)state;
29274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        super.onRestoreInstanceState(ss.getSuperState());
29374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        setCurrentTabByTag(ss.curTab);
29474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
29574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
29674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    @Override
29774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    public void onTabChanged(String tabId) {
29874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (mAttached) {
29974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            FragmentTransaction ft = doTabChanged(tabId, null);
30074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            if (ft != null) {
30174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                ft.commit();
30274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
30374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
30474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (mOnTabChangeListener != null) {
30574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            mOnTabChangeListener.onTabChanged(tabId);
30674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
30774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
30874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
30974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
31074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        TabInfo newTab = null;
31174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        for (int i=0; i<mTabs.size(); i++) {
31274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            TabInfo tab = mTabs.get(i);
31374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            if (tab.tag.equals(tabId)) {
31474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                newTab = tab;
31574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
31674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
31774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (newTab == null) {
31874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            throw new IllegalStateException("No tab known for tag " + tabId);
31974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
32074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        if (mLastTab != newTab) {
32174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            if (ft == null) {
32274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                ft = mFragmentManager.beginTransaction();
32374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
32474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            if (mLastTab != null) {
32574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                if (mLastTab.fragment != null) {
32674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    ft.detach(mLastTab.fragment);
32774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                }
32874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
32974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            if (newTab != null) {
33074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                if (newTab.fragment == null) {
33174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    newTab.fragment = Fragment.instantiate(mContext,
33274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                            newTab.clss.getName(), newTab.args);
33374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    ft.add(mContainerId, newTab.fragment, newTab.tag);
33474c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                } else {
33574c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                    ft.attach(newTab.fragment);
33674c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn                }
33774c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            }
33874c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn
33974c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn            mLastTab = newTab;
34074c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        }
34174c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn        return ft;
34274c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn    }
34374c671b3b67000bf16b4865a8d361344310dccbeDianne Hackborn}
344