私の小さなアプリには、次の基本的な構造があります (タブホストに 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)
私を助けてください!(英語でごめんなさい!)