如何在同一个标​​签中切换片段?

时间:2012-11-28 18:13:28

标签: android android-fragments android-tabs

我的小应用程序具有以下基本结构(tabhost中的2个选项卡):

Main(扩展FragmentActivity) HomeFragment(扩展片段) ConfigFragment(扩展片段)

有时(当用户点击菜单时)我需要显示其他片段(GraphicFragment)而不是HomeFragment。当我在GraphicFragment并使用后退按钮(或菜单项Home)时,该选项卡将再次显示片段HomeFragment。

怎么做?

main.xml(布局):

<TabHost
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

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

        <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0" />

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0" />

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

    </LinearLayout>

</TabHost>

Main.java:

public class Main扩展FragmentActivity {

private TabHost mTabHost;
private ViewPager mViewPager;
private HashMap<String, TabInfo> mapTabInfo = new HashMap<String, Main.TabInfo>();
private PagerAdapter mPagerAdapter;
private Config config;

private class TabInfo {

    private String tag;
    @SuppressWarnings("unused")
    private Class<?> clss;
    @SuppressWarnings("unused")
    private Bundle args;

    TabInfo(String tag, Class<?> clazz, Bundle args) {
        this.tag = tag;
        this.clss = clazz;
        this.args = args;
    }

}

private class TabFactory implements TabContentFactory {

    private final Context mContext;

    public TabFactory(Context context) {
        mContext = context;
    }

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

}   

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);      

    initializeTabHost(savedInstanceState);
    if (savedInstanceState != null) {
        mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
    }

    intializeViewPager();

    config = Config.GetInstance();
    config.setContext(getApplicationContext());     
}

private void initializeTabHost(Bundle args){
    mTabHost = (TabHost)findViewById(android.R.id.tabhost);
    mTabHost.setup();

    TabInfo tabInfo = null;

    Main.addTab(
        this,
        mTabHost,
        mTabHost.newTabSpec("Home").setIndicator("Home"),
        (tabInfo = new TabInfo("Home", HomeFragment.class, args)));
    mapTabInfo.put(tabInfo.tag, tabInfo);

    Main.addTab(
        this,
        mTabHost,
        mTabHost.newTabSpec("Config").setIndicator("Config"),
        (tabInfo = new TabInfo("Config", ConfigFragment.class, args)));
    mapTabInfo.put(tabInfo.tag, tabInfo);        

    mTabHost.setOnTabChangedListener(tabChangeListener);
}

protected void onSaveInstanceState(Bundle outState) {
    outState.putString("tab", mTabHost.getCurrentTabTag());
    outState.putString("tab", "Home");
    super.onSaveInstanceState(outState);
}

private void intializeViewPager() {

    List<Fragment> fragments = new Vector<Fragment>();
    fragments.add(Fragment.instantiate(this, HomeFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, ConfigFragment.class.getName()));
    fragments.add(Fragment.instantiate(this, GraphicFragment.class.getName()));

    mPagerAdapter  = new PagerAdapter(super.getSupportFragmentManager(), fragments);

    mViewPager = (ViewPager)super.findViewById(R.id.viewpager);
    mViewPager.setAdapter(mPagerAdapter);
    mViewPager.setOffscreenPageLimit(4);
    mViewPager.setOnPageChangeListener(pageChangeListener);
}

private static void addTab(Main activity, TabHost tabHost, TabHost.TabSpec tabSpec, TabInfo tabInfo) {
    tabSpec.setContent(activity.new TabFactory(activity));
    tabHost.addTab(tabSpec);
}

private final TabHost.OnTabChangeListener tabChangeListener = new TabHost.OnTabChangeListener(){

    public void onTabChanged(String tabId) {
        int pos = mTabHost.getCurrentTab();
        mViewPager.setCurrentItem(pos);
    }
};  

private final ViewPager.OnPageChangeListener pageChangeListener = new ViewPager.OnPageChangeListener(){
    public void onPageScrollStateChanged(int state) {}

    public void onPageScrolled(int arg0, float arg1, int arg2) {}

    public void onPageSelected(int position) {
        mTabHost.setCurrentTab(position);
    }
};

}

片段:

public class HomeFragment扩展了Fragment {

@SuppressWarnings("unused")
private Config config = Config.GetInstance();

private View view;

@SuppressWarnings("unused")
private Context context;    

public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){

    if(container == null){
        return null;
    }

    view = (LinearLayout)inflater.inflate(R.layout.tab_graphic, container, false);
    context = view.getContext();

    return view;

}

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    inflater.inflate(R.menu.tab_graphic, menu);
}

public boolean onOptionsItemSelected(MenuItem item) {

    switch (item.getItemId()) {
        case R.id.menu_home:
            loadGraphicFragment();
    }

    return false;
}

public void loadGraphicFragment(){

    Fragment fragment = new GraphicFragment();

    FragmentManager fm = getActivity().getSupportFragmentManager();
    FragmentTransaction transaction = fm.beginTransaction();
    transaction.replace(R.id.viewpager, fragment);
    transaction.commit();       
}

}

时间执行错误:

11-28 18:09:13.673: E/AndroidRuntime(468): Uncaught handler: thread main exiting due to uncaught exception
11-28 18:09:13.695: E/AndroidRuntime(468): java.lang.NullPointerException
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.support.v4.app.Fragment.setUserVisibleHint(Fragment.java:801)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.support.v4.app.FragmentPagerAdapter.setPrimaryItem(FragmentPagerAdapter.java:130)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.support.v4.view.ViewPager.populate(ViewPager.java:1010)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:523)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:495)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:476)
11-28 18:09:13.695: E/AndroidRuntime(468):  at br.com.censanet.connectionmonitor.Main$1.onTabChanged(Main.java:125)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.widget.TabHost.invokeOnTabChangeListener(TabHost.java:353)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.widget.TabHost.setCurrentTab(TabHost.java:338)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.widget.TabHost$2.onTabSelectionChanged(TabHost.java:129)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.widget.TabWidget$TabClickListener.onClick(TabWidget.java:379)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.View.performClick(View.java:2364)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.View.onTouchEvent(View.java:4179)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.View.dispatchTouchEvent(View.java:3709)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:852)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
11-28 18:09:13.695: E/AndroidRuntime(468):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1659)
11-28 18:09:13.695: E/AndroidRuntime(468):  at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.app.Activity.dispatchTouchEvent(Activity.java:2061)
11-28 18:09:13.695: E/AndroidRuntime(468):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1691)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.os.Handler.dispatchMessage(Handler.java:99)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.os.Looper.loop(Looper.java:123)
11-28 18:09:13.695: E/AndroidRuntime(468):  at android.app.ActivityThread.main(ActivityThread.java:4363)
11-28 18:09:13.695: E/AndroidRuntime(468):  at java.lang.reflect.Method.invokeNative(Native Method)
11-28 18:09:13.695: E/AndroidRuntime(468):  at java.lang.reflect.Method.invoke(Method.java:521)
11-28 18:09:13.695: E/AndroidRuntime(468):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
11-28 18:09:13.695: E/AndroidRuntime(468):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)

请帮帮我! (对不起英语!)

1 个答案:

答案 0 :(得分:0)

您可以从此处下载示例代码,对于标签类型项目非常有用。

https://github.com/JakeWharton/Android-ViewPagerIndicator

<强>更新 在这里你可以找到更多关于碎片

change fragment