我正在使用新的API 17在我的应用程序中实现嵌套片段,它提供了一个FragmentTabHost.但是,对于父片段中的简单2选项卡片段,我遇到了一些基本问题:
>我希望嵌套的标签位于底部(VIEw1和VIEw2标签)
>我想自定义实际标签,看起来与标准不同
有没有人曾经使用过这些并知道如何实现这一目标?这是我已启动并运行的示例代码:
import androID.os.Bundle;import androID.support.v4.app.Fragment;import androID.support.v4.app.FragmentTabHost;import androID.vIEw.LayoutInflater;import androID.vIEw.VIEw;import androID.vIEw.VIEwGroup;public class FragmentTabsFragmentSupport extends Fragment {private FragmentTabHost mTabHost;@OverrIDepublic VIEw onCreateVIEw(LayoutInflater inflater, VIEwGroup container, Bundle savedInstanceState) { mTabHost = new FragmentTabHost(getActivity()); mTabHost.setup(getActivity(), getChildFragmentManager(), R.ID.fragment1); mTabHost.addTab(mTabHost.newTabSpec("Tab1").setIndicator("Simple"), nestedFragment1.class, null); mTabHost.addTab(mTabHost.newTabSpec("Tab2").setIndicator("Contacts"), nestedFragment2.class, null); return mTabHost;}@OverrIDepublic voID onDestroyVIEw() { super.onDestroyVIEw(); mTabHost = null;}}
我已经尝试了下面的底部对齐标签,但没有运气:
TabWidget mTabWidget = mTabHost.getTabWidget();mTabWidget.setGravity(Gravity.BottOM);mTabWidget.setVerticalGravity(Gravity.BottOM);
解决方法:
我终于到底了. FragmentTabHost.java存在一个问题,它总是为您创建一个TabHost元素,无论您在XML中定义什么并事先膨胀.
因此,在编写自己的FragmentTabHost.java版本时,我注释掉了部分代码.
确保在XML布局中使用此新版本,< com.example.app.MyFragmentTabHost当然要夸大它:Fragment1.java:
mTabHost = (MyFragmentTabHost) vIEw.findVIEwByID(androID.R.ID.tabhost);mTabHost.setup(getActivity(), getChildFragmentManager(), androID.R.ID.tabcontent);
MyFragmentTabHost.java:
package com.example.app;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.Widget.FrameLayout;import androID.Widget.TabHost;/** * 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. * */public class MyFragmentTabHost 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 MyFragmentTabHost(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 MyFragmentTabHost(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); /*** REMOVE THE REST OF THIS FUNCTION ***/ /*** findVIEwByID(androID.R.ID.tabs) IS NulL EVERY TIME ***/}/** * @deprecated Don't call the original TabHost setup, you must instead * call {@link #setup(Context, FragmentManager)} or * {@link #setup(Context, FragmentManager, int)}. */@OverrIDe @Deprecatedpublic 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); } }}@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, 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);}@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 = 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(); }}@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 (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); } } 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;}}
总结 以上是内存溢出为你收集整理的android – 自定义FragmentTabHost的实现全部内容,希望文章能够帮你解决android – 自定义FragmentTabHost的实现所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)