Recently to do a similar to the bottom of the QQ bubble function, try a few programs are not very good, I think many developers use tabhost will know that it does not save the state, each time to reload the layout, in order to save the state, using Radiogroup to achieve, the state can be saved, the problem is unable to implement the bubble function , cannot customize the layout, because the radiogroup inside can only contain RadioButton, otherwise the state switch not to use as, this can view Radiogroup source code, in order to save the state and can realize the bubble function, So you can only modify the control itself or write a similar switching function, view the source code of Fragmenttabhost, You can know that Fragmenttabhost does not save the state is because the switch fragment when the use of detach and attach to fragment the hidden and display, so that each switch must reload the layout, processing the use of detach and Attach, we can also use show and hide to achieve the display and hiding, so that can save the state, the solution is to modify the Fragmenttabhost source code will switch fragment way detach and attach changed to hide and show.
The following is the revised fragmenttabhost source code:
/* Copyright (C) The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License") ; * You are not a use this file except in compliance with the License. * Obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * unless required by appli Cable law or agreed into writing, software * Distributed under the License is distributed on a "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. */package Com.jwzhangjie.com;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} objec TS for it tab * content. When placing the "a" view hierarchy, after inflating the hierarchy * your must call {@link #setup (Context, Fragmentmanage R, Int)} to complete the * Initialization of the TAB host. * * <p> * Here's a simple example of using a fragmenttabhost in an Activity: * * {@sample * development/samples/s upport4demos/src/com/example/android/supportv4/app/* Fragmenttabs.java Complete} * * <p> * The can also be used I Nside of a fragment through fragment nesting: * * {@sample * development/samples/support4demos/src/com/example/android/su pportv4/app/* Fragmenttabsfragmentsupport.java Complete} */public class Fragmenttabhost extends Tabhost Implementstabhost.ontabchangelistener {private final arraylist<tabinfo> mtabs = new ArraYlist<tabinfo> ();p rivate framelayout mrealtabcontent;private Context mcontext;private FragmentManager mfragmentmanager;private int mcontainerid;private Tabhost.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 Tabhost.tabcontentfactory {private final Context mcontext;public Dummytabfactory (Context context) {Mcontext = context;} @Overridepublic 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 ();} @Overridepublic void WritetopArcel (Parcel out, int flags) {Super.writetoparcel (out, flags); out.writestring (Curtab);} @Overridepublic String toString () {return ' fragmenttabhost.savedstate{' + integer.tohexstring ( System.identityhashcode (this)) + "curtab=" + Curtab + "}";} public static final parcelable.creator<savedstate> Creator = new parcelable.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 this through to the version of 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 Would construct a standard one here.if (Findviewbyid (Android. r.id.tabs) = = null) {LinearLayout LL = new LinearLayout (context); ll.setorientation (linearlayout.vertical); AddView (LL, New Framelayout.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, Fragme Ntmanager)} or * {@link #setup (Context, Fragmentmanager, int)}. */@Override @deprecatedpublic void Setup () {throw new IllegalStateException ("Must call Setup () takes a Context and Fra Gmentmanager ");} public void Setup (context context, Fragmentmanager Manager) {ensurehierarchy (context);//ensure views required by SUPER.S Etup () Super.setup (); mcontext = Context;mfragmentmanager = Manager;ensurecontent ();} public void Setup (context context, Fragmentmanager Manager, int. Containerid) {ensurehierarchy (context);//ensure views re Quired by Super.setup () Super.setup (); mcontext = Context;mfragmentmanager = Manager;mcontainerid = ContainerId; Ensurecontent (); Mrealtabcontent.setid (Containerid);//We must have a ID to is able to save/restore our state. if//the owner hasn ' t set one at this point, we'll 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);} }} @Overridepublic void Setontabchangedlistener (Ontabchangelistener l) {montabchangelistener = l;} public void AddTab (Tabhost.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 and then check to MAK e//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);} @Overrideprotected 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 = Mfragme Ntmanager.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, we really want to have//as the current tab. Nothing to Do.mlasttab = tab;} else {//This fragment were restored in the active state,//and 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 is switched to the//correct tab.mattached = true;ft = dotabchanged (currEnttab, FT); if (ft! = null) {ft.commit (); Mfragmentmanager.executependingtransactions ();}} @Overrideprotected void Ondetachedfromwindow () {Super.ondetachedfromwindow (); mattached = false;} @Overrideprotected parcelable onsaveinstancestate () {parcelable superstate = super.onsaveinstancestate (); savedstate ss = new savedstate (superstate); ss.curtab = Getcurrenttabtag (); return SS;} @Overrideprotected void Onrestoreinstancestate (parcelable state) {savedstate SS = (savedstate) state; Super.onrestoreinstancestate (Ss.getsuperstate ()); Setcurrenttabbytag (Ss.curtab);} @Overridepublic void ontabchanged (String tabId) {if (mattached) {fragmenttransaction ft = dotabchanged (tabId, NULL); if (f T! = 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;}}
<a target=_blank href= "http://download.csdn.net/download/jwzhangjie/7561781" ><span style= "font-size:24px ;" > This is a demo</span></a>