Android Tips #38 FragmentTabHost を使って Fragment をタブで切り替える
FragmentTabHost とは
FragmentTabHost は Fragment をタブで切り替えるための View です。Android 1.6 から使用することができます。Activity にタブを表示して View を切り替える実装は以前は TabActivity を使っていましたが、現在は非推奨になっています。この機会に最新の実装方法を覚えておきましょう!
FragmentTabHost の使いかた
1. レイアウトを作る
まずはレイアウトを作ります。
<android.support.v4.app.FragmentTabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TabWidget android:id="@android:id/tabs" android:orientation="horizontal" android:layout_width="match_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"/> <FrameLayout android:id="@+id/content" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> </LinearLayout> </android.support.v4.app.FragmentTabHost>
まず大原則として大枠は FragmentTabHost にします。その中にタブの View である TabWidget を @android:id/tabs という id で配置します。TabWidget は TabActivity のときにも使われていた View なので馴染み深いと思います。また FrameLayout を @android:id/tabcontent という id で配置します。これは実際には表示されない View になりますが、こうすることで FragmentTabHost がそれぞれの View をパーツとして使ってくれます。最後に Fragment を追加するレイアウトに好きな id を入れて完了です。今回は content という名前にしました。
2. FragmentTabHost をセットアップする
次に Activity の実装です。Fragment を取り扱うので FragmentActivity を継承します。onCreate() で FragmentTabHost を findViewById() で参照し FragmentTabHost#setup() メソッドを呼びます。引数には Context と FragmentManager を渡さなければいけないので FragmentActivity#getSupportFragmentManager() で取得した FragmentManager を渡すようにします。
FragmentTabHost host = (FragmentTabHost)findViewById(android.R.id.tabhost); host.setup(this, getSupportFragmentManager(), R.id.content);
3. TabSpec を追加する
あとはタブの情報である TabSpec で作っていきます。TabSpec のインスタンスは
FragmentTabHost#newTabSpec() で生成します。引数には TabSpec のタグを渡します。
必ず設定しておかなければいけないのが TabSpec#setIndicator() です。これはタブの View になります。String を渡すとデフォルトのタブボタンの View が使われます。
最後に FragmentTabHost#addTab() でタブを追加します。第一引数に TabSpec を、第二引数にタブが選択されたときに表示したい Fragment を Class で渡します。第三引数には Fragment で読み込みたいデータを Bundle で渡します。特に必要ない場合は null でOKです。
TabSpec tabSpec1 = host.newTabSpec("tab1").setIndicator("Tab1"); host.addTab(tabSpec1, SampleFragment.class, null);
以下が Activity の全ソースです。Fragment は適当に。
MainActivity.java
package jp.classmethod.android.sample.fragmenttabhost; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTabHost; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TabHost.TabSpec; import android.widget.TextView; public class MainActivity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentTabHost host = (FragmentTabHost) findViewById(android.R.id.tabhost); host.setup(this, getSupportFragmentManager(), R.id.content); TabSpec tabSpec1 = host.newTabSpec("tab1"); Button button1 = new Button(this); button1.setBackgroundResource(R.drawable.tab_left); tabSpec1.setIndicator(button1); Bundle bundle1 = new Bundle(); bundle1.putString("name", "Tab1"); host.addTab(tabSpec1, SampleFragment.class, bundle1); TabSpec tabSpec2 = host.newTabSpec("tab2"); Button button2 = new Button(this); button2.setBackgroundResource(R.drawable.tab_center); tabSpec2.setIndicator(button2); Bundle bundle2 = new Bundle(); bundle2.putString("name", "Tab2"); host.addTab(tabSpec2, SampleFragment.class, bundle2); TabSpec tabSpec3 = host.newTabSpec("tab3"); Button button3 = new Button(this); button3.setBackgroundResource(R.drawable.tab_right); tabSpec3.setIndicator(button3); Bundle bundle3 = new Bundle(); bundle3.putString("name", "Tab3"); host.addTab(tabSpec3, SampleFragment.class, bundle3); } public static class SampleFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); textView.setText(getArguments().getString("name")); return textView; } } }
まとめ
タブの切り替えはよく使われる UI のひとつだと思いますが Fragment を使うととても管理しやすいです。何より以前良く使われていた TabActivity の実装方法は非推奨になっているので、これからは FragmentTabHost を使うようにしていきましょう。
しかし Support Package で導入されてから Fragment を使う機会がかなり増えてきましたね。Android 開発者にとって Fragment を使いこなすことは必須といえますね!今回は初歩的な解説となりましたが、これからも Fragment を使った実装 Tips をシェアしていきますのでよろしくお願いします!