[Fragmentによるタブ作成 関連記事]
前回はFragmentによるタブのレイアウト作成の処理をメモった。今回はタブで切り替わるコンテンツ(Fragment) を作成する処理をメモる。
コンテンツ(Fragment) の作成
今回はコンテンツ部分を Fragment で作成する。タブの切り替えが3つあるのでFragment も3つ作成する。
フラグメントは、Fragmentクラス ( または既存のそのサブクラス ) のサブクラスを作成する。Fragment クラスのコードは Activity のそれとほとんどそっくりである。これには onCreate()、onStart()、onPause()、および onStop() などのアクティビティと同様のコールバックメソッドがある。
※詳しくは 1.1 フラグメント - ソフトウェア技術ドキュメントを勝手に翻訳 参考
"TAB1"が選択された場合のコンテンツを作成
[Tab1Fragment.java]
package localhost.test_tab_fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class Tab1Fragment extends Fragment { @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.tab1_fragment, container, false); return v; } }
[tab1_fragment.xml]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TAB1の内容(フラグメント)"/> </LinearLayout>
FragmentはAndroid SDK 3.0 からでないとサポートされていない。Android1.6以降のSDKでもFragment が使えるようにサポートライブラリ android-support-v4.jar を使うことにする。
※詳しくは Android1.6以上で Fragment 対応 / android-support-v4 を参考に
import android.support.v4.app.Fragment; public class Tab1Fragment extends Fragment
- サポートライブラリを使うので "Fragmentクラス" は "android.support.v4.app" パッケージからインポートする。
- フラグメントは、Fragmentクラス ( または既存のそのサブクラス ) のサブクラスとなるので "Fragment" を継承してクラスを作る。
"TAB2"が選択された場合のコンテンツを作成
同様に "TAB2" のコンテンツを作成する。
[Tab2Fragment.java]
package localhost.test_tab_fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class Tab2Fragment extends Fragment { @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.tab2_fragment, container, false); return v; } }
[tab2_fragment.xml]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TAB2の内容(フラグメント)"/> </LinearLayout>
"TAB3"が選択された場合のコンテンツを作成
同様に "TAB3" のコンテンツを作成する。
[Tab3Fragment.java]
package localhost.test_tab_fragment; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class Tab3Fragment extends Fragment { @Override public View onCreateView( LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.tab3_fragment, container, false); return v; } }
[tab3_fragment.xml]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TAB3の内容(フラグメント)"/> </LinearLayout>
TAB選択時のコンテンツ切り替え
[MainActivity.java]
package localhost.test_tab_fragment; import android.content.Context; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTransaction; import android.util.Log; import android.view.View; import android.widget.TabHost; import android.widget.TabHost.TabContentFactory; import android.widget.TabHost.TabSpec; public class MainActivity extends FragmentActivity implements TabHost.OnTabChangeListener { // TabHost private TabHost mTabHost; // Last selected tabId private String mLastTabId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_tabhost); mTabHost = (TabHost) findViewById(android.R.id.tabhost); mTabHost.setup(); /* Tab1 設定 */ TabSpec tab1 = mTabHost.newTabSpec("tab1"); tab1.setIndicator("TAB1"); tab1.setContent(new DummyTabFactory(this)); mTabHost.addTab(tab1); // Tab2 設定 TabSpec tab2 = mTabHost.newTabSpec("tab2"); tab2.setIndicator("TAB2"); tab2.setContent(new DummyTabFactory(this)); mTabHost.addTab(tab2); // Tab3 設定 TabSpec tab3 = mTabHost.newTabSpec("tab3"); tab3.setIndicator("TAB3"); tab3.setContent(new DummyTabFactory(this)); mTabHost.addTab(tab3); // タブ変更時イベントハンドラ mTabHost.setOnTabChangedListener(this); // 初期タブ選択 onTabChanged("tab1"); } /* * タブの選択が変わったときに呼び出される * @Override */ public void onTabChanged(String tabId) { Log.d("TAB_FRAGMENT_LOG","tabId:" + tabId); if(mLastTabId != tabId){ FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); if("tab1" == tabId){ fragmentTransaction .replace(R.id.realtabcontent, new Tab1Fragment()); }else if("tab2" == tabId){ fragmentTransaction .replace(R.id.realtabcontent, new Tab2Fragment()); }else if("tab3" == tabId){ fragmentTransaction .replace(R.id.realtabcontent, new Tab3Fragment()); } mLastTabId = tabId; fragmentTransaction.commit(); } } /* * android:id/tabcontent のダミーコンテンツ */ private static class DummyTabFactory implements TabContentFactory { /* Context */ private final Context mContext; DummyTabFactory(Context context) { mContext = context; } @Override public View createTabContent(String tag) { View v = new View(mContext); return v; } } }
mTabHost.setOnTabChangedListener(this);
※TabHost | Android Developers
- タブが変化したときのイベントリスナを setOnTabChangedListener で登録する。
- タブが変化したときの処理は onTabChanged メソッド で行う。
public class MainActivity extends FragmentActivity implements TabHost.OnTabChangeListener {
※TabHost.OnTabChangeListener | Android Developers
/* * タブの選択が変わったときに呼び出される * @Override */ public void onTabChanged(String tabId) { Log.d("TAB_FRAGMENT_LOG","tabId:" + tabId); if(mLastTabId != tabId){ FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); if("tab1" == tabId){ fragmentTransaction .replace(R.id.realtabcontent, new Tab1Fragment()); }else if("tab2" == tabId){ fragmentTransaction .replace(R.id.realtabcontent, new Tab2Fragment()); }else if("tab3" == tabId){ fragmentTransaction .replace(R.id.realtabcontent, new Tab3Fragment()); } mLastTabId = tabId; fragmentTransaction.commit(); } }
TabHost.OnTabChangeListener インターフェースを実装したのでonTabChanged メソッドをオーバーライドする。タブが選択されるとこのメソッドが呼ばれる。パラメータとして選択されたタブのキーを受ける。レイアウトの "R.id.realtabcontent" 領域を、"選択されたタブと関連するフラグメント"に置き換える。(fragmentTransaction.replace)
サンプルソース
参考
- FragmentでタブUIを簡単にできるライブラリ作った - ほげほげ(仮)
- 1.1 フラグメント - ソフトウェア技術ドキュメントを勝手に翻訳
- TabHost.OnTabChangeListener | Android Developers
[Fragmentによるタブ作成 関連記事]