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