简体   繁体   English

使用ViewPageIndicator在SherlockFragment内的Tabhost

[英]Tabhost inside a SherlockFragment using ViewPageIndicator

So I have 3 Sherlock Fragments setup and working fine with ViewPageIndicator. 因此,我设置了3个Sherlock Fragments,并且可以与ViewPageIndicator一起正常工作。 What I'd like to do now is put a TabHost inside one of the Fragments so that it displays 2 separate tabs (at the bottom). 我现在想做的是将TabHost放在Fragments之一中,以便它在底部显示2个单独的选项卡。 I believe this means I need to have 2 more Fragments to put inside the 3rd Fragment controlled by the TabHost. 我相信这意味着我需要再将2个片段放入TabHost控制的第3个片段中。

Considering the TabHost needs to be created inside a Fragment, I'm not sure how to properly create it. 考虑到TabHost需要在Fragment中创建,我不确定如何正确创建它。

Here is the code for the Fragment I've gotten working from this tutorial , which I've tried to update to add the TabHost unsuccessfully: 这是我从本教程开始工作的Fragment的代码,我尝试对其进行更新以成功添加TabHost:

TestFragment3.java TestFragment3.java

public class TestFragment3 extends SherlockFragment {
private String mContent = "none";

public static TestFragment3 newInstance(String text) {
    TestFragment3 fragment = new TestFragment3();

    // Supply num input as an argument.
    Bundle args = new Bundle();
    args.putString(KEY_TAB_NUM, text);
    fragment.setArguments(args);

    return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.activity_main, null);
    String text = getString(R.string.tab_page_num) + mContent;
    ((TextView)view.findViewById(R.id.text)).setText(text);

    return view;
}

@Override
public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   mContent =  getArguments() != null ? getArguments().getString(KEY_TAB_NUM) : "none";
}

}

MainActivity.java MainActivity.java

public class MainActivity extends SherlockFragmentActivity {

private static final String[] TAB_TITLES = new String[] { "This", "Is", "A", "ViewPager" };

TestFragmentAdapter mAdapter;
    ViewPager mPager;
    PageIndicator mIndicator;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.simple_tabs);

    mAdapter = new TestFragmentAdapter(getSupportFragmentManager());

    mPager = (ViewPager)findViewById(R.id.pager);
    mPager.setAdapter(mAdapter);

    mIndicator = (TabPageIndicator)findViewById(R.id.indicator);
    mIndicator.setViewPager(mPager);
}

class TestFragmentAdapter extends FragmentPagerAdapter {     
    private int mCount = TAB_TITLES.length;

    public TestFragmentAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return TestFragment.newInstance(String.valueOf(position));
    }

    @Override
    public int getCount() {
        return mCount;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return TAB_TITLES[position];
    }
}
}

Do I need to create a new SherlockFragmentActivity and add the 2 additional SherlockFragments to that TabHost? 我是否需要创建一个新的SherlockFragmentActivity并将2个其他SherlockFragments添加到该TabHost? If so, how do I setup the MainActivity with 3 Fragments to use another Activity, not a Fragment, for its 3rd Fragment? 如果是这样,我如何设置带有3个片段的MainActivity以将另一个Activity(而不是片段)用于其第3个片段?

I'm getting this error for trying to put a Fragment within a Fragment... 我因尝试将片段放入片段而收到此错误...

11-14 19:10:54.271: E/AndroidRuntime(2812): java.lang.IllegalStateException: Recursive entry to executePendingTransactions
11-14 19:10:54.271: E/AndroidRuntime(2812):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1388)
11-14 19:10:54.271: E/AndroidRuntime(2812):     at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:431)
11-14 19:10:54.271: E/AndroidRuntime(2812):     at com.example.demolistview.EventInviteesFragment$TabManager.onTabChanged(EventInviteesFragment.java:152)
11-14 19:10:54.271: E/AndroidRuntime(2812):     at android.widget.TabHost.invokeOnTabChangeListener(TabHost.java:391)
11-14 19:10:54.271: E/AndroidRuntime(2812):     at android.widget.TabHost.setCurrentTab(TabHost.java:376)
11-14 19:10:54.271: E/AndroidRuntime(2812):     at android.widget.TabHost.addTab(TabHost.java:236)
...
...
...

In regards to this question: 关于这个问题:

Considering the TabHost needs to be created inside a Fragment, I'm not sure how to properly create it. 考虑到TabHost需要在Fragment中创建,我不确定如何正确创建它。

If you look at the latest support demos they have an example of what you are trying to implement. 如果您查看最新的支持演示,则它们提供了您要实现的示例。 They can be downloaded through the SDK Manager. 可以通过SDK Manager下载它们。

This is how they are nesting a tab host within a fragment. 这就是他们在片段中嵌套选项卡宿主的方式。 The setup is using the Child FragmentManager. 安装程序使用子FragmentManager。

public class FragmentTabsFragmentSupport extends Fragment {
    private FragmentTabHost mTabHost;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        mTabHost = new FragmentTabHost(getActivity());
        mTabHost.setup(getActivity(), getChildFragmentManager(), R.id.fragment1);

        mTabHost.addTab(mTabHost.newTabSpec("simple").setIndicator("Simple"),
                FragmentStackSupport.CountingFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("contacts").setIndicator("Contacts"),
                LoaderCursorSupport.CursorLoaderListFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("custom").setIndicator("Custom"),
                LoaderCustomSupport.AppListFragment.class, null);
        mTabHost.addTab(mTabHost.newTabSpec("throttle").setIndicator("Throttle"),
                LoaderThrottleSupport.ThrottledLoaderListFragment.class, null);

        return mTabHost;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        mTabHost = null;
    }
}

I also created a small example which can be found at: https://github.com/marsucsb/nested-fragments 我还创建了一个小示例,可以在以下位置找到: https : //github.com/marsucsb/nested-fragments

Did not tested it, but should be something like this 没有测试过,但是应该是这样的

TabFragment extends SherlockFragment {
TabHost mTabHost;
    TabManager mTabManager;

mTabHost = (TabHost)findViewById(android.R.id.tabhost);
                 mTabHost.setup();

                 mTabManager = new TabManager(this.getActivity(), mTabHost, R.id.realtabcontent);

                 mTabManager.addTab(mTabHost.newTabSpec("first").setIndicator("First", getResources().getDrawable(R.drawable.ic_tab_first_tab)), FirstFragment.class  , null);

                 mTabManager.addTab(mTabHost.newTabSpec("second").setIndicator("Second", getResources().getDrawable(R.drawable.ic_tab_second_tab)), SecondFragment.class  , null);
 public static class TabManager implements TabHost.OnTabChangeListener {
            private final FragmentActivity mActivity;
            private final TabHost mTabHost;
            private final int mContainerId;
            private final HashMap<String, TabInfo> mTabs = new HashMap<String, TabInfo>();
            TabInfo mLastTab;

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


                public View createTabContent(String tag) {
                    View v = new View(mContext);
                    v.setMinimumWidth(0);
                    v.setMinimumHeight(0);
                    return v;
                }
            }

            public TabManager(FragmentActivity activity, TabHost tabHost, int containerId) {
                mActivity = activity;
                mTabHost = tabHost;
                mContainerId = containerId;
                mTabHost.setOnTabChangedListener(this);
            }

            public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
                tabSpec.setContent(new DummyTabFactory(mActivity));
                String tag = tabSpec.getTag();

                TabInfo info = new TabInfo(tag, clss, args);

                // Check to see if we already have a fragment for this tab, probably
                // from a previously saved state.  If so, deactivate it, because our
                // initial state is that a tab isn't shown.
                info.fragment = mActivity.getSupportFragmentManager().findFragmentByTag(tag);
                if (info.fragment != null && !info.fragment.isDetached()) {
                    FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
                    ft.detach(info.fragment);
                    ft.commitAllowingStateLoss();
                }

                mTabs.put(tag, info);
                mTabHost.addTab(tabSpec);
            }


            public void onTabChanged(String tabId) {
                TabInfo newTab = mTabs.get(tabId);
                if (mLastTab != newTab) {
                    FragmentTransaction ft = mActivity.getSupportFragmentManager().beginTransaction();
                    if (mLastTab != null) {
                        if (mLastTab.fragment != null) {
                            ft.detach(mLastTab.fragment);
                        }
                    }
                    if (newTab != null) {
                        if (newTab.fragment == null) {
                            newTab.fragment = Fragment.instantiate(mActivity,
                                    newTab.clss.getName(), newTab.args);
                            ft.add(mContainerId, newTab.fragment, newTab.tag);
                        } else {
                            ft.attach(newTab.fragment);
                        }
                    }

                    mLastTab = newTab;
                    ft.commitAllowingStateLoss();
                    mActivity.getSupportFragmentManager().executePendingTransactions();
                }
            }
        }
}

And your frament layout 还有你的框架布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

<TabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >

     <LinearLayout 
        android:orientation="vertical" 
        android:layout_height="fill_parent"
        android:layout_width="fill_parent">



        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="fill_parent"
            android:layout_weight="1"
            android:layout_height="wrap_content">

        <FrameLayout
            android:id="@+id/realtabcontent"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"/>

        </FrameLayout>

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="fill_parent"
            android:layout_marginBottom="-4dp"
            android:background="#333333" 
            android:layout_height="wrap_content" 
         />


        </LinearLayout>
</TabHost>

</LinearLayout>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM