3

私の小さなアプリには、次の基本的な構造があります (タブホストに 2 つのタブ):

Main (FragmentActivity を拡張) HomeFragment (Fragment を拡張) ConfigFragment (Fragment を拡張)

時々 (ユーザーがメニューをクリックすると) HomeFragment の代わりに他のフラグメント (GraphicFragment) を表示する必要があります。GraphicFragment で [戻る] ボタン (またはメニュー項目の [ホーム]) を使用すると、タブに再びフラグメント 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 extends 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 extends 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)

私を助けてください!(英語でごめんなさい!)

4

1 に答える 1

0

タブタイプのプロジェクトに非常に役立つサンプルコードをここからダウンロードできます。

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

ここで更新 すると、フラグメントの詳細を確認できます。

フラグメントを変更する

于 2012-11-28T18:17:10.570 に答える