自定义的FragmentTabHost,保存fragment实例不销毁

来源:互联网 发布:mysql配置参数详解 编辑:程序博客网 时间:2024/06/05 09:53

如题,由于android.support.v4.app.FragmentTabHost不会保存fragment ,
故自定义FragmentTabHost,保存fragment实例不销毁,用的话直接拷贝代码即可

package com.zccfocusing.widget;/** * Created by monkey * on 2014/9/24 * 功能描述:修改过的FragmentTabHost,保存fragment实例不销毁 *//* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */import java.util.ArrayList;import android.content.Context;import android.content.res.TypedArray;import android.os.Bundle;import android.os.Parcel;import android.os.Parcelable;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.LinearLayout;import android.widget.TabHost;import android.widget.TabWidget;/** * Special TabHost that allows the use of {@link Fragment} objects for its tab * content. When placing this in a view hierarchy, after inflating the hierarchy * you must call {@link #setup(Context, FragmentManager, int)} to complete the * initialization of the tab host. * <p> * <p> * Here is a simple example of using a FragmentTabHost in an Activity: * <p> * {@sample * development/samples/Support4Demos/src/com/example/android/supportv4/app/ * FragmentTabs.java complete} * <p> * <p> * This can also be used inside of a fragment through fragment nesting: * <p> * {@sample * development/samples/Support4Demos/src/com/example/android/supportv4/app/ * FragmentTabsFragmentSupport.java complete} */public class FragmentTabHost extends TabHost implements        TabHost.OnTabChangeListener {    private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();    private FrameLayout mRealTabContent;    private Context mContext;    private FragmentManager mFragmentManager;    private int mContainerId;    private OnTabChangeListener mOnTabChangeListener;    private TabInfo mLastTab;    private boolean mAttached;    static final class TabInfo {        private final String tag;        private final Class<?> clss;        private final Bundle args;        private Fragment fragment;        TabInfo(String _tag, Class<?> _class, Bundle _args) {            tag = _tag;            clss = _class;            args = _args;        }    }    static class DummyTabFactory implements TabContentFactory {        private final Context mContext;        public DummyTabFactory(Context context) {            mContext = context;        }        @Override        public View createTabContent(String tag) {            View v = new View(mContext);            v.setMinimumWidth(0);            v.setMinimumHeight(0);            return v;        }    }    static class SavedState extends BaseSavedState {        String curTab;        SavedState(Parcelable superState) {            super(superState);        }        private SavedState(Parcel in) {            super(in);            curTab = in.readString();        }        @Override        public void writeToParcel(Parcel out, int flags) {            super.writeToParcel(out, flags);            out.writeString(curTab);        }        @Override        public String toString() {            return "FragmentTabHost.SavedState{"                    + Integer.toHexString(System.identityHashCode(this))                    + " curTab=" + curTab + "}";        }        public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {            public SavedState createFromParcel(Parcel in) {                return new SavedState(in);            }            public SavedState[] newArray(int size) {                return new SavedState[size];            }        };    }    public FragmentTabHost(Context context) {        // Note that we call through to the version that takes an AttributeSet,        // because the simple Context construct can result in a broken object!        super(context, null);        initFragmentTabHost(context, null);    }    public FragmentTabHost(Context context, AttributeSet attrs) {        super(context, attrs);        initFragmentTabHost(context, attrs);    }    private void initFragmentTabHost(Context context, AttributeSet attrs) {        TypedArray a = context.obtainStyledAttributes(attrs,                new int[]{android.R.attr.inflatedId}, 0, 0);        mContainerId = a.getResourceId(0, 0);        a.recycle();        super.setOnTabChangedListener(this);    }    private void ensureHierarchy(Context context) {        // If owner hasn't made its own view hierarchy, then as a convenience        // we will construct a standard one here.        if (findViewById(android.R.id.tabs) == null) {            LinearLayout ll = new LinearLayout(context);            ll.setOrientation(LinearLayout.VERTICAL);            addView(ll, new LayoutParams(                    ViewGroup.LayoutParams.MATCH_PARENT,                    ViewGroup.LayoutParams.MATCH_PARENT));            TabWidget tw = new TabWidget(context);            tw.setId(android.R.id.tabs);            tw.setOrientation(TabWidget.HORIZONTAL);            ll.addView(tw, new LinearLayout.LayoutParams(                    ViewGroup.LayoutParams.MATCH_PARENT,                    ViewGroup.LayoutParams.WRAP_CONTENT, 0));            FrameLayout fl = new FrameLayout(context);            fl.setId(android.R.id.tabcontent);            ll.addView(fl, new LinearLayout.LayoutParams(0, 0, 0));            mRealTabContent = fl = new FrameLayout(context);            mRealTabContent.setId(mContainerId);            ll.addView(fl, new LinearLayout.LayoutParams(                    LinearLayout.LayoutParams.MATCH_PARENT, 0, 1));        }    }    /**     * @deprecated Don't call the original TabHost setup, you must instead call     * {@link #setup(Context, FragmentManager)} or     * {@link #setup(Context, FragmentManager, int)}.     */    @Override    @Deprecated    public void setup() {        throw new IllegalStateException(                "Must call setup() that takes a Context and FragmentManager");    }    public void setup(Context context, FragmentManager manager) {        ensureHierarchy(context); // Ensure views required by super.setup()        super.setup();        mContext = context;        mFragmentManager = manager;        ensureContent();    }    public void setup(Context context, FragmentManager manager, int containerId) {        ensureHierarchy(context); // Ensure views required by super.setup()        super.setup();        mContext = context;        mFragmentManager = manager;        mContainerId = containerId;        ensureContent();        mRealTabContent.setId(containerId);        // We must have an ID to be able to save/restore our state. If        // the owner hasn't set one at this point, we will set it ourself.        if (getId() == View.NO_ID) {            setId(android.R.id.tabhost);        }    }    private void ensureContent() {        if (mRealTabContent == null) {            mRealTabContent = (FrameLayout) findViewById(mContainerId);            if (mRealTabContent == null) {                throw new IllegalStateException(                        "No tab content FrameLayout found for id "                                + mContainerId);            }        }    }    @Override    public void setOnTabChangedListener(OnTabChangeListener l) {        mOnTabChangeListener = l;    }    public void addTab(TabSpec tabSpec, Class<?> clss, Bundle args) {        tabSpec.setContent(new DummyTabFactory(mContext));        String tag = tabSpec.getTag();        TabInfo info = new TabInfo(tag, clss, args);        if (mAttached) {            // If we are already attached to the window, then check to make            // sure this tab's fragment is inactive if it exists. This shouldn't            // normally happen.            info.fragment = mFragmentManager.findFragmentByTag(tag);            if (info.fragment != null && !info.fragment.isDetached()) {                FragmentTransaction ft = mFragmentManager.beginTransaction();//              ft.detach(info.fragment);                ft.hide(info.fragment);                ft.commit();            }        }        mTabs.add(info);        addTab(tabSpec);    }    @Override    protected void onAttachedToWindow() {        super.onAttachedToWindow();        String currentTab = getCurrentTabTag();        // Go through all tabs and make sure their fragments match        // the correct state.        FragmentTransaction ft = null;        for (int i = 0; i < mTabs.size(); i++) {            TabInfo tab = mTabs.get(i);            tab.fragment = mFragmentManager.findFragmentByTag(tab.tag);//          if (tab.fragment != null && !tab.fragment.isDetached()) {            if (tab.fragment != null) {                if (tab.tag.equals(currentTab)) {                    // The fragment for this tab is already there and                    // active, and it is what we really want to have                    // as the current tab. Nothing to do.                    mLastTab = tab;                } else {                    // This fragment was restored in the active state,                    // but is not the current tab. Deactivate it.                    if (ft == null) {                        ft = mFragmentManager.beginTransaction();                    }//                  ft.detach(tab.fragment);                    ft.hide(tab.fragment);                }            }        }        // We are now ready to go. Make sure we are switched to the        // correct tab.        mAttached = true;        ft = doTabChanged(currentTab, ft);        if (ft != null) {            ft.commitAllowingStateLoss();            mFragmentManager.executePendingTransactions();        }    }    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        mAttached = false;    }    @Override    protected Parcelable onSaveInstanceState() {        Parcelable superState = super.onSaveInstanceState();        SavedState ss = new SavedState(superState);        ss.curTab = getCurrentTabTag();        return ss;    }    @Override    protected void onRestoreInstanceState(Parcelable state) {        SavedState ss = (SavedState) state;        super.onRestoreInstanceState(ss.getSuperState());        setCurrentTabByTag(ss.curTab);    }    @Override    public void onTabChanged(String tabId) {        if (mAttached) {            FragmentTransaction ft = doTabChanged(tabId, null);            if (ft != null) {                ft.commit();            }        }        if (mOnTabChangeListener != null) {            mOnTabChangeListener.onTabChanged(tabId);        }    }    private FragmentTransaction doTabChanged(String tabId,                                             FragmentTransaction ft) {        TabInfo newTab = null;        for (int i = 0; i < mTabs.size(); i++) {            TabInfo tab = mTabs.get(i);            if (tab.tag.equals(tabId)) {                newTab = tab;            }        }        if (newTab == null) {            throw new IllegalStateException("No tab known for tag " + tabId);        }        if (mLastTab != newTab) {            if (ft == null) {                ft = mFragmentManager.beginTransaction();            }            if (mLastTab != null) {                if (mLastTab.fragment != null) {//                  ft.detach(mLastTab.fragment);                    ft.hide(mLastTab.fragment);                }            }            if (newTab != null) {                if (newTab.fragment == null) {                    newTab.fragment = Fragment.instantiate(mContext,                            newTab.clss.getName(), newTab.args);                    ft.add(mContainerId, newTab.fragment, newTab.tag);                } else {//                  ft.attach(newTab.fragment);                    ft.show(newTab.fragment);                }            }            mLastTab = newTab;        }        return ft;    }}
1 0
原创粉丝点击