android– 自定义FragmentTabHost的实现

android– 自定义FragmentTabHost的实现,第1张

概述我正在使用新的API17在我的应用程序中实现嵌套片段,它提供了一个FragmentTabHost.但是,对于父片段中的简单2选项卡片段,我遇到了一些基本问题:>我希望嵌套的标签位于底部(View1和View2标签)>我想自定义实际标签,看起来与标准不同有没有人曾经使用过这些并知道如何实现这一目标?这

我正在使用新的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的实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1106251.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-28
下一篇 2022-05-28

发表评论

登录后才能评论

评论列表(0条)

保存