2012-12-06 21 views
0

我发现我认为是FragmentTabHost.java中的一个错误,即使指定了布局,它也总是为tabhost生成新的布局。查看谷歌讨论here更新或覆盖Android支持库中的文件

我想在我的项目中重写这个文件,但是当我将它导入到我的项目中时遇到错误。

有谁知道正确的方式来使用我自己的副本FragmentTabHost.java?

回答

0

你可以使用这个类,然后用这个

public class YourFragmentTabHost extends FragmentTabHost { 

FragmentTabHost.java

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; 

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 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; 
     } 

     @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 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 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); 


    } 
    /** 
    * @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) { 
     super.setup(); 
     mContext = context; 
     mFragmentManager = manager; 
     ensureContent(); 
    } 

    public void setup(Context context, FragmentManager manager, int containerId) { 
     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(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, 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.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.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); 
       } 
      } 
     } 

     // 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.commit(); 
      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) { 
      android.support.v4.app.FragmentTransaction ft = doTabChanged(tabId, null); 
      if (ft != null) { 
       ft.commit(); 
      } 
     } 
     if (mOnTabChangeListener != null) { 
      mOnTabChangeListener.onTabChanged(tabId); 
     } 
    } 

    private FragmentTransaction doTabChanged(String tabId, android.support.v4.app.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); 
       } 
      } 
      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); 
       } 
      } 

      mLastTab = newTab; 
     } 
     return ft; 
    } 
} 
+0

扩展新类。如果你的意思是告诉我使用FragmentTabHost.java创建我的它自己的版本(它扩展TabHost就像FragmentTabHost),那么你绝对是对的。我用我的工作更新了你的代码。扔了FragmentTabHost并扩展TabHost在我自己的。 – jamis0n

+0

是的,正如我所说的答案开始。 “ – Talha